Shader-FresnelReflection(菲涅尔反射)

2019-06-17 14:37:53 浏览数 (1)

菲涅尔公式:用来描述光在不同折射率的介质之间的行为。用公式推导出的光的反射称之为“菲涅尔反射”。

fresnelRes.PNG

应用:运用于类似水面的效果,在近的地方反射较少,看远的地方反射较多。这种效果称之为菲涅尔效应。

在用系统简化公式提升效率: fresnel = fresnel基础值 fresnel缩放量*pow( 1 - dot( N, V ), 5 ) N-法线 V-观察向量 L-平行光方向

代码语言:javascript复制
Shader "Unlit/FresnelReflection"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _fresnelBase("fresnelBase", Range(0, 1)) = 1
        _fresnelScale("fresnelScale", Range(0, 1)) = 1
        _fresnelIndensity("fresnelIndensity", Range(0, 5)) = 5
        _fresnelCol("_fresnelCol", Color) = (1,1,1,1)
    }

        SubShader
    {
        Tags{ "RenderType" = "Opaque" }
        LOD 100

        Pass
    {
        tags{ "lightmode=" = "forward" }

        CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"
#include "Lighting.cginc"

        struct appdata
    {
        float4 vertex : POSITION;
        float2 uv : TEXCOORD0;
        float3 normal : NORMAL;
    };

    struct v2f
    {
        float2 uv : TEXCOORD0;
        float4 vertex : SV_POSITION;
        float3 L : TEXCOORD1;
        float3 N : TEXCOORD2;
        float3 V : TEXCOORD3;
    };

    sampler2D _MainTex;
    float4 _MainTex_ST;

    float _fresnelBase;

    float _fresnelScale;

    float _fresnelIndensity;

    float4 _fresnelCol;

    v2f vert(appdata v)
    {
        v2f o;
        o.vertex = UnityObjectToClipPos(v.vertex);
        o.uv = TRANSFORM_TEX(v.uv, _MainTex);
        //将法线转到世界坐标
        o.N = mul(v.normal, (float3x3)unity_WorldToObject);
        //获取世界坐标的光向量
        o.L = WorldSpaceLightDir(v.vertex);
        //获取世界坐标的视角向量
        o.V = WorldSpaceViewDir(v.vertex);
        return o;
    }

    fixed4 frag(v2f i) : SV_Target
    {
        fixed4 col = tex2D(_MainTex, i.uv);

    float3 N = normalize(i.N);
    float3 L = normalize(i.L);
    float3 V = normalize(i.V);

    col.rgb *= saturate(dot(N, L)) * _LightColor0.rgb;
    //菲尼尔公式
    float fresnel = _fresnelBase   _fresnelScale * pow(1 - dot(N, V), _fresnelIndensity);

    col.rgb  = lerp(col.rgb, _fresnelCol, fresnel) * _fresnelCol.a;

    return col;
    }

        ENDCG
    }
    }
}

fresnelBase表示基础值,fresnelScale表示fresnel效果系数,fresnelIndensity增强次数

fresnelSet.PNG

0 人点赞