ShaderLab学习小结(十八)cubemap
现在还没用到cubemap(除了天空盒子),只是初步的学了一下最简单的cubemap的shader
找一幅图
好吧,有点大,在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"}
注意,以上这段代码是有问题的,后面会指出问题并改正,先以这段代码来说明
按照注释位置
_Cube ("Cubemap", cube) = "" {} //1.
samplerCUBE _Cube; //2.
2D贴图时,Properties里定义的是2d,而变量声明时用的是sampler2D
而对于cubemap来说则是cube和samplerCUBE
注意:samplerCUBE的CUBE大写,就像sampler2D的D大写一样
先看5
fixed4 col = texCUBE(_Cube, IN.R); //5.
因为按照所学,最后的纹理采样要用到texCUBE这个CG函数,其实看形式和tex2D很像
第一个参数就是我们的cubemap那张图
第二个参数则是在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函数
看下效果
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。