由於使用漫反射光照的時候 在光照面和半光照面結合處出現了鋸齒形狀,影響模型的效果,Value公司 提出一種技術,在原蘭伯特光照模型基礎上做出了修改解決了漫反射中的的問題,依次被稱爲半蘭伯特光照模型。
廣義半蘭伯特計算公式:
(C * M)(α()+β)
沒有采用max 函數來防止點積爲負值,採用的是α倍的縮放和β倍的偏移。一般情況下,α和β的值均爲0.5
這樣也可以將結果從[-1,1]映射到[0,1],這樣在被光面 也可以有明暗變化(不同的點積結果會映射成不同的值),而不是像之前那樣都爲0在被光面。
半蘭伯特模型 是一種是視覺加強技術,沒有物理依據的。
與漫反射的逐像素光照相比,只是修改了片元函數中漫反射的計算
Shader "Custom/HalfLambert"
{
Properties
{
_DiffuseColor("Color",Color)=(1.0,1.0,1.0,1.0)
}
SubShader
{
pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
fixed4 _DiffuseColor;
struct a2v
{
float4 vertPos:POSITION;
float3 normal:NORMAL;
};
struct v2f
{
float4 pos :SV_POSITION;
float3 normalWorld:TEXCOORD0;
};
v2f vert(a2v v)
{
v2f o;
o.pos=UnityObjectToClipPos(v.vertPos);
o.normalWorld=mul(v.normal,(float3x3)unity_WorldToObject);
return o;
}
fixed4 frag(v2f i):SV_Target
{
fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal=normalize(i.normalWorld);
fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
fixed halfLambert=dot(worldNormal,worldLightDir)*0.5+0.5;
fixed3 diffuse=_LightColor0.rgb*_DiffuseColor.rgb*halfLambert;
return fixed4(ambient+diffuse,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
三種效果比較:向光面
背光面:
可以看出來半蘭伯特光照在背面也是有明顯的明暗變化