立方体 反射 CubeMap
立方体反射(CubeMap)
在虚拟环境中,我们需要模拟材质球反射周围的环境,立方体反射正是让材质球反射出天空盒的背景的方法之一。
原理
当我们观察物体时,物体表面足够光滑,再视线方向和物体相交的点上,能够看到物体映射的周围环境,交点上呈现的正是沿着反射方向观察到的物体。
1. 我们需要在同一空间(这里是世界空间)中计算 视线方向I、反射向量R;
视线方向: float3 I = posW -_WorldSpaceCameraPos.xyz;//摄像机指向顶点的方向
反射向量: o.R = reflect(I,N);//反射向量,cg内置函数
源代码:
1 Shader "JQM/CubeReflectCube" 2 { 3 Properties 4 { 5 _Reflectivity ("Reflectivity", Range (0,1)) = 0.5 6 _MainTex("Base", 2D) = "white" 7 _Environment ("Environment", Cube) = "white" 8 } 9 10 SubShader 11 { 12 13 Pass 14 { 15 CGPROGRAM 16 17 #pragma vertex vert 18 #pragma fragment frag 19 20 #include "UnityCG.cginc" 21 22 sampler2D _MainTex; 23 float4 _MainTex_ST; 24 25 samplerCUBE _Environment; 26 float _Reflectivity; 27 28 struct v2f 29 { 30 float4 pos : SV_POSITION; 31 float2 uv : TEXCOORD0; 32 float3 R:TEXCOORD1; 33 }; 34 35 v2f vert (appdata_base v) 36 { 37 v2f o; 38 o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 39 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); 40 41 float3 posW = mul(_Object2World,v.vertex).xyz; 42 float3 I = posW -_WorldSpaceCameraPos.xyz;//顶点到摄像机方向 43 float3 N = mul((float3x3)_Object2World,v.normal); 44 N = normalize(N); 45 o.R = reflect(I,N);//反射向量 46 47 48 return o; 49 } 50 51 fixed4 frag (v2f i) : SV_Target 52 { 53 float4 reflectiveColor = texCUBE(_Environment,i.R); 54 float4 decalColor = tex2D(_MainTex,i.uv); 55 float4 outp = lerp(decalColor,reflectiveColor,_Reflectivity); 56 return outp; 57 58 } 59 ENDCG 60 } 61 } 62 }