O que você está perguntando é possível no OpenGL 3.2. Eu tenho meu FBO exibindo cores difusas em uma textura de cor, normais em outra textura de cor e profundidade em uma textura de profundidade - não são necessários amortecedores de renderização. De fato, os buffers de renderização são apenas um problema, porque você não pode obter amostras deles; portanto, você teria que usar glReadPixels(...)
ou copiar de alguma forma os dados da RBO para uma textura na CPU, em vez de apenas manter tudo na memória da GPU. Então...
Se você realmente quiser, pode escrever um código no seu sombreador de primeira passagem para enviar manualmente coisas como profundidade, para um anexo de textura de cor separado no seu FBO. Isso seria para você usar em seus shaders pós-passe. Para o uso do OpenGL em seus testes internos de profundidade, você precisaria adicionalmente de uma RBO ou textura definida como GL_DEPTH_ATTACHMENT do seu FBO. Mas você pode configurar uma única textura para servir a ambos - isso é mais eficiente e fácil de usar.
Meu código de configuração de textura de profundidade se parece com isso (Java, apenas ignore o material ByteBuffer ... e observe que eu uso "id" para me referir a identificadores / ponteiros inteiros, já que esse conceito realmente não se encaixa bem em 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);
E depois:
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, fbo.id);
//your existing glFramebufferTexture2D(...) calls here
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gBufferDepthTexture.id, 0);
Agora você pode passar gBufferDepthTexture
(ou o que você tem) como um uniforme para o seu segundo e terceiro pass shaders de fragmento. Acho que podemos assumir com segurança que você pode fazer exatamente a mesma coisa com o buffer de estêncil.