一、OpenGL Cube Texture 立方体纹理
立方体纹理是一种特殊的纹理技术,他用6幅二维贴图构成一个以原点为中心的纹理立方体。对于每个片段,
纹理坐标(s,t,r)被当做三维向量看待,每个纹素(texel)都被看做是从原点看到的立方纹理上的的图像。
指定立方体纹理的6张纹理
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA,
imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA,
imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA,
imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA,
imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA,
imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA,
imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image6);
指定6张纹理的参数
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
想要快速创建一个立方体纹理,可以在场景的原点放置一台照相机,然后让相机Forward依次对准XYZ各轴的正负方向
并且保证相机FOV=90°,快照的的3D空间为在原点相交的6个平截头体。这6张纹理即为立方体纹理的6个2D纹理。
二 OpenGL 立方体纹理采样(纹理纹素获取算法)
正如前面所述,对于每个片段,纹理坐标(s, t, r)被当作方向向量看待,每个纹素(texel)都表示从原点所看到的纹理立方体上的图像。
下面实现代码来自mesa3d里面,源文件路径为Mesa-8.0.4srcmesaswrasts_texfilter.c。
最常见的2个纹理坐标算法:
(1)顶点法线作为纹理坐标,用于天空盒贴图
(2)相机到定点的向量与顶点法线求反射向量,用于做类似环境纹理镜面反射效果
1 // Reflection Shader 2 // Vertex Shader 3 // Richard S. Wright Jr. 4 // OpenGL SuperBible 5 #version 130 6 7 // Incoming per vertex... position and normal 8 in vec4 vVertex; 9 in vec3 vNormal; 10 11 uniform mat4 mvpMatrix; 12 uniform mat4 mvMatrix; 13 uniform mat3 normalMatrix; 14 uniform mat4 mInverseCamera; 15 16 // Texture coordinate to fragment program 17 smooth out vec3 vVaryingTexCoord; 18 19 void main(void) 20 { 21 // Normal in Eye Space 22 vec3 vEyeNormal = normalMatrix * vNormal; 23 24 // Vertex position in Eye Space 25 vec4 vVert4 = mvMatrix * vVertex; 26 vec3 vEyeVertex = normalize(vVert4.xyz / vVert4.w); 27 28 // Get reflected vector 29 vec4 vCoords = vec4(reflect(vEyeVertex, vEyeNormal), 1.0); 30 31 // Rotate by flipped camera 32 vCoords = mInverseCamera * vCoords; 33 vVaryingTexCoord.xyz = normalize(vCoords.xyz); 34 35 // Don't forget to transform the geometry! 36 gl_Position = mvpMatrix * vVertex; 37 }