半蘭伯特光照模型

由於使用漫反射光照的時候 在光照面和半光照面結合處出現了鋸齒形狀,影響模型的效果,Value公司 提出一種技術,在原蘭伯特光照模型基礎上做出了修改解決了漫反射中的的問題,依次被稱爲半蘭伯特光照模型

廣義半蘭伯特計算公式:

C^{_{diffuse}}=(C_{light}* M_{diffuse})max(0,\hat{n}\cdot \hat{l}))(C_{light} * M_{diffuse})(α(\hat{n}\cdot\hat{l})+β)

沒有采用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"
}

三種效果比較:向光面

背光面:

可以看出來半蘭伯特光照在背面也是有明顯的明暗變化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章