Blinn-Phong 光照模型

前面 我們使用Phong光照模型計算的高光反射,這裏我們 用Blinn-Phong來實現高光反射計算。

在Blinn-Phong中,沒有使用反射方向,而是引入了新的矢量h,它是通過對視角方向v 和光照方向 l 相加後再歸一化得到的。

\hat{h}=(\hat{v}+\hat{l})/(l\hat{v}+\hat{l}l)

所以Blinn-Phong 模型計算高光反射公式如下:

_{Cspecular}=(_{Clight} * _{Mspecular})max(0,\hat{n}\cdot\hat{h})^{_{Mgloss}}

計算如下:

Shader "Custom/SpecularBlinnPhong"
{
    Properties
    {
        _DiffuseColor("DiffuseColor",Color)=(1,1,1,1)
        _SpecularColor("SpecularColor",Color)=(1,1,1,1)
        _Gloss("Gloss",Range(8,256))=20
    }

    SubShader
    {
        pass
        {
            Tags{"LightMode"="ForwardBase"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Lighting.cginc"
            fixed4 _DiffuseColor;
            fixed4 _SpecularColor;
            float _Gloss;


            struct a2v
            {
                float4 vertPos:POSITION;
                float3 normal:NORMAL;

            };

            struct v2f
            {
                float4 pos:SV_POSITION;
                float3 worldNormal:TEXCOORD0;
                float3 worldPos:TEXCOORD1;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertPos);
                o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
                o.worldPos=mul(unity_ObjectToWorld,v.vertPos).xyz;
                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*_DiffuseColor.rgb*saturate(dot(worldNormal,worldLightDir));
                fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));
                fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
                fixed3 halfDir=normalize(worldLightDir+viewDir);
                fixed3 specular=_LightColor0.rgb*_SpecularColor.rgb*pow(max(0,dot(worldNormal,halfDir)),_Gloss);
                fixed3 scolor=ambient+diffuse+specular;
                return fixed4(scolor,1);
            }

            ENDCG
        }

    }
    FallBack "Diffuse"
}

效果如下:右邊是Blinn-Phong光照模型實現的高光反射,左邊是Phong模型實現的。

Blinn-Phong 實現的高光更大,更亮。這兩種模型都是經驗模型。實際上Blinn-Phong模型 更符合實驗結果。

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