10.1.4 環境映射的立方體紋理 折射

代碼來自於 馮樂樂 shader入門精要

左邊是反射,右邊是折射 

Shader "Chapter10/MyRefractionShader"
{
	Properties
	{
		_Color("Main Color",Color) = (1,1,1,1)
		_RefractColor("Reflect Color",Color) = (1,1,1,1)
		_RefractAmount("Reflect Amount",Range(0,1)) = 1
		//該屬性得到不同介質的透射比,以此來計算折射方向。
		_RefractRatio("Refraction Ratio",Range(0,1)) = 0.5 
		_Cubemap("Cube Map",Cube) = "_Skybox"{}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" "Queue"="Geometry"}

		Pass
		{
			Tags{"LightMode"="ForwardBase"}
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
			#include "AutoLight.cginc"

			struct a2v{
				float4 vertex: POSITION;
				float3 normal: NORMAL;
			};

			struct v2f{
				float4 pos: SV_POSITION;
				fixed3 worldNormal:TEXCOORD;
				fixed3 worldPos:TEXCOORD1;
				fixed3 worldViewDir: TEXCOORD2;
				fixed3 worldRefr:TEXCOORD3;
				SHADOW_COORDS(4)
			};

			fixed4 _Color;
			samplerCUBE _Cubemap;
			fixed4 _RefractColor;
			fixed _RefractAmount;
			fixed _RefractRatio;
			
			v2f vert (a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
				o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
				//它的第一個參數即爲入射光線的方向,它必須是歸一化後的矢量;第二個參數是表面法線,
				//法線方向同樣需要是歸一化後的;第三個參數是入射光線所在介質的折射率和折射光線所在介
				//質的折射率之間的比值,例如如果光是從空氣射到玻璃表面,那麼這個參數應該是空氣的折射
				//率和玻璃的折射率之間的比值,即1/1.5。它的返回值就是計算而得的折射方向,它的模則等於入射光線的模。
				o.worldRefr = refract(-normalize(o.worldViewDir),normalize(o.worldNormal),_RefractRatio);

				TRANSFER_SHADOW(o);

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				fixed3 worldViewDir = normalize(i.worldViewDir);

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

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

				fixed3 refraction = texCUBE(_Cubemap,i.worldRefr).rgb * _RefractColor.rgb;

				UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);

				//混合漫反射顏色和折射顏色,並和環境光照相加後返回
				fixed3 color = ambient + lerp(diffuse,refraction,_RefractAmount)*atten;

				return fixed4(color,1.0);

			}
			ENDCG
		}
	}
	Fallback "Reflective/VertexLit"
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章