Cook-Torrance光照模型

 金屬效果html

Cook-Torrance光照模型

  該光照模型是基於物理材質的光照模型。光照射到物體表面發生漫反射、鏡面反射、折射、透射等現象,在這裏咱們只考慮漫反射和鏡面反射,Cook-Torrance是用來模擬不一樣材質的鏡面反射效果。app

  

    其中:函數

      ambient :環境光;spa

      K:決定高光部分和漫射的比例,通常而已,光復合能量守恆定律,即入射光的總能量和出射光的總能量相等;code

      rs :鏡面發射;orm

  

F項:菲涅爾反射

  即Fresnel,菲涅爾反射。咱們在觀察水面的時候,垂直看下去,清澈見底,看遠處的水面,向鏡子同樣,這個就是菲涅爾效應。菲涅爾效應能夠說是無處不在,不一樣的材質效果不一樣而已。htm

  

    v:視點的方向;blog

    h:半角向量,即視點和光線的中間向量;get

D項:微平面法線分佈函數

  該項模擬物體表面是由無數微小的像鏡子同樣的平面組成,每個微平面對於光線會根據自身的方向反射光線,只有那些面向視點的平面貢獻大。具體參見微平面法線分佈的理論。it

  

G項:幾何項

   該項用於計算微平面中反射光重合部分的修正。

  

  

  

=============================================================================

 

Shader "JQM/Cook-Torrance"
{
    Properties
    {
        _Color("Base Color",Color) = (1,1,1,1)
        _MainTex ("Texture", 2D) = "white" {}

        _Roughness("Roughness",Range(0,1)) = 1
        _Fresnel("Fresnel",Range(0,1)) = 1
        _K("K",Range(0,1)) = 1

        _Environment ("Environment", Cube) = "white"
    }

    
    SubShader
    {

        Pass
        {
            Tags { "LightMode" = "ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"

            float4 _Color;
            //使用Unity定義的變量:燈光
            uniform float4 _LightColor0;


            float _Roughness;
            float _Fresnel;
            float _K;
            samplerCUBE _Environment;

            struct VertexOutput
            {
                float4 pos : SV_POSITION;
                float4 posWorld : TEXCOORD1;
                float2 uv : TEXCOORD2;
                float3 normal:Normal;
                
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            VertexOutput vert (appdata_full v)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.posWorld = mul(_Object2World, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.normal = v.normal;

                return o;
            }

            fixed4 frag (VertexOutput i) : COLOR
            {
                //將法線轉到世界空間:乘以變換矩陣的逆的轉置
                //float3 normalWorld  = mul(_Object2World,i.normal);
                float3 normalWorld  = mul(i.normal,_World2Object);

                //觀察者
                float3 eyeDir = normalize(_WorldSpaceCameraPos -i.posWorld).xyz;

                //光源
                float3 lightDir = normalize(_WorldSpaceLightPos0).xyz;

                fixed4 col = tex2D(_MainTex, i.uv);

                ///計算漫反射
                float3 diffuse = _Color;

                //計算天空盒
                float3 r = reflect(-eyeDir,normalWorld);
                float4 reflectiveColor = texCUBE(_Environment,r);



                //計算高光
                //float3 h = (eyeDir+lightDir)/2;
                //float3 r = normalize(reflect(-lightDir,normalWorld));
                //float3 specular = saturate(dot(lightDir,normalWorld))* _SpecularColor * pow(saturate(dot(r,eyeDir)),_SpecularPower);

                //計算Cook-Torrance高光
                float s;
                float ln = saturate(dot(lightDir,normalWorld));

                if(ln > 0.0)//在光照範圍內
                {
                    float3 h = normalize(eyeDir+lightDir);
                    float nh = saturate(dot(normalWorld, h));
                    float nv = saturate(dot(normalWorld, eyeDir));                
                    float vh = saturate(dot(eyeDir, h));
                    
                    //G項
                    float nh2 = 2.0*nh;
                    float g1 = (nh2*nv)/vh;
                    float g2 = (nh2*ln)/vh;
                    float g = min(1.0,min(g1,g2));

                    //D項:beckmann distribution function
                    float m2 = _Roughness*_Roughness;
                    float r1 = 1.0/(4.0 * m2 *pow(nh,4.0));
                    float r2 = (nh*nh -1.0)/(m2 * nh*nh);
                    float roughness = r1*exp(r2);

                    //F項
                    float fresnel = pow(1.0 - vh,5.0);
                    fresnel *= (1.0-_Fresnel);
                    fresnel += _Fresnel;
                    s = saturate((fresnel*g*roughness)/(nv*ln*3.14));

                    //reflectiveColor *= fresnel;
                }
                
                float3 final =_LightColor0*ln*(_K*diffuse*reflectiveColor*2 + s*(1-_K)*reflectiveColor*2) + UNITY_LIGHTMODEL_AMBIENT.xyz;
                return float4(final,1);
            }
            ENDCG
        }
    }
}

 

 

  參考資料:

Google:http://ruh.li/GraphicsCookTorrance.html

相關文章
相關標籤/搜索