您要问的是在OpenGL 3.2中是可能的。我的FBO将漫反射颜色分散为一种颜色纹理,法线为另一种颜色纹理,以及深度为深度纹理-不需要渲染缓冲区。实际上,渲染缓冲区只是一个问题,因为您无法从中进行采样,因此必须使用glReadPixels(...)
或以其他方式将数据从RBO中复制出来并复制到CPU的纹理中,而不是仅将所有内容保留在GPU内存中。所以...
如果确实需要,可以在首遍着色器中编写代码,以将诸如深度之类的内容手动输出到FBO中的单独颜色纹理附件。那将供您在通过后着色器中使用。对于OpenGL 在其内部深度测试中的使用,您还需要一个RBO或纹理集作为FBO的GL_DEPTH_ATTACHMENT。但是您可以设置单个纹理来同时使用这两种纹理-这更高效且更易于使用。
我的深度纹理设置代码如下(Java,请忽略ByteBuffer之类的东西,并请注意,我使用“ id”指代整数句柄/指针,因为该概念在Java中并不适合):
gBufferDepthTexture = new Texture();
gBufferDepthTexture.id = glGenTextures();
gBufferDepthTexture.unit = 2;
gBufferDepthTexture.width = Display.getWidth();
gBufferDepthTexture.height = Display.getHeight();
gBufferDepthTexture.bytes = ByteBuffer.allocateDirect(Display.getWidth()*Display.getHeight() * 4);
glActiveTexture(gBufferDepthTexture.unit + GL_TEXTURE0); //eg. 0 + 33984 = GL_TEXTURE0, while 31 + 33984 = GL_TEXTURE31.
glBindTexture(GL_TEXTURE_2D, gBufferDepthTexture.id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gBufferDepthTexture.width, gBufferDepthTexture.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, gBufferDepthTexture.bytes);
//...GL_UNSIGNED_INT or GL_UNSIGNED_BYTE may work better for you, instead... YMMV.
//glPixelStorei(GL_PACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
然后:
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, fbo.id);
//your existing glFramebufferTexture2D(...) calls here
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gBufferDepthTexture.id, 0);
现在,您可以将gBufferDepthTexture
制服作为制服传递(或拥有)到第二,第三遍片段着色器。我认为我们可以放心地假设您可以使用模板缓冲区执行完全相同的操作。