现在还没用到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函数
看下效果
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。