Cg lighting(Phong model)
这个链接讲的很清楚了,直接看就行了。
http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter05.html
太久没写程序了,好多东西记不住了。只记得diffuse要根据入射角和法线来计算强度。specular要还要根据摄像机观察角度来计算。
光照模型
看不懂的此段忽略。(转载一下)Lambert 模型能够较好地表现粗糙表面上的光照现象,如石灰墙,纸张等等,但是在渲染金属材质制成的物体时,则会显得呆板,表现不出光泽,主要原因是其没有考虑到镜面反射效果,所以Phong模型对其进行了很好的补充。由于Blinn-phng光照模型混合了Lambert的漫射部分和标准的高光,渲染效果有时会比 Phong高光更柔和,有些人认为phong光照模型比blinn-phong更加真实,实际上也是如此,Blinn-phong渲染效果要更加柔和一些,但是由于Blinn-phong的光照模型省去了计算反射光线方向向量的两个乘法运算,速度更快,因此成为许多CG软件中默认的光找渲染方法,此外它也继承在了大多数图形芯片中,用以产生实时的快速渲染。在OpenGL和Direct3D渲染管线中,Blinn-Phong就是默认的渲染模型。 Rendering Equation是基于物理光学的模型,其对于观察方向上的辐射率进行了本质上的量化,Phong模型只是其特定BRDF的推导
Phong模型
说说phong吧,
light color = emissive + ambient + diffuse + specluar,
phong把光定义为四个分量:自发光,环境光,漫反射光和镜面光。在普通应用中,diffuse是最重要的,其他的在材质细节不是很明显的时候完全可以忽略(嘿嘿嘿)。
先说说投射到最终的颜色值output_color = texture_color * (material_k * light_color);
其中 material_k 是一个vec4(Ke, Ka, Kd, Ks);它的作用是在光照模型固定的情况下,通过调整系数,来模拟不同的材质。当然,KeKaKdKs也可以是vec4,那么公式就得写成:light_color = Ke + Ka*ambient + kd*diffuse + Ks*specluar;
分量的作用:
- emissive 自发光:太阳啊,灯泡啊什么的,翡翠碧玉之类的也是可以用这个分量来模拟通透性。(当然还有别的方法,比如blend什么的)
- ambient 环境光:微光,往往是全局范围的globalAmbient,可以想象一下暗室,四周墙面上化学制剂、荧光灯什么发出幽幽蓝光的效果。
- diffuse 漫反射:一般看到的颜色主要是这个,因为漫反射会有入射角度问题,所以它表现光照方向作用是很明显的。
- specular 镜面光:镜面光主要是模拟反射效果,也就是高光颜色,主要是遇到光滑,金属表面的时候表现明显。
diffuse 漫反射光
先说diffuse吧,因为她相对来说最重要。公式:diffuse
=
lightColor
x max(
N
·
L
, 0);
很简单吧,主要是N dot L, max函数的作用是为了背光表面的判断。
根据Lambert定律, diffuse color正比于法线n和光向量l的余弦, 当n和l被normalize后, 余弦值等于n.l
- N是法线
- L是入射向量的反向量
- P是当前顶点。
- N·L 主要是用来判断面上的点是面朝光源还是背朝光源的。 dot(N, L)
![](https://img-my.csdn.net/uploads/201209/21/1348209702_4685.jpg)
specular 镜面光
镜面光则需要人眼的参与,因为摄像机位置不同,看到的反射也是不一样的。公式:
specular
=
lightColor
x
facing
x (max(
N
·
H
, 0)) ^
shininess;
(这个是Blinn提出的,
specular = (r.v)
shiness
, r是光向量l关于法线的反射, v是表面点到视点的向量, r = 2 (n.l) – 1, 其中n l为单位化的法向量 光向量. 如果 n.l = 0 镜面光也为0. 镜面光还有另外的计算方式, 如Blinn提出的 specular = (n.h)
shiness
= (cosO)
shiness
,
其中h = (l+v) / ||l+v||, 即l和v的平分线方向的单位向量. )
- NLP同上
- V是视线的反向量;
- H是V和L的中线; normalize( (V+L)/2 );
- shiness是光强度参数
- facing是一个布尔值,如果N·L 是大于0的,取值为1,说明光源向量L是面对表面的,和上头max(N·L, 0)作用一样。背对光源还要什么specular,diffuse啊!
![](https://img-my.csdn.net/uploads/201209/21/1348209708_6226.jpg)