US3S1L6-1——Blinn-Phong式高光反射光照模型的逐顶点光照
US3S1L6-1——Blinn-Phong式高光反射光照模型的逐顶点光照
知识回顾
公式:
- 得到的结果就是
- 光泽度是幂运算,假设光泽度为 ,相当于:
利用Blinn-Phong式高光反射模型实现光照效果(逐顶点光照)
关键步骤
-
属性声明(材质高光反射颜色、光泽度)
1
2
3
4
5Properties
{
_SpecularColor("SpecularColor", Color) = (1, 1, 1, 1) //材质高光反射颜色
_SpecularNum("SpecularNum", Range(0, 20)) = 5 //光泽度
} -
渲染标签 Tags 设置将 LightMode 光照模式设置为 ForwardBase 向前渲染(通常用于不透明物体的基本渲染)
1
Tags { "LightMode" = "ForwardBase" }
-
引用内置文件 UnityCG.cginc 和 Lighting.cginc
1
2 -
结构体声明
1
2
3
4
5struct v2f
{
float4 svPos : SV_POSITION;
fixed3 color : COLOR;
}; -
基本公式实现逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22fixed4 _SpecularColor; //材质高光反射颜色
float _SpecularNum; //光泽度
v2f vert (appdata_base v)
{
v2f v2fData;
v2fData.svPos = UnityObjectToClipPos(v.vertex); //首先将模型空间下的顶点转换到裁剪空间下
float3 wNormal = UnityObjectToWorldNormal(v.normal); //得到世界空间下的法线向量
float3 wPos = mul(unity_ObjectToWorld, v.vertex); //使用unity_ObjectToWorld矩阵,将模型空间下的顶点转换到世界空间下
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - wPos); //将摄像机坐标和顶点坐标通过相减,得到观察方向向量,并标准化
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //得到世界空间下的指向光源方向的标准化向量
float3 halfA = normalize(viewDir + lightDir); //将光源方向和观察方向相加得到其半角向量,并标准化
//Blinn-Phong高光反射模型的实现,这里的颜色计算只取rgb,不考虑透明度的情况
v2fData.color = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(wNormal, halfA)), _SpecularNum);
return v2fData;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(i.color.rgb, 1); //因为传递过来的颜色变量不包括透明度,因此这里需要手动指定透明度
}
显示效果(光泽度统一为5,左边为Blinn-Phong式高光反射模型的效果,右边为Phong式高光反射模型的效果):
可见,Blinn-Phong式高光反射模型比Phong式高光反射模型的高光效果更加均匀,面积也更大
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 文KRIFE齐的博客!