Unity图形学之菲尼尔色散Fresnel

发布于:2024-11-28 ⋅ 阅读:(15) ⋅ 点赞:(0)

1.描述多少光被反射,多少被折射,用来渲染一种类似瓷砖表面有釉的那种感觉或者木头表面清漆的效果

2.计算公式:

C(fresnelFinal) =  reflectFact *C (reflect)+(1-reflectFact)* C (refract)

(1)反射因子怎么计算:

fresnelBias      菲尼尔偏移系数
fresnelScale     菲尼尔缩放系数
fresnelPower     菲尼尔指数


reflectFactor =  fresnelBias+fresnelScale*pow(1+dot(viewDir,N),fresnelPower);

(2)反射计算公式:

C (reflect)=  reflect(viewDir,N);

(3)折射计算公式:

C (refract)   =refract (viewDir,N,eatRatio)

Shader "Custom/Fresnel"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _SubTex ("SubTex (RGB)", CUBE) = "white" {}
        
        _EatRation("EatRation",float) = 1.2   //折射率
        _FresnelBias("FresnelBias",float) = 1 //菲尼尔偏移系数
        _FresnelScale("FresnelScale",float) = 1 //菲尼尔缩放系数
        _FresnelPower("FresnelPower",float) = 0.5 //菲尼尔指数
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all  light types
        #pragma surface surf Lambert vertex:MyVertex
        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0
        sampler2D _MainTex;
        samplerCUBE _SubTex;
        struct Input
        {
            float2 uv_MainTex;
            float3 worldRefl;
            //折射
            float3 refract;
            //反射系数
            float reflectFact;
        };
       
       fixed4 _Color;
       float _EatRation;
       float _FresnelBias;
       float _FresnelPower;
       float _FresnelScale;
       void MyVertex(inout appdata_full v,out Input data)
       {
           //初始化Input变量
            UNITY_INITIALIZE_OUTPUT(Input,data);  
           //计算法线,法线转化到local
           float3 localNormal =  normalize(mul(v.normal,(float3x3)unity_WorldToObject));
           //相机的方向 视角到顶点的向量WorldSpaceViewDir(v.vertex) 顶点到视角的向量-WorldSpaceViewDir(v.vertex)
           float3 viewDir = -WorldSpaceViewDir(v.vertex);
           
           //求出折射refract 是API
           data.refract = refract(viewDir,localNormal,_EatRation);
           //计算反射系数
           data.reflectFact =  _FresnelBias+_FresnelScale*pow(1+dot(viewDir,localNormal),_FresnelPower);     
       }
        void surf (Input IN, inout SurfaceOutput o)
        {
            // Albedo comes from a texture tinted by color
            //反射从纹理中采样出来
            // fixed4 cflect = tex2D (_MainTex, IN.worldRefl);
            // fixed4 cfract = tex2D (_MainTex, IN.refract);
            fixed4 cflect = texCUBE (_SubTex, IN.worldRefl);
            fixed4 cfract = texCUBE (_SubTex, IN.refract);
            
            o.Albedo = IN.reflectFact * cflect.rgb+(1-IN.reflectFact)*cfract.rgb;
            
            o.Alpha = cflect.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}