代碼來自於 馮樂樂 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"
}