Shader
"lijia/fresnelTest"
{
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
}
}
一般运用于水面效果,试想一下你站在湖边,低头看向水里,你会发现近的地方非常清澈见底(反射较少),而看远的地方却倒映着天空(反射较多)。
由于真实的菲尼尔公式计算量较多。在游戏里往往会用简化版的公式来提升效率达到近似的效果
简化后的公式
fresnel = fresnel基础值 + fresnel缩放量*pow( 1 - dot( N, V ), 5 )