2009-01-20 90 views
11

根据ARB_geometry_shader4,可以在具有几何着色器的立方体贴图的6个面上渲染场景,并将该立方体贴图附加到帧缓冲区对象。我想用这种方式创建一个阴影贴图。然而,有似乎是我无法解决冲突:渲染到立方体贴图

  1. 我只能GL_DEPTH_COMPONENT附加纹理内部类型的GL_DEPTH_ATTACHMENT_EXT。
  2. 深度纹理只能是1D或2D。
  3. 如果我想附加立方体贴图,所有其他附加纹理也必须是立方体贴图。

所以它看起来像我不能使用任何深度测试时,我想渲染到立方体贴图。或者我在这里错过了什么?

编辑:它看起来像新的Nvidia司机(180.48)支持深度立方体地图。

+0

我不确定渲染立方体贴图与几何着色器有什么关系,但感觉完全独立,但我没有答案。 – falstro 2009-01-21 10:57:12

+1

几何着色器可以为每个输入三角形创建6个输出三角形,并将其重定向到每个立方体贴图面(请参阅“分层渲染”)。如果没有着色器,我必须附加每个面并渲染几何图形。 – 2009-01-22 21:35:48

回答

12

好了,在这里回答一些其他问题:

当然是可以使用6个宗教组织,每一个面孔。或者在绘制之前使用一个FBO并附上每张脸。在这两种情况下,立方体贴图面都将像其他任何2D贴图一样对待,并且可以将其与普通的2D贴图或渲染缓冲区一起使用。在所有可能的方式中(如果硬件支持它们),可能没有多大区别。

但是,也可以在一个步骤中绘制所有内容,因为我很好奇这是如何完成的,所以我做了一些研究。

要创建连接到我用这个代码将一个连接点的立方体地图的所有面的FBO(写在d):

// depth cube map 
glGenTextures(1, &tDepthCubeMap); 
glBindTexture(GL_TEXTURE_CUBE_MAP, tDepthCubeMap); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 
for (uint face = 0; face < 6; face++) { 
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT24, 
     width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null); 
} 

// color cube map 
glGenTextures(1, &tColorCubeMap); 
glBindTexture(GL_TEXTURE_CUBE_MAP, tColorCubeMap); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 
for (uint face = 0; face < 6; face++) { 
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 
     width, height, 0, GL_RGBA, GL_FLOAT, null); 
} 

// framebuffer object 
glGenFramebuffersEXT(1, &fbo); 
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); 
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, tDepthCubeMap, 0); 
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, tColorCubeMap, 0); 

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 

if (!isValidFBO()) { 
    glDeleteFramebuffersEXT(1, &fbo); 
    fbo = 0; 
} 
  • 如果你想只有一个深度图你必须改变glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);glDrawBuffer(GL_NONE);前验证它
  • MIN和MAG过滤器必须设置的东西有效(默认是GL_NEAREST_MIPMAP_LINEAR)
  • 宽度和所有纹理的高度必须相同

(并绘制之前)渲染到立方体贴图的表面,您需要几何着色器。以下着色器错过了一些旋转,但它应该清楚它的作用。 gl_Layer用于将原语指向正确的人脸(0 = + X,1 = -X,...)。

#version 120 
#extension GL_EXT_geometry_shader4 : enable 

void main(void) { 
    int i, layer; 
    for (layer = 0; layer < 6; layer++) { 
     gl_Layer = layer; 
     for (i = 0; i < 3; i++) { 
      gl_Position = gl_PositionIn[i]; 
      EmitVertex(); 
     } 
     EndPrimitive(); 
    } 
}