漫反射-逐像素光照(半兰伯特)

来源:互联网 发布:网络电视机顶盒直播软件哪个好 编辑:程序博客网 时间:2024/06/06 12:29
Shader "Custom/testShader" {
 properties
 {
     _Diffuse("my Diffuse",Color)=(1.0, 1.0, 0.0, 1.0)     
 }
 subshader
 {
     Tags{"LightMode"="ForwardBase"}
     pass
     {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "Lighting.cginc"

        fixed4 _Diffuse;

        struct a2v
        {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
        };
        struct v2f
        {
            float4 pos : SV_POSITION;
            float3 worldNormal : TEXCOORD0;
        };


        v2f vert(a2v v)
        {
            v2f o;
            o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
            o.worldNormal = mul(v.normal, (float3x3)_World2Object);
            return o;
        }
        fixed4 frag(v2f i):SV_Target           //计算漫反射光照模型
        {
            fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;            //得到环境光
            fixed3 worldNormal = normalize(i.worldNormal);                         //得到世界空间中的法线
            fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);      //得到世界空间中的光照
            fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb *saturate(dot(worldNormal, worldLightDir));                                                                                                                 
            fixed3 color = ambient + diffuse;
            return fixed4(color, 1.0);
        }
        ENDCG
     }
 }
  Fallback "Diffuse"

}


【说明】

1. 顶点着色器不需要计算光照模型,只需要把世界空间下的法线传递给片元着色器即可。

2. 在光线无法达到的区域,模型的外观是黑色的,解决背光面明暗问题,提出了半兰伯特模型

     在逐像素光照上只需改变如下:

      fixed4 frag(v2f i) : SV_Target {
// Get ambient term
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;  
fixed3 worldNormal = normalize(i.worldNormal); 
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); 
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);
}


3. 半兰伯特模型原理:

         Half Lambert技术实现的是原理是把漫反射光照值的范围分成两半,然后加上0.5。基本意思就是如果光照值是1,对半开后就是0.5,然后再加0.5回去,将会再得到1。如果你对0进行操作,那么你会得到0.5,因此我们将0~1之间的值重新映射到区间0.5~1。
       下图展示了漫反射的值经过Half Lambert计算后的函数曲线图。

0 0