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模型 更符合实验结果。

发布了76 篇原创文章 · 获赞 43 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/hnzmdlhc/article/details/104403132