7.2 改进的立方体程序(下):立方图纹理
除了2D纹理,WebGL还支持立方图纹理。我们知道立方体有六个面,你可以简单地把立方图纹理当成一个立方体,只不过该立方体的每个面是一个2D纹理。换言之,六个单独的2D纹理组成了一个完整的立方图纹理。立方图纹理的操作和2D纹理类似,只是传递的某些参数值变更为TEXTURE_CUBE_MAP、TEXTURE_CUBE_MAP_*,并且设置纹理图像数据的操作要对每个面进行一次。在着色器中,进行取样的内建函数换成textureCube(注意,不是texture3D,立方图纹理和3D纹理不是一回事);取样器和纹理坐标也要相应变换为samplerCube和vec3。
需要注意的是,立方图纹理有一个限制:图像的宽度和高度必须相等。另外,立方体纹理的坐标范围也不再是[0, 1]。它的取样过程可以理解为:首先把立方图纹理想象成一个六面是图像的立方体。你所指定的纹理坐标,对应着一个从该立方体的中心点开始的向量。该向量和该立方体的交点处的图像像素,就是最终的取样值。
在示例代码中,我去除了原先传入2D纹理坐标的相关变量和操作。
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=gb2312">
<script type="text/javascript" src="glMatrix-0.9.5.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 v3Position;
uniform mat4 um4Rotate;
varying vec3 v_texCoord;
void main(void)
{
v_texCoord = v3Position;//由于我们定义的立方体的中心就是(0,0,0),所以取样坐标就是顶点位置
gl_Position = um4Rotate * vec4(v3Position, 1.0);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform samplerCube s_texture;
varying vec3 v_texCoord;
void main(void)
{
gl_FragColor = textureCube(s_texture, v_texCoord);//着色器内建的取样函数要变成立方图纹理的版本
}
</script>
<script>
function ShaderSourceFromScript(scriptID)
{
var shaderScript = document.getElementById(scriptID);
if (shaderScript == null) return "";
var sourceCode = "";
var child = shaderScript.firstChild;
while (child)
{
<head>
<meta http-equiv="content-type" content="text/html; charset=gb2312">
<script type="text/javascript" src="glMatrix-0.9.5.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 v3Position;
uniform mat4 um4Rotate;
varying vec3 v_texCoord;
void main(void)
{
v_texCoord = v3Position;//由于我们定义的立方体的中心就是(0,0,0),所以取样坐标就是顶点位置
gl_Position = um4Rotate * vec4(v3Position, 1.0);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform samplerCube s_texture;
varying vec3 v_texCoord;
void main(void)
{
gl_FragColor = textureCube(s_texture, v_texCoord);//着色器内建的取样函数要变成立方图纹理的版本
}
</script>
<script>
function ShaderSourceFromScript(scriptID)
{
var shaderScript = document.getElementById(scriptID);
if (shaderScript == null) return "";
var sourceCode = "";
var child = shaderScript.firstChild;
while (child)
{