由三部分组成 1 ambient 环境光 :没有固定来源,来自周围 2 diffuse 漫反射 :来自光源,但反射向各个方向:需要计算光线和物体表面法线的夹角; !!!:计算向量时确保坐标是在同一空间,要把向量进行标准化。否则计算会出现错误
3 specular 高光:来自光源,反射向另一个方向。需要光线和眼睛的方向
Ⅰ 设置变量
①光照颜色 :这是UI变量,可以在窗口中控制颜色
float4 AmbientColor: Ambient
<
string UIName="AMbient Color";
>=(0.25f,0.25f,0.25f,1.0f);
float4 DiffuseColor: Diffuse
<
string UIName="Diffuse Color";
>=(1.0f,1.0f,1.0f,1.0f);
float4 SpecularColor: Specular
<
string UIName="Specular Color";
>=(1.0f,1.0f,1.0f,1.0f);
②在vertex shader中计算一些必要的信息
Out.lightVec
Out.eyeVec=ViewInverse[3]-worldSpacePos;//眼睛到物体表面顶点的向量,ViewInverse的最后一列是摄像机的位置
③在pixel shader 中对光照做处理
//环境光
float4 Ambient =AmbientColor*ColorTexture; //用环境光乘以贴图得到物体表面颜色
//漫反射
float diffuselight=saturate(dot(normal,lightVec)); //saturate是计算结果在[0,1]范围内
//normal是贴了法线贴图后的法线
//lightVec是光线和顶点之间的向量,在vertex shader中计算后传过来
//normal和lightVec已经标准化过了
float4 Diffuse =diffuselight*DiffuseColor*ColorTexture*lightColor; //lightColor是光源的颜色
//ColorTexture是贴图
//高光
float3 normalEyeVector=normalize(In.eyeVec.xyz);
//光向量和眼睛向量的夹角中线上的向量
float3 half=normalize(lightVec+normalEyeVector);
//光向量和眼睛向量夹角中线和物体法线的夹角
float normal_dot_half=saturate(dot(normal,half));
//控制高光的焦点,限制高光的影响范围
float gloss=Glossiness*SpecularTexture.a; //glossiness是自定义变量。SpectularTexture.a是高光贴图的alpha通道
float SpecularPower=pow(normal_dot_half,gloss);
float4 Specular =SpecularPower*SpecularColor*SpecularTexture;//SpecularTexture用以遮罩
//最终的光为三种光加在一起
float4 finallight= Ambient+Diffuse+Specular;
|