UnityShader入门精要第十章代码解析(菲涅尔效果)

菲涅尔效果:光线照射到物体表面时,一部分光发生反射,一部分光进入物体内部发生折射或者散射。

Schlick菲涅尔近似等式:

 

Empricial菲涅耳近似等式:

 v是视角方向,n是法线,bias、scale、power是控制项。

Shader "Custom/12"
{
	Properties
	{
		_Color("Color Tint",Color) = (1,1,1,1)
		_FresnelScale("Fresnel Scale",Range(0,1)) = 0.5
		_Cubemap("reflection Cubemap",Cube) = "_Skybox"{}

	}

	SubShader
	{
		Tags{"RenderType" =  "Opaque" "Queue" = "Geometry"}

		pass
		{
			Tags{"LightMode" = "ForwardBase"}

			CGPROGRAM

			#pragma multi_compile_fwdbase
			
			#pragma vertex vert 
			#pragma fragment frag

			#include "Lighting.cginc"
			#include "AutoLight.cginc"


			fixed4 _Color;
			fixed _FresnelScale;
			samplerCUBE _Cubemap;

			struct a2v
			{
				fixed4 vertex : POSITION;
				fixed3 normal : NORMAL;
			};

			struct v2f
			{
				fixed4 pos : SV_POSITION;
				fixed3 worldPos : TEXCOORD0;
				fixed3 worldNormal : TEXCOORD1;
				fixed3 worldViewDir : TEXCOORD2;
				fixed3 worldRefl : TEXCOORD3;

				SHADOW_COORDS(4)
			};

			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);

				o.worldRefl = reflect(-o.worldViewDir,o.worldNormal);

				TRANSFER_SHADOW(o);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target 
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				fixed3 viewDir = normalize(i.worldViewDir);

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Color.rgb;
				
				UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);

				fixed3 reflection = texCUBE(_Cubemap,i.worldRefl).rgb;

				fixed fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(viewDir , worldNormal),5);

				fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(0,dot(worldNormal,lightDir));

				fixed3 color = ambient + lerp(diffuse,reflection,saturate(fresnel)) * atten;

				return fixed4 (color,1.0);
			}

			ENDCG
		}
	}
	FallBack "Reflective/VertexLit"
}

fixed fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(viewDir , worldNormal),5);
 

此处单纯混合了漫反射和反射。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码在文件 Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Diffuse (RGB) Alpha (A)", 2D) = "white" {} _SpecularTex ("Specular (R) Gloss (G) Anisotropic Mask (B)", 2D) = "gray" {} _BumpMap ("Normal (Normal)", 2D) = "bump" {} _AnisoTex ("Anisotropic Direction (RGB)", 2D) = "bump" {} _AnisoOffset ("Anisotropic Highlight Offset", Range(-1,1)) = -0.2 _Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5 } SubShader{ Tags { "RenderType" = "Opaque" } CGPROGRAM struct SurfaceOutputAniso { fixed3 Albedo; fixed3 Normal; fixed4 AnisoDir; fixed3 Emission; half Specular; fixed Gloss; fixed Alpha; }; float _AnisoOffset, _Cutoff; inline fixed4 LightingAniso (SurfaceOutputAniso s, fixed3 lightDir, fixed3 viewDir, fixed atten) { fixed3 h = normalize(normalize(lightDir) + normalize(viewDir)); float NdotL = saturate(dot(s.Normal, lightDir)); fixed HdotA = dot(normalize(s.Normal + s.AnisoDir.rgb), h); float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180))); float spec = saturate(dot(s.Normal, h)); spec = saturate(pow(lerp(spec, aniso, s.AnisoDir.a), s.Gloss * 128) * s.Specular); fixed4 c; c.rgb = ((s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * spec)) * (atten * 2); c.a = 1; clip(s.Alpha - _Cutoff); return c; } #pragma surface surf Aniso #pragma target 3.0 struct Input { float2 uv_MainTex; float2 uv_AnisoTex; }; sampler2D _MainTex, _SpecularTex, _BumpMap, _AnisoTex; void surf (Input IN, inout SurfaceOutputAniso o) { fixed4 albedo = tex2D(_MainTex, IN.uv_MainTex); o.Albedo = albedo.rgb; o.Alpha = albedo.a; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex)); fixed3 spec = tex2D(_SpecularTex, IN.uv_MainTex).rgb; o.Specular = spec.r; o.Gloss = spec.g; o.AnisoDir = fixed4(tex2D(_AnisoTex, IN.uv_AnisoTex).rgb, spec.b); } ENDCG } FallBack "Transparent/Cutout/VertexLit" }[/code]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值