US3S1L5-2——Phong光照模型的逐片元光照
US3S1L5-2——Phong光照模型的逐片元光照
知识回顾
Phong光照模型公式:
其中:
- 环境光颜色 =
UNITY_LIGHTMODEL_AMBIENT
(或者:unity_AmbientSky
、unity_AmbientEquator
、unity_AmbientGround
)- 漫反射光颜色 = 兰伯特光照模型 计算得到的颜色
- 高光反射光颜色 = Phong式高光反射光照模型 计算得到的颜色
利用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;
} -
计算Phong式高光反射光照模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16fixed4 _SpecularColor; //属性设置的材质高光颜色
float _SpecularNum; //属性设置的光泽度
//计算Phong高光反射光照模型 颜色相关函数(逐片元)
//参数:
// wPos: 世界空间下顶点坐标
// wNormal: 世界空间下顶点的法线信息
fixed3 getFragSpecularColor(in float3 wPos, in float3 wNormal)
{
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - wPos); //计算观察方向
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //标准化光源方向
float3 reflectDir = reflect(-lightDir, wNormal); //计算反射光线向量,需要对光源方向取反
//Phong高光反射模型的实现,这里的颜色计算只取rgb,不考虑透明度的情况
fixed3 color = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(viewDir, reflectDir)), _SpecularNum);
return color;
}
完整的Shader代码如下:
1 | Shader "TeachShader/Lesson39" |
显示效果(漫反射颜色为红色,高光反射颜色为白色,光泽度为5,左边为逐片元光照,右边为逐顶点光照):
显然,逐片元光照的效果更平滑
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 文KRIFE齐的博客!