opengL ES _ 入门_05

OpenGL ES _ 入门_01
OpenGL ES _ 入门_02
OpenGL ES _ 入门_03
OpenGL ES _ 入门_04
OpenGL ES _ 入门_05
OpenGL ES _ 入门练习_01
OpenGL ES _ 入门练习_02
OpenGL ES _ 入门练习_03
OpenGL ES _ 入门练习_04
OpenGL ES _ 入门练习_05
OpenGL ES _ 入门练习_06
OpenGL ES _ 着色器 _ 介绍
OpenGL ES _ 着色器 _ 程序
OpenGL ES _ 着色器 _ 语法
OpenGL ES_着色器_纹理图像
OpenGL ES_着色器_预处理
OpenGL ES_着色器_顶点着色器详解
OpenGL ES_着色器_片断着色器详解
OpenGL ES_着色器_实战01
OpenGL ES_着色器_实战02
OpenGL ES_着色器_实战03

学习是一件开心的额事情

展示图:


效果图

友情提示:

本文重在讲解一些游戏中灯光的类型和作用,明白原理就可以,代码看不懂没关系.之后会用大量时间,剖析OpenGL ES 代码,持续更新!

  • 学习目标:

1.理解OpenGL是如何模拟现实世界的光照条件
2.通过定义光源,材料和光照模型属性,渲染光照物体
3.定义光照物体的材料属性

  • 任务:

绘制一个被光照射的球体

  • 概念解释:

深度缓冲区原理:首先,把一个距离观察平面的深度值(距离) 与窗口中的每个像素相关联,一开始,使用glClear(GL_DEPTH_BUFFER_BIT) 把所有像素的深度值,设置为最大可能的距离,然后,在场景中绘制所有物体,硬件或者软件会把被绘制表面转回为像素集合,在这个时候,不考虑是否被遮挡,OpenGL 此时,还会计算,这些表面和观查着平面的距离,如果启动了深度缓冲区,OpenGL 会把它的深度值和已经存储在缓冲区中的深度值,进行比较,如果新像素比原先的像素更靠近观察平面,这个新像素的颜色和深度会取代原先那个像素,如果新像素的深度值大于原先像素的深度值,新像素就会被遮挡,他的颜色和深度会被丢弃。

如何使用?

首先需要启动它,启动一次即可,每次绘制场景时,需要在绘制之前清除深度缓冲区,然后以任意顺序绘制场景中的物体
glclear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
理解OpenGL是如何模拟现实世界的光照条件

补充知识?

当观察一个物理表面时,眼睛对颜色的感知取决于到达刺激缀细胞的光子和能量分布,这些光子可能来自单个光源,也可能来自多个光源,有些光子被表面吸收,有些被反射出来。不同表面的属性可能存在非常大的区别,有些表面非常光滑,会把光线反射到某个方向,有些表面会把均匀的发散到所有地方,很多表面位于两者之间。

请认真阅读以上的内容,这个将影响到您对本文的理解。

OpenGL是怎么模拟光照的?

首先,假定光可以分解为红,绿,蓝成分,光源的特性是由它发射的红,绿和蓝的数量决定的,表面材料的特性,是由它向不同方向反射光的百分比决定的。OpenGL 有自己的一套光照方程式,计算效率相对来说,也很高,如果想要自己实现这样的一套光照方程式,也可以,可能你需要花费很大的精力,实在是太复杂了。
OpenGL 光照模型中,场景中的灯光,有来自固定方向的和不同方向的,可以单独打开和关闭,这个很简单,想一下我们的生活场景就可以了。
当光照射到物体上,能会体现出光照的意义。
OpenGL 光照模型,把光分为4种独立的成分:环境光,反射光,镜面光,发射光。

下面就来解释一下四种光的含义和作用。

环境光: 在环境中充分的散射,无法辨别其方向的光,似乎来自于所有的方向。当环境光撞击物体表面时,会向各个方向发散。
散射光:来自某个方向,如果它从正面照射,他可能看起来更亮一下,如果他斜着掠过表面,看其他则会暗一些,来自某个特性的位置或者方向的任何光很可能具有散射的成分。

朗伯体光照模型:


朗伯体光照模型

Id=kdIi cos(Θ)

