概述
Phong式高光反射模型基于光的反射行为和观察者的位置决定高光反射的表现效果,认为高光反射的颜色和光源的反射光线以及观察者位置方向向量夹角的余弦成正比,并且通过对余弦值取n次幂来表示光泽度(反光度)
高光反射光照颜色 = 光源的颜色 * 材质高光反射颜色 * max(0, dot(标准化后观察方向向量, 标准化后的反射方向))幂
幂 代表光泽度
ShaderLab示例
Phong式高光反射模型逐顶点光照
SubShader
{
Tags
{
"LightMode"="ForwardBase"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _SpecularColor;
float _SpecularLevel;
struct v2f
{
float4 vertex : SV_POSITION;
fixed3 color : COLOR;
};
v2f vert(appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
// 将模型空间下的顶点位置转换到世界空间下
float3 worldPos = mul(UNITY_MATRIX_M, v.vertex);
// 获取标准化观察方向向量
float3 viewDir = _WorldSpaceCameraPos.xyz - worldPos;
viewDir = normalize(viewDir);
// 获取标准化反射方向向量
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 normal = UnityObjectToWorldNormal(v.normal);
float3 reflectDir = reflect(-lightDir, normal);
fixed3 color = _LightColor0.rgb * _SpecularColor.rgb * pow(
max(0, dot(viewDir, reflectDir)), _SpecularLevel);
o.color = color;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return fixed4(i.color.rgb, 1);
}
ENDCG
}
}
Phong式高光反射模型逐顶点光照
SubShader
{
Tags
{
"LightMode"="ForwardBase"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _SpecularColor;
float _SpecularLevel;
struct v2f
{
float4 vertex : SV_POSITION;
// 世界空间下的法线信息
fixed3 wNormal : NORMAL;
// 世界空间下的顶点坐标
float3 wPos : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.wNormal = UnityObjectToWorldNormal(v.normal);
o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// 获取标准化观察方向向量
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.wPos);
// 获取标准化反射方向向量
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 reflectDir = reflect(-lightDir, i.wNormal);
fixed3 color = _LightColor0.rgb * _SpecularColor.rgb * pow(
max(0, dot(viewDir, reflectDir)), _SpecularLevel);
return fixed4(color, 1);
}
ENDCG
}
}