老样子,还是先上效果图:
菲涅尔效果的原理大家可以自己去百度看看,网上有很多,这里就不多说了,我们直接看如何实现这个效果
实现思路:
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
}
}
}