Shader 学习笔记(14) Fresnel 效果

时间:2021-11-30 04:36:53

菲涅尔效果.书上的公式Shader 学习笔记(14) Fresnel 效果,效果图Shader 学习笔记(14) Fresnel 效果

和原书相比,代码上我稍微调整了下: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
		}
	}
}