1. 程式人生 > >利用立方體貼圖的折射 10.1.4

利用立方體貼圖的折射 10.1.4

//10.1.4

Shader "Unlit/Chapter10-Reflection"
{
	Properties
	{
		//物體顏色
		_Color("Color Tint",Color) = (1,1,1,1)
		//折射顏色
		_RefractColor("Refract Color",Color) = (1,1,1,1)
		//折射程度
		_ReflractAmount("Refract Amount",Range(0,1)) = 1
		//模擬折射的環境對映紋理
		_Cubemap("Refraction Cubemap",Cube) = "_Skybox"{}

		//折射比
		_RefractRatio("Refraction Ratio",Range(0.1,1))=0.5
	}
		SubShader
	{
		//渲染型別=不透明  佇列=幾何
		Tags{ "RenderType" = "Opaque" "Queue" = "Geometry" }

		Pass
	{
		//光照模式=向前渲染
		Tags{ "LightMode" = "ForwardBase" }

		CGPROGRAM

		//定義頂點片元
#pragma vertex vert
#pragma fragment frag

		//確保光照衰減等光照變數可以被正確賦值
#pragma multi_compile_fwdbase

		//包含引用的內建檔案
#include "UnityCG.cginc"
#include "Lighting.cginc"  
#include "AutoLight.cginc"

		//宣告屬性變數
	fixed4 _Color;
	fixed4 _RefractColor;
	float _ReflractAmount;
	//cube 屬性用 samplerCUBE 來宣告
	samplerCUBE _Cubemap;

	float _RefractRatio;

	//定義輸入結構體
	struct a2v
	{
		float4 vertex : POSITION;
		float3 normal:NORMAL;

	};

	//定義輸出結構體
	struct v2f
	{

		float4 pos:SV_POSITION;
		fixed3 worldNormal : TEXCOORD0;
		float3 worldPos:TEXCOORD1;
		fixed3 worldViewDir : TEXCOORD2;
		fixed3 worldRefr : TEXCOORD3;


		//新增內建巨集,宣告一個用於陰影紋理採集的座標,引數是下一個可用的插值暫存器的索引值
		SHADOW_COORDS(4)
	};

	//頂點著色器
	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 = UnityWorldSpaceViewDir(o.worldPos);

		//compute the reflect dir in world space(計算世界空間中的反射方向)
		//用CG的reflect函式來計算該處頂點的反射方向       reflect(物體反射到攝像機的光線方向,法線方向)
		//物體反射到攝像機的的光線方向,可以由光路可逆的原則反向求得,
		//o.worldRefl = reflect(-o.worldViewDir, o.worldNormal);
		
		//計算世界空間中的折射方向
		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 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

	//獲取歸一化的視角方向
	//fixed3 worldViewDir = normalize(i.worldViewDir);
	fixed3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);

	//獲取環境光
	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);

	//Mix the diffuse color whith the reflected color(混合漫反射的顏色和反射的顏色)
	//環境光+插值(漫反射,反射,折射程度)*光照衰減程度
	//fixed3 color = ambient + lerp(diffuse, reflection, _ReflectAmount)*atten;
	//return fixed4(color, 1.0);
	return fixed4(ambient + lerp(diffuse, refraction, _ReflractAmount)*atten, 1.0);

	}
		ENDCG
	}
	}
		FallBack "Reflective/VertexLit"
}