斯涅尔定律-Snell’s Law :n1 * Sin a = n2 * Sin b,n1 和 n2就是两个物体的折射比,a = 入射角 b = 反射角 移动 :n1 / n2 = sin b / sin a = 透射比。
Shader "QShader/Refract" {
Properties{
_BaseColor ( "Base Color" , Color) = ( 1. 0, 1. 0, 1. 0, 1. 0)
_RefractColor ( "Refract Color" , Color) = ( 1. 0, 1. 0, 1. 0, 1. 0)
_RefractAmount ( "Refract Amount" , Range ( 0 , 1 ) ) = 1.0
_RefractRatio ( "Refract Ratio" , Range ( 0.1 , 1 ) ) = 0.5
_RefractTex ( "Refract Texture" , Cube) = "skybox" { }
}
SubShader{
pass {
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
} ;
struct v2f {
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
float3 worldNormal : TEXCOORD1;
float3 worldViewDir : TEXCOORD2;
float2 uv : TEXCOORD3;
float3 worldRefractDir : TEXCOORD4;
SHADOW_COORDS ( 5 )
} ;
fixed4 _BaseColor;
fixed4 _RefractColor;
float _RefractAmount;
float _RefractRatio;
samplerCUBE _RefractTex;
v2f Vertex ( a2v v) {
v2f o;
o. pos = UnityObjectToClipPos ( v. vertex) ;
o. worldPos = mul ( unity_ObjectToWorld, v. vertex) . xyz;
o. worldNormal = UnityObjectToWorldNormal ( v. normal) ;
o. uv = v. texcoord;
o. worldViewDir = UnityWorldSpaceViewDir ( o. worldPos) ;
o. worldRefractDir = refract ( normalize ( o. worldViewDir) , normalize ( o. worldNormal) , _RefractRatio) ;
TRANSFER_SHADOW ( o)
return o;
}
fixed4 Fragment ( v2f i) : SV_TARGET{
fixed3 worldNormal = normalize ( i. worldNormal) ;
fixed3 lightDir = normalize ( UnityWorldSpaceLightDir ( i. worldPos) ) ;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT. xyz * _BaseColor. xyz;
fixed3 diffuse = _LightColor0. xyz * _BaseColor. xyz * saturate ( dot ( worldNormal, lightDir) ) ;
fixed3 refraction = texCUBE ( _RefractTex, i. worldRefractDir) * _RefractColor. xyz;
UNITY_LIGHT_ATTENUATION ( atten, i, i. worldPos) ;
return fixed4 ( ambient + lerp ( diffuse, refraction, _RefractAmount) * atten, 1.0 ) ;
}
ENDCG
}
}
}