ID是漫反射的强度,Ii是光的入射光的强度,和KD的漫反射,是对粗糙松散耦合对象材料。松散的意思是,在许多现实世界的材料,实际表面可能有点抛光,但半透明的,而层立即下执行散射。材料,如这可能有强烈的漫反射和镜面反射成分。此外,每个颜色带可能有自己的K值在现实生活中,所以会有一个红色,绿色和蓝色

镜面光:来自某个方向,如果物体表面光滑,这种光将充分反射,但是一般的物体表面不会绝对的光滑,所有不可能有真正的完美反射.

1594482-ab7c1ba7c2e68e10.png

I =W(q)I cosn Θ
Ilight 入射光的轻度
W(q) 基于光线I的夹角是如何反射的
N是亮度因子
Θ是反射光线,光线射到眼睛的夹交
虽然W(q)是不能直接使用在OpenGL ES 1,它可以用来在一个版本的OpenGL ES 2着色器。它将是特别有用的,在做反射的水,例如。在它的位置是一个常数,是基于从材质设置的高光值。

发射光:材料自身可能具有一种发射颜色,可以模拟那些来自物体的光,它不受任何光源的影响,发射颜色没有作为一种额外的光源。
顶点颜色值:
color=ambientworldmodel +ambientmaterial +emissivematerial +intensitylight
材料颜色:可以给物体设置材料颜色,通俗的解释一下,假设一个物体的材料颜色为红色,那么,用蓝光照射这个物体,我们看到的是一个黑色的球,因为他把蓝光吸收了,如果我们用红光照射他,我们看到的就是一个红球,如果用白光照射他,我们也看到的是红球,因为白光(R=1,G=1,B=1)中 用红光的成分
光照和材料RGB值
如果一束光线的成分为(LR,LG,LB) 一种材料具有的颜色成分为(MR,MG,MB) 那么,进入眼睛的光就是(LR*MR,LG*MG,LB*MB)
两个光源叠加原理(R1,G1,B1) 和 (R2,G2,B2) 叠加后 (R1+R2,G1+G2,B1+B2) 如果相加后任何一个值大于1,则会被截取1(因为设备能后现实的最大颜色亮度)。

提示:

如果使用光照RGBA 颜色索引模式优先选择

为每个物体的每个顶点定义法线向量?

物体的法线向量,决定了它相对于光源的方向,OpenGL 使用法线判断这个顶点从每个光源接受的光线数量,注意,为了正确计算光线,表面法线必须为单位长度,必须保证对物体所进行的模型转换,并没有对表面法线进行缩放,最终的法线仍然为单位长度。

如何创建光源?

glLightfv()函数指定光源的位置,如果使用不同颜色的光,使用glLight*()函数修改
场景中至少可以包含八个光源,除了GL_LIGHT0 之外的其他光源的颜色都为黑色。可以把光源放在很远的地方,模拟阳光,可以对光源进行控制,让它产生狭窄的聚焦光束和角度宽广的光束

如何启用光源?

glEnable() 参数GL_LIGHTING
光源的几个重要属性:颜色,位置,和方向
两个重要函数:
glLight(GLenum light,Glenum pname,TYPE para),
glLightv(GLenum light,Glenum pname,TYPE *param )
参数1 light 指定光源 GL_LIGHT0…GL_LIGHT7
参数2 pname 具体的属性
参数3 para 属性值单值,param属性值,向量 根据属性的不同选择不同的函数

参考下面的表格

参数名称 默认值 含义
GL_AMBIENT (0,0,0,1) 环境光强度
GL_DIFFUSE (1,1,1,1) 光的散射强度
GL_SPECULAR (1,1,1,1) 光的镜面强度
GL_POSITION (0,0,1,0) 光源的位置坐标
GL_SPOT_DIRECTION (0,0,-1,0) 聚光灯的方向
GL_SPOT_EXPONENT 0.0 聚光指数
GL_SPOT_CUTOFF 180 聚光灯的切角
GL_CONSTANT_ATTENUATION 1.0 常亮衰减因子
GL_LINEAR_ATTENUATION 0.0 线性衰减因子
GL_QUADRATIC_ATTENUATION 0.0 二次衰减因子

提示: 如果想要创建逼真的效果可以将GL_SPECULAR 和 GL_DIFFUSE 的参数值设置相同

选择光照模型我们应该思考的问题?

1.观察者应该在无限远处还是场景本地
2.确定场景中的物体的正面和背面是否应该执行不同的计算
glLightModel*()

为场景中的物体定义材料属性?

物体的材料属性决定他是如何反射光线的,因此也决定了它的颜色。可以指定材料的颜色,散射和镜面颜色以及它的光泽,这个例子只指定了最后两种材料属性,镜面材料颜色和光泽度。

提示: 当光照条件发生变化时,可以使用显示列表实现最大限度的效率

  • 光源类型

第一种,光源位于无限远处,这种光源被称为方向性光源,如果光源位于无限远处,当光线到达物体表面时,认为所有的光源都是平行的
第二种,被称为位置性光源,通俗的讲,它的位置决定它对场景产生的效果,具体来说,它决定光线的方向,台灯就是一个位置性光源,通常位置性光源是朝向每个方向发射光线的,但也可以把光源定义为聚光灯,把它的照明范围限制在一个锥体里

  • 衰减

随着光源的距离的增加,光的强度也随之衰减,由于方向性光源在无限远处,所以这个原则不适用于方向性光源,但是我们可以对位置性光源进行衰减,OpenGL将光源的强度乘以衰减因子。
衰减因子 = 1/(kc+kl*d+kq*d^2)
d = 光源和顶点的位置
KC = GL_CONSTANT_ATTENUATION
KL = GL_LINEAR_ATTENUATION
KQ = GL_QUADRATIC_ATTENUATION
环境光,散射光,镜面光的强度都进行了衰减,只有发射光和全局环境光没有衰减,由于衰减需要在每种经过计算差生的颜色上再进行一次除法,所以衰减光可能会影响应用程序的性能。

创建聚光灯步骤?

1594482-34b63549fa30bdf8.png

设置光锥切角:
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,45.0);
设置聚光灯的方向 默认方向为(0,0,-1)
glLightfv(GL_LIGHT0,GL_SPOT_DORECTION,spot_direction);
可以设置衰减因子和光的集中度
GL_SPOT_EXPONENT 参数控制光的集中度

代码部分:

-(void)initLighting
{
// 创建灯光的位置
GLfloat posMain[]={5.0,4.0,6.0,1.0};
GLfloat posFill1[]={-15.0,15.0,0.0,1.0};
GLfloat posFill2[]={-10.0,-4.0,1.0,1.0};
GLfloat white[]={1.0,1.0,1.0,1.0};
// 定义几种颜色值
GLfloat dimblue[]={0.0,0.0,.2,1.0};
GLfloat cyan[]={0.0,1.0,1.0,1.0};
GLfloat yellow[]={1.0,1.0,0.0,1.0};
GLfloat dimmagenta[]={.75,0.0,.25,1.0};
GLfloat dimcyan[]={0.0,.5,.5,1.0};
//设置反射光的位置和颜色
glLightfv(GL_LIGHT0,GL_POSITION,posMain);
glLightfv(GL_LIGHT0,GL_DIFFUSE,white);
// 设置镜面光的颜色,它的光源和反射光是同一个光源
glLightfv(GL_LIGHT0,GL_SPECULAR,yellow);
// 设置光源2的位置和类型
glLightfv(GL_LIGHT1,GL_POSITION,posFill1);
glLightfv(GL_LIGHT1,GL_DIFFUSE,dimblue);
glLightfv(GL_LIGHT1,GL_SPECULAR,dimcyan);
// 设置光源3 的位置和类型以及
glLightfv(GL_LIGHT2,GL_POSITION,posFill2);
glLightfv(GL_LIGHT2,GL_SPECULAR,dimmagenta);
glLightfv(GL_LIGHT2,GL_DIFFUSE,dimblue);
//设置衰减因子
glLightf(GL_LIGHT2,GL_QUADRATIC_ATTENUATION,.005);
//设置材料在反射光下的颜色
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, cyan);
// 设置材料在镜面光下的颜色
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
//
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,25);
// 设置光照模式 GL_SMOOTH 代表均匀的颜色涂在表面上
glShadeModel(GL_SMOOTH);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,0.0);
// 开启灯光模式
glEnable(GL_LIGHTING);
// 打开灯光123
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
}

参考完整代码:

完整代码下载地址:demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容