UnityShader(十一)半兰伯特模型

目录

兰伯特定律

半兰伯特光照模型(Half Lambert)

实现:


兰伯特定律

在平面某点漫反射光的光强与该反射点的法向量和入射光角度的余弦成正比。

半兰伯特光照模型(Half Lambert)

半兰伯特光照模型是在原兰伯特光照模型的基础上进行了简单的修改。

广义的半兰伯特光照模型的公式如下:

c_{diffuse}=\left ( c_{light}\cdot m_{diffuse} \right )\left ( \alpha \left ( \widehat{n}\cdot \widehat{l} \right )+\beta \right )

与原兰伯特模型相比,半兰伯特光照模型没有使用max操作来防止nl的点积为负值,而是对其结果进行了一个a倍的缩放再加上一个β大小的偏移。绝大多数情况下,aβ的值均为0.5

这样就可以把n.l的结果范围从[-1,1]映射到[0,1]范围内。

需要注意的是,半兰伯特模型没有任何物理依据,只是一个视觉加强技术。 

实现:

Shader "MyShader/HalfLambert"
{
    Properties
    {
        _Diffuse ("Diffuse",Color)=(1,1,1,1)
    }
 
    SubShader  {
        Pass
        {
            Tags{"LightMode"="ForwardBase"}
 
            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;
                fixed3 worldNormal:TEXCOORD0;
            };
            
            v2f vert(a2v v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
                return o;
            }
 
            //修改片元着色器中计算漫反射光照的部分
            fixed4 frag(v2f i):SV_TARGET
            {
               fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
                fixed3 worldNormal=normalize(i.worldNormal);
                fixed3 worldDir=normalize(_WorldSpaceLightPos0.xyz);

                fixed halfLambert= dot(worldNormal,worldDir)*0.5+0.5;
                fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*halfLambert;

                fixed3 color=ambient+diffuse;
 
                return fixed4(color,1.0);
            }
 
            ENDCG
        }
    }
 
    FallBack "Diffuse"
 
}

效果:

UnityShader(十一)半兰伯特模型_第1张图片

你可能感兴趣的:(UnityShader入门学习,unity,图形渲染,着色器,游戏引擎)