• Cook-Torrance光照模型


     金属效果

    Cook-Torrance光照模型

      该光照模型是基于物理材质的光照模型。光照射到物体表面发生漫反射、镜面反射、折射、透射等现象,在这里我们只考虑漫反射和镜面反射,Cook-Torrance是用来模拟不同材质的镜面反射效果。

      

        其中:

          ambient :环境光;

          K:决定高光部分和漫射的比例,一般而已,光复合能量守恒定律,即入射光的总能量和出射光的总能量相等;

          rs :镜面发射;

      

    F项:菲涅尔反射

      即Fresnel,菲涅尔反射。我们在观察水面的时候,垂直看下去,清澈见底,看远处的水面,向镜子一样,这个就是菲涅尔效应。菲涅尔效应可以说是无处不在,不同的材质效果不同而已。

      

        v:视点的方向;

        h:半角向量,即视点和光线的中间向量;

    D项:微平面法线分布函数

      该项模拟物体表面是由无数微小的像镜子一样的平面组成,每一个微平面对于光线会根据自身的方向反射光线,只有那些面向视点的平面贡献大。具体参见微平面法线分布的理论。

      

    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

  • 相关阅读:
    elastic search配置ik分词及pinyin分词使搜索同时支持中文和拼音搜索
    centos如何配置本地yum源
    PostGIS 3.0.1编译安装
    CentOS7安装GeoServer
    PostgreSQL v12.0在Centos7手动安装
    CentOS7.3镜像下载
    CentOS7各个版本镜像下载地址
    ElasticSerach7.6.0拼音分词器安装和使用
    uDig配图与GeoServer添加Style
    清除SQL2005数据库日志的方法
  • 原文地址:https://www.cnblogs.com/jqm304775992/p/5202973.html
Copyright © 2020-2023  润新知