ShaderLab學習小結(十八)cubemap
阿新 • • 發佈:2018-02-11
mar shader sha pass mage text 向量 平行光 cgp 現在還沒用到cubemap(除了天空盒子),只是初步的學了一下最簡單的cubemap的shader
找一幅圖
好吧,有點大,在unity裏把它設置成cubemap
OK,圖有了,看shader,代碼挺簡單的,其實和普通的2D貼圖shader挺像 第一個參數就是我們的cubemap那張圖
第二個參數則是在vert程序中計算的一個世界坐標系下的反射向量,float3的
再看4是如何計算這個反射的
其實也不能說錯了,如果就是要這個效果的話
用光與法線算出來的反射,因為光是平行光固定的,頂點法線也是固定的,反射也是固定的
所以算出來的顏色是固定,就有了這個效果
但如果想實現的是像鏡面那種效果的話,隨著視角的不同,看到的東西並不相同,代碼就要做些修改了
既然是隨視角變化,那是不是認為不要用光的方向而是用視方向
我們把註釋的3和4改一下
找一幅圖
好吧,有點大,在unity裏把它設置成cubemap
OK,圖有了,看shader,代碼挺簡單的,其實和普通的2D貼圖shader挺像
Shader "Custom/Cubemap" { Properties { _Cube ("Cubemap", cube) = "" {} //1. } SubShader { pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" #include "Lighting.cginc" samplerCUBE _Cube; //2. struct v2f { float4 pos:POSITION; float3 R:TEXCOORD0; }; v2f vert(appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); float3 L= -_WorldSpaceLightPos0.xyz; //3. float3 N = UnityObjectToWorldNormal(v.normal); o.R = reflect(L, N); //4. return o; } fixed4 frag(v2f IN):COLOR { fixed4 col = texCUBE(_Cube, IN.R); //5. return col; } ENDCG } } FallBack "Diffuse" }
註意,以上這段代碼是有問題的,後面會指出問題並改正,先以這段代碼來說明
按照註釋位置
1、2
_Cube ("Cubemap", cube) = "" {} //1.
samplerCUBE _Cube; //2.
2D貼圖時,Properties裏定義的是2d,而變量聲明時用的是sampler2D
而對於cubemap來說則是cube和samplerCUBE
註意:samplerCUBE的CUBE大寫,就像sampler2D的D大寫一樣
3、4、5
先看5
fixed4 col = texCUBE(_Cube, IN.R); //5.
因為按照所學,最後的紋理采樣要用到texCUBE這個CG函數,其實看形式和tex2D很像
第二個參數則是在vert程序中計算的一個世界坐標系下的反射向量,float3的
再看4是如何計算這個反射的
o.R = reflect(L, N); //4.
反射嗎,當然是光和法線,而這個L,是光的入射,即從光源指向頂點
reflect函數是計算反射向量的
所以看3
float3 L= -_WorldSpaceLightPos0.xyz; //3.
以前用到這個世界坐標空間下的光方向_WorldSpaceLightPos0.xyz,這個是從頂點指向光源的方向,現在正好相反,所以取負
貌似OK了,我們看看結果,在場景中建一個球體,把這個材質賦給它,並轉動視角
其實也不能說錯了,如果就是要這個效果的話
用光與法線算出來的反射,因為光是平行光固定的,頂點法線也是固定的,反射也是固定的
所以算出來的顏色是固定,就有了這個效果
但如果想實現的是像鏡面那種效果的話,隨著視角的不同,看到的東西並不相同,代碼就要做些修改了
既然是隨視角變化,那是不是認為不要用光的方向而是用視方向
我們把註釋的3和4改一下
float3 V = -WorldSpaceViewDir(v.vertex); //3.
o.R = reflect(V, N); //4.
這裏用了視方向,同樣是從眼睛指向頂點,所以也取負
再用reflect函數
看下效果
ShaderLab學習小結(十八)cubemap