利用立方體貼圖的折射 10.1.4
阿新 • • 發佈:2018-12-14
//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" }