光线效果

1.模拟灯光方法:

(1)首先GPU为每个三角形的顶点执行关心计算,然后把计算的结果插补在顶点之间来修改每个渲染的片元的最终颜色。因此模拟灯光的质量和光滑度要取决于组成3D物体的顶点数量。

(2)灯光效果可以被预计算并被“烘焙”进纹理中,以便在完全不需要GPU光线计算的情况下产生逼真的场景。

2.环境光、漫反射光、镜面反射光

环境光来自各个方向,因此会同等地增强所有几何图形的亮度。

程序通过设置模拟环境光的颜色和亮度来设置场景中的背景灯光的基础水平。

每个光源的漫反射部分是定向的,会基于三角形相对于光线的方向来照亮场景中的每个三角形。

漫反射的光的颜色只会着色被定向的光线照射到的三角形。

从几何图形对象反射出来的光线叫做镜面反射光。

一个渲染的三角形中的每个光线组成部分的效果取决于三个相互关联的因素:光线的设置、三角形相对于光线的方向,以及三角形的材质属性。

3.光线与几何图形相互作用的关键是要计算出每个几何物体照射和散发出来多少光线。要做到这点,就需要计算出每个三角形有多么接近于与光的方向垂直的方向。

三角形可以用三个顶点表示,也可以用一个顶点和两个矢量表示。

矢量积运算:



方向与相乘的两个矢量构成的平面垂直,遵循右手法则。

GLKVector3 GLKVector3CrossProduct(GLKVector3 vectorLeft, GLKVector3 vectorRight)为GLKit计算矢量积的函数。

光线计算依赖于表面法向量,可以使用定义三角形的任意两个矢量的矢量积计算出来。

法向量也是单位向量,长度总是1.0.

计算法向量:先计算矢量积向量,然后用这个矢量积向量的长度除以矢量积的每个分量。

GLKVector3 GLKVector3Normalize(GLKVector3 vector)函数可以求单位向量。

GLKVector3Normalize(GLKVector3CrossProduct(vectorA, vectorB));可用来求向量A和向量B的法向量。

投射到三角形上的光线的数量可以通过确定光线的方向与法向量的方向之间的角度轻松计算出来。

介于一个光线方向上的单位向量和一个三角形的表面法向量之间的余弦决定了照射到三角形上的光线的数量。

如果三角形垂直于光线,那么表面法向量会平行于光线的方向,角度为0度,余弦值为1.0,这意味着最大强度的光会照射到三角形上。如果这个三角形平行于光线的方向,那么介于光线和表面法向量之间的角度就是90度,余弦值为-1,因此没有光线会照射到三角形上。

OpenGLES程序为每个顶点指定了单独的法向量。法向量通常计算一次,然后与顶点的位置和纹理的坐标一起被保存起来。

如果一个三角形的三个顶点被赋予相同的法向量,这叫做平面法线,灯光模拟会让三角形变得平坦。

如果每个顶点的法向量是包含顶点的所有三角形的法向量的一个平均值,灯光模拟会创建三角形被轻微弯曲的感觉。

4.使用GLKit灯光

GLKit使用与下面摘录的用于漫反射光的代码相似的Shading Language代码为每个光线实现了标准的灯光模拟方程式。

GLKit会自动地生成与上摘录相类似的Shading Language代码,以便同时混入每个光线的镜面反射光和环境光颜色。

这个代码会改变每个顶点的法向量来匹配正在被渲染的场景的方向,计算光线的方向与新的法向量之间的标量积,然后使用这个标量积来按比例决定光的漫反射颜色的影响力。

GLKit的GLKBaseEffect类最多可以支持三个命名为light0、light1、light2的模拟灯光。每个灯光都是GLKBaseEffect的一个同名属性。这些属性是GLKEffectPropertyLight类的实例,这些属性又可以设置每个灯光的属性,每个灯光至少有一个位置、一个环境颜色、一个漫反射色和一个镜面反射颜色。每个灯光都可以被单独的开启和关闭。


灯光的漫反射颜色被设置为不透明中等灰色。灯光的镜面反射和环境颜色保持为GLKit的默认值,分别为不透明白色和不透明黑色。这意味着灯光的漫反射部分不会影响场景并且高反光的物体会显得非常有光泽。

上面代码position用一个GLKVector4来设置光源的位置。前三个元素要么是光源的X、Y、Z位置,要么是指向一个无限远的光源的方向。第四个元素指定了前三个元素是一个位置还是一个方向。如果第四个元素是零,前三个元素就是一个方向;如果第四个元素非零,光源就从它的位置向各个方向投射光线。因此每个顶点的光线方向是多种多样的,并且必须要由GPU使用从每个顶点到光源的方向而计算出来。位置光源可以被设置为一个锥形而不是向各个方向发散光线的聚光灯。

仅仅开启一个灯光是不够的,必须为被一个灯光照射到的每一个三角形的每一个顶点提供法向量。

在一个或多个GLKBaseEffect的灯光被开启后,灯光决定了渲染的物体的颜色;GLKBaseEffect的常量颜色和所有的顶点颜色被忽略了。当GLKBaseEffect的灯光被创建之后,constantColor属性就被忽略了,及时灯光被关闭了,例如:baseEffect.light0.enable = GL_FALSE;

作为最后的手段,GLKBaseEffect的constantColor属性会告诉GLKBaseEffect为生成的片元使用什么颜色。大部分OpenGLES应使用某种灯光和纹理的结合来决定片元的颜色。constantColor属性仅适用于渲染单调不发光的物体。

作为最后手段,GLKBaseEffect的constanColor属性会告诉GLKBaseEffect为生成的片元使用什么颜色。大部分的OpenGLES应用使用某种灯光和纹理的结合来决定片元颜色。constantColor仅适用于渲染单调不发光的物体。

5.把灯光烘焙进纹理中

用灯光模拟的方法,每个被照射到的顶点,除了位置坐标,法向量的使用还需要三个浮点值的存储空间。

如果纹理可以以任何形式来使用,把灯光烘焙进一个现存的纹理中可以替代灯光模拟的方法。换句话说就是使用已经包含了本来是由灯光模拟生成的明亮和黑暗区域的纹理。

把灯光烘焙进纹理仅仅适用于几何图形和灯光都不是动态的情况下。

6.片元计算

GPU可以为每个单独的片元而不仅仅是为顶点重新计算灯光效果。可以使用为顶点计算灯光效果相同的方程式。光线方程式需要每个片元的法向量。解决方法是编码一个纹理的每个RGB纹素内的法向量X、Y、Z分量。这样的纹理成为法线贴图。

一个纹理单元决定了哪一个法线贴图纹素会影响片元。一个Shading Language程序会计算由选中的纹素和光线的方向所代表的矢量的标量积。然后用这个标量积来按比例确定最终的片元的颜色效果。

每片元光线计算即使是在动态的灯光和几何图形的情况下,仍然可以工作良好,但很耗资源。

7.小结

真实世界的灯光效果是我们感知周围环境的关键,模拟灯光效果可以为3D渲染增加真实感。结合了材质的传统OpenGLES顶点灯光模拟提供了广泛的配置选项,但还是要忍受各种限制以及嵌入式GPU相对低性能。比起OpenGLES材质,纹理总是会产生更高质量的渲染效果。在使用了纹理之后,可以在纹理中包含一些灯光效果,同时完全避免OpenGLES灯光模拟。所有运行iOS的硬件都支持每片元灯光计算技术,并且随着内存、处理器和工具支持的改进这项技术会变得更加普遍。

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

推荐阅读更多精彩内容