参考资料
nvidia官网cg编程指南链接
基本光照
固定管道使用的基本光照计算公式
surfaceColor = emissive + ambient + diffuse + specular
surfaceColor:最终颜色
emissive:自发光颜色
ambient:环境关颜色
diffuse:漫反射关颜色
specular:镜面高光颜色
光照计算
emissive = Ke
ke:材质的emissive颜色
自发光是在没有光照的情况下现在的颜色,光照计算直接就是该颜色想象一下在一个黑暗无光的背景,如果物体emissive=color(1,0,0,1),当前物体就显示出红色,surfaceColor = emissive + 0+ 0 + 0
ambient = Ka x globalAmbient
Ka:材质的ambient颜色
globalAmbient:全局环境光的颜色
diffuse = Kd x lightColor x max(N · L, 0)
kd:材质的漫反射颜色
lightColor :漫反射光照颜色
N:物体表面法线
L:光照向量(是从表面位置指向光源位置的向量,与光的方向相反)
当N与L之间的夹角大于90度是值为负数,光照不能照到物体的背面故取值为0
其中向量全部归一化了
specular = Ks x lightColor x facing x (max(N · H, 0)) shininess
Ks :材质的镜面反射颜色
lightColor:漫反射光照颜色
facing:默认为1,协调光照,相当于光照强度
N:物体表面法线
V:视角,物体到摄像机向量
L:光照向量(是从表面位置指向光源位置的向量,与光的方向相反)
H:H = V+L (N与L之间夹角中一半的向量);
shininess:高光级别值越大高光区域越小(是N*H的幂N*H的值在0-1)
其中向量全部归一化了
常用选项
其中emissive一般用于特殊效果,最常用的光照模型是排除他的及
surfaceColor = ambient + diffuse + specular
ambient :一般在一个场景中就一个环境光
diffuse 与specular的光照颜色一般在同一个光源里面设置同样的颜色
上面提到的光照模型还没有计算衰减
方向光不需要衰减,点光源和聚光灯是需要衰减的
光照衰减
衰减公式 :attenuationFactor=1/(Kc+Kl*d+Kq*d^2)
Kc,Kl,Kq:衰减常量
d:当前光照点与光源的距离
平行光
光线是平行了如太阳关,距离太远了所以不需要衰减
点光源
直接在漫反射与镜面发生乘以衰减值attenuationFactor
公式:surfaceColor = emissive + ambient + (diffuse + specular)*attenuationFactor
聚光灯
D:光源方向
V:光源与光照点的向量
取舍:为聚关灯照射的角度一般取cos值
判断一点是否在聚关灯照射范围,取d,v之间的cos值(向量点积)与取舍值比较
if(dot(d,v)<取舍)
return false//不知光照范围
公式:
if(dot(d,v)<取舍)
return false//不在光照范围
else
surfaceColor = emissive + ambient + (diffuse + specular)*attenuationFactor
这样计算的光照在光照范围内是均匀的,而真实世界是有外围衰减的,我们将聚光灯分为两部分,内部光照强度不变,外表向外光照强度递减
使用hlsl及cg都提供的一个内置函数smoothstep(min,max,x),计算0到1的平滑插值范围[min,max]小于min为0,打于max为1hlsl官网函数详情
计算公式为
if(dot(d,v)<取舍)
return false//不在光照范围
else
surfaceColor = emissive + ambient +
(diffuse + specular)*attenuationFactor*smoothstep(外部,内部,dot(d,v))