本节基础知识结构
基础光照部分
环境光
在标准光照模型中,我们会环境光来代替间接光照
Cambient = g amient
我们可以在Windows->Rendering->Lighting->Enviroment进行修改Ambient 的Color
自发光
直接在最后片元着色器输出颜色之前把材质的自发光颜色添加到输出颜色上就行了
漫反射光照模型
为了缩短文章篇幅,因此我就只在片元着色器上计算光照,不考虑高洛德着色
n代表法向量,I代表光源反向(注意方向是否需要取反)
兰伯特模型
v2f vert(a2v v) {
v2f o;
// Transform the vertex from object space to projection space
o.pos = UnityObjectToClipPos(v.vertex);
// Transform the normal from object space to world space
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
return o;
}
fixed4 frag(v2f i) : SV_Target {
// Get ambient term
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
// Get the normal in world space
fixed3 worldNormal = normalize(i.worldNormal);
// Get the light direction in world space
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
// Compute diffuse term
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));
fixed3 color = ambient + diffuse;
return fixed4(color, 1.0);
}
实现效果如下
半兰伯特模型
v2f vert(a2v v) {
v2f o;
// Transform the vertex from object space to projection space
o.pos = UnityObjectToClipPos(v.vertex);
// Transform the normal from object space to world space
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
return o;
}
fixed4 frag(v2f i) : SV_Target {
// Get ambient term
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
// Get the normal in world space
fixed3 worldNormal = normalize(i.worldNormal);
// Get the light direction in world space
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
// Compute diffuse term
fixed halfLambert = dot(worldNormal, worldLightDir) * 0.5 + 0.5;
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;
fixed3 color = ambient + diffuse;
return fixed4(color, 1.0);
}
实现效果如下
高光反射光照模型
同样,我们这里就只在片元着色器里实现高光,不考虑顶点着色
这个函数对于性能的消耗非常大,尽量少用吧。
Blinn-Phong就避免了这种情况
这种模型为了避免计算反射向量,用半角向量h代替
半角向量和法线的接近程度同样可以反应高光程度。
这些模型都是经验模型,不是完全符合物理的。图形学第一定律:If it looks right,it is right.