unity shader 菲涅尔效果

17 篇文章 3 订阅
该博客介绍了如何在Unity中实现菲涅尔效果,通过计算视角方向与法线方向的点乘,应用菲涅尔公式,调整颜色,最终达到逼真的表面反射效果。涉及到的关键步骤包括获取法线和视角方向,计算菲涅尔值,以及将结果与自定义颜色相乘。
摘要由CSDN通过智能技术生成

老样子,还是先上效果图:

在这里插入图片描述
菲涅尔效果的原理大家可以自己去百度看看,网上有很多,这里就不多说了,我们直接看如何实现这个效果

实现思路:

1、求得视角方向,法线方向(世界空间下)
2、根据菲涅尔效果的公式:FresnelValue=pow(1-max(0,dot(N,V)),_FresnelPow) ->N:模型顶点法线 V:视角方向 _FresnelPow:菲涅尔效 果的强度
3、将求得的值与颜色相乘,即可

具体实现:

1、首先求世界空间下法线方向,这个比较简单,直接略过
o.normalDir = UnityObjectToWorldNormal(v.normal);
然后在求视角方向:也就是顶点到相机的一个向量,_WorldSpaceCameraPos是shader中的定义好的,代表摄像机的位置
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
2、根据公式,并带入法线,视角方向等数据,_FresnelPow是自定义的一个float值,可自己定义,然后调节看效果
float FresnelValue = pow(1 - max(0,dot(o.normalDir,viewDir)),_FresnelPow)
3、然后自定义一个菲涅尔的颜色(_FresnelColor)与第二部的值相乘即可
fixed4 resultColor =_FresnelColor;
resultColor.rgb *=FresnelValue;
return resultColor;

全部代码:

Shader "Unlit/Fresnel"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _FresnelPow ("菲涅尔强度",float) = 1
        _FresnelColor("菲涅尔颜色",COLOR) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "AutoLight.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float3 normalDir : TEXCOORD1;
                float4 worldPos : TEXCOORD2;
            };
            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FresnelPow;
            fixed4 _FresnelColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.normalDir = UnityObjectToWorldNormal(v.normal);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : COLOR
            {
                i.normalDir = normalize(i.normalDir);
                float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
                float dotValue = pow(1 - saturate(dot(i.normalDir,viewDir)),_FresnelPow);
                fixed4 resultColor = _FresnelColor;
                resultColor.rgb *=dotValue;
                return resultColor;
            }
            ENDCG
        }
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值