菲涅尔效果.书上的公式,效果图
和原书相比,代码上我稍微调整了下:1 添加了菲涅尔颜色,让效果更显而易见. 2 添加了菲涅尔范围控制,原书中是固定值,我改为范围变量.代码如下:
Shader"wx/Fresnel"{ Properties{ _Color("Color Tint",Color)=(1,1,1,1) _FresnelScale("Fresnel Scale",Range(0,1))=0.5 _Cubemap("Reflection Cubemap",Cube)="_Skybox"{} _FresnelColor("Fresnel Color",Color)=(1,1,1,1) _FresnelRange("Fresnel Range",Range(0,10))=5 } Subshader{ Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" fixed4 _Color; fixed4 _FresnelColor; fixed _FresnelScale; samplerCUBE _Cubemap; half _FresnelRange; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; }; struct v2f { float4 pos:SV_POSITION; float3 worldNormal:TEXCOORD0; float4 worldPos:TEXCOORD1; float3 worldViewDir:TEXCOORD2; float3 worldRefl:TEXCOORD3; }; v2f vert (a2v v){ v2f o; o.pos=UnityObjectToClipPos(v.vertex); o.worldNormal=UnityObjectToWorldNormal(v.normal); o.worldPos=mul(unity_ObjectToWorld,v.vertex); o.worldViewDir=normalize(UnityWorldSpaceViewDir(o.worldPos)); o.worldRefl=reflect(-o.worldViewDir,o.worldNormal); return o; } fixed4 frag(v2f i):SV_Target{ fixed3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz; fixed3 reflection=texCUBE(_Cubemap,i.worldRefl).rgb; fixed3 fresnel=_FresnelScale+(1-_FresnelScale)*pow(1-dot(i.worldViewDir,i.worldNormal),_FresnelRange); fixed3 diffuse=_LightColor0.rgb*_Color.rgb*max(0,dot(i.worldNormal,worldLightDir)); fixed3 color=ambient+lerp(diffuse,reflection,saturate(fresnel)*_FresnelColor); return fixed4(color,1.0); } ENDCG } } }