渲染到立方体贴图 [英] Rendering to cube map

查看:152
本文介绍了渲染到立方体贴图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

According to ARB_geometry_shader4 it is possible to render a scene onto the 6 faces of a cube map with a geometry shader and the cube map attached to a framebuffer object. I want to create a shadow map using this way. However there seems to be a conflict that I can't resolve:

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

因此,当我想渲染到立方体贴图时,似乎无法使用任何深度测试.还是我在这里到底想念什么?

So it looks like I can't use any depth testing when I want to render to a cube map. Or what exactly am I missing here?

编辑:看起来较新的Nvidia驱动程序(180.48)支持深度立方体贴图.

It looks like newer Nvidia drivers (180.48) support depth cube maps.

推荐答案

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

Ok, to answer some other questions here:

当然可以使用6个FBO,每个面孔一个.或者使用一个FBO并在画上每个面之前对其进行附加.在这两种情况下,立方体贴图面都将像其他任何2D纹理一样对待,您可以将其与常规2D纹理或Renderbuffers一起使用.而且,在所有可能的方式上(如果硬件支持它们的话)可能并没有太大的区别.

Of course it is possible to use 6 FBOs, one for each face. Or to use one FBO and attach each face before you draw to it. In both cases the cube map face will be treated like any other 2D texture and you can use it together with normal 2D textures or Renderbuffers. And there's probably not much of a difference in all the possible ways (if the hardware supports them).

但是,也可以一步一步绘制所有内容,并且由于我很好奇这是如何完成的,所以我做了一些研究.

However, it's also possible to draw everything in one step and as I was curious as to how this is done I did some research.

要创建一个FBO,并将多维数据集映射的所有面都附加到一个附加点,我使用了以下代码(用D编写):

To create a FBO with all faces of a cube map attached to a single attachment point I used this code (written in 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)
  • 所有纹理的宽度和高度必须相同
    • If you want to have only a depth map you have to change glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); to glDrawBuffer(GL_NONE); before validating it (and before drawing to it)
    • MIN and MAG filters must be set to something valid (default would be GL_NEAREST_MIPMAP_LINEAR)
    • width and height of all textures must be the same
    • 要渲染到立方体贴图的表面,您需要一个几何着色器.下面的着色器缺少一些旋转,但是应该清楚其作用. gl_Layer用于将图元定向到正确的面孔(0 = + X,1 = -X,...).

      To render to the faces of a cube map you need a geometry shader. The following shader misses some rotations but it should be clear what it does. gl_Layer is used to direct the primitive to the correct face (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();
          }
      }
      

      这篇关于渲染到立方体贴图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