US3S1L7-2——Blinn-Phong光照模型的逐片元光照
US3S1L7-2——Blinn-Phong光照模型的逐片元光照
知识回顾
Blinn Phong光照模型公式:
其中:
环境光颜色 =
UNITY_LIGHTMODEL_AMBIENT (unity_AmbientSky、unity_AmbientEquator、unity_AmbientGround)关于上边四个变量,详见:US3S1L5——Phong光照模型
漫反射光颜色 = 兰伯特光照模型 计算得到的颜色
高光反射光颜色 = Blinn Phong式高光反射光照模型 计算得到的颜色
利用Blinn-Phong式光照模型实现光照效果(逐片元光照)
关键步骤:
-
计算兰伯特光照模型
1
2
3
4
5
6
7
8
9
10
11
12fixed4 _MainColor; //属性设置的漫反射颜色
//计算兰伯特光照模型 颜色相关函数(逐片元)
//参数:
// wNormal: 世界空间下顶点的法线信息
fixed3 getFragLambertColor(in float3 wNormal)
{
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //将光源0的位置标准化,得到方向,用于计算夹角
//兰伯特光照模型的实现,这里的颜色计算只取rgb,不考虑透明度的情况
fixed3 color = _LightColor0.rgb * _MainColor.rgb * max(0, dot(wNormal, lightDir));
return color;
} -
计算Blinn-Phong式高光反射光照模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16fixed4 _SpecularColor; //属性设置的材质高光颜色
float _SpecularNum; //属性设置的光泽度
//计算Blinn-Phong高光反射光照模型 颜色相关函数(逐片元)
//参数:
// wPos: 世界空间下顶点坐标
// wNormal: 世界空间下顶点的法线信息
fixed3 getFragSpecularColor(in float3 wPos, in float3 wNormal)
{
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - wPos); //计算观察方向
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //标准化光源方向
float3 halfA = normalize(viewDir + lightDir); //将光源方向和观察方向相加得到其半角向量,并标准化
//Blinn-Phong高光反射模型的实现,这里的颜色计算只取rgb,不考虑透明度的情况
fixed3 color = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(wNormal, halfA)), _SpecularNum);
return color;
}
完整的Shader代码如下:
1 | Shader "TeachShader/Lesson45" |
显示效果(光泽度为5,漫反射颜色为红色,高光反射颜色为白色):

可见,Blinn-Phong式光照模型比Phong式光照模型的高光效果更加均匀,面积也更大
而逐片元光照相比逐顶点光照的光斑边缘也更加平滑
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 文KRIFE齐的博客!
