简体   繁体   English

FBO中的延迟着色器纹理显示为黑色

[英]Deferred shader textures from FBO display as black

I am trying to use deferred shading to implement SSAO and I have problems to access my textures in the deferred fragment shader. 我试图使用延迟着色来实现SSAO,我在延迟片段着色器中访问我的纹理时遇到问题。 The code is in C++/Qt5 and makes use of Coin3D to generate the rest of the UI (but this shouldn't really matter here). 代码在C ++ / Qt5中,并使用Coin3D生成UI的其余部分(但这不应该在这里真正重要)。

The fragment shader of the deferred pass is: 延迟传递的片段着色器是:

#version 150 compatibility 

uniform sampler2D color;
uniform sampler2D position;
uniform sampler2D normal;

uniform vec3 dim;
uniform vec3 camPos;
uniform vec3 camDir;

void main()
{
    // screen position
    vec2 t = gl_TexCoord[0].st;

    // the color
    vec4 c = texture2D(color, t);

    gl_FragColor = c + vec4(1.0, t.x, t.y, 1.0);
}

The code for running the deferred pass is 运行延期传递的代码是

_geometryBuffer.Unbind();

// push state
{
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    glPushAttrib(GL_DEPTH_BUFFER_BIT | 
                 GL_COLOR_BUFFER_BIT |
                 GL_LIGHTING_BIT | 
                 GL_SCISSOR_BIT | 
                 GL_POLYGON_BIT |
                 GL_CURRENT_BIT);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_LIGHTING);
    glDisable(GL_COLOR_MATERIAL);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_CULL_FACE);
}

// bind shader
// /!\ IMPORTANT to do before specifying locations
_deferredShader->bind();

_CheckGLErrors("deferred");

// specify positions
_deferredShader->setUniformValue("camPos", ...);
_deferredShader->setUniformValue("camDir", ...);
_geometryBuffer.Bind(GBuffer::TEXTURE_TYPE_NORMAL, 2);
_deferredShader->setUniformValue("normal", GLint(2));
_geometryBuffer.Bind(GBuffer::TEXTURE_TYPE_POSITION, 1);
_deferredShader->setUniformValue("position",  GLint(1));
_geometryBuffer.Bind(GBuffer::TEXTURE_TYPE_DIFFUSE, 0);
_deferredShader->setUniformValue("color",  GLint(0));

_CheckGLErrors("bind");

// draw screen quad
{
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);
    glColor3f(0, 0, 0);
    glVertex2f(-1, -1);

    glTexCoord2f(1, 0);
    glColor3f(0, 0, 0);
    glVertex2f( 1, -1);

    glTexCoord2f(1, 1);
    glColor3f(0, 0, 0);
    glVertex2f( 1,  1);

    glTexCoord2f(0, 1);
    glColor3f(0, 0, 0);
    glVertex2f(-1,  1);
    glEnd();
}

_deferredShader->release();

// for debug
_geometryBuffer.Unbind(2);
_geometryBuffer.Unbind(1);
_geometryBuffer.Unbind(0);
_geometryBuffer.DeferredPassBegin();
_geometryBuffer.DeferredPassDebug();

// pop state
{
    glPopAttrib();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

I know that the textures have been correctly processed in the geometry buffer creation because I can dump them into files and get the expected result. 我知道在几何缓冲区创建中已经正确处理了纹理,因为我可以将它们转储到文件中并获得预期的结果。

The deferred pass doesn't work. 延期通行证不起作用。 The shader compiled correctly and I get the following result on screen: 着色器编译正确,我在屏幕上得到以下结果:

结果不好

And the last part of my code (DeferredPassBegin/Debug) is to draw the FBO to the screen (as shown in screenshot) as a proof that the GBuffer is correct. 我的代码的最后一部分(DeferredPassBegin / Debug)是将FBO绘制到屏幕上(如屏幕截图所示),作为GBuffer正确的证明。

The current result seems to mean that the textures are not correctly bound to their respective uniform, but I know that the content is valid as I dumped the textures to files and got the same results as shown above. 当前的结果似乎意味着纹理没有正确绑定到它们各自的统一,但我知道内容是有效的,因为我将纹理转储到文件并得到与上面显示的相同的结果。

My binding functions in GBuffer are: 我在GBuffer中的绑定功能是:

void GBuffer::Unbind()
{
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}

void GBuffer::Bind(TextureType type, uint32_t idx)
{
    glActiveTexture(GL_TEXTURE0 + idx);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, _textures[static_cast<uint32_t>(type)]);
}

void GBuffer::Unbind(uint32_t idx)
{
    glActiveTexture(GL_TEXTURE0 + idx);
    glDisable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);
}

Finally, the textures are 512/512, and I created them in my GBuffer with: 最后,纹理是512/512,我在我的GBuffer中创建它们:

WindowWidth = WindowHeight = 512;
// Create the FBO
glGenFramebuffers(1, &_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);

const uint32_t NUM = static_cast<uint32_t>(NUM_TEXTURES);

// Create the gbuffer textures
glGenTextures(NUM, _textures);
glGenTextures(1, &_depthTexture);

for (unsigned int i = 0 ; i < NUM; i++) {
   glBindTexture(GL_TEXTURE_2D, _textures[i]);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WindowWidth, WindowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i + _firstIndex, GL_TEXTURE_2D, _textures[i], 0);
}

// depth
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _depthTexture, 0);

GLenum buffers[NUM];
for(uint32_t i = 0; i < NUM; ++i){
    buffers[i] = GLenum(GL_COLOR_ATTACHMENT0 + i + _firstIndex);
}
glDrawBuffers(NUM, buffers);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
    printf("FB error, status: 0x%x\n", status);
    return _valid = false;
}

// unbind textures
glBindTexture(GL_TEXTURE_2D, 0);

// restore default FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);

How can I debug farther at this stage? 我怎样才能在这个阶段进行更远的调试? I know that the texture data is valid, but I can't seem to bind it to the shader correctly (but I have other shaders that use textures loaded from files and which work fine). 我知道纹理数据是有效的,但我似乎无法正确地将它绑定到着色器(但我有其他着色器使用从文件加载的纹理,并且工作正常)。

--- Edit 1 --- --- 编辑1 ---

As asked, the code for DeferredPassBegin/Debug (mostly coming from this tutorial ) 如上所述,DeferredPassBegin / Debug的代码(主要来自本教程

void GBuffer::DeferredPassBegin() {
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo); 
}

void GBuffer::DeferredPassDebug() {
    GLsizei HalfWidth = GLsizei(_texWidth / 2.0f);
    GLsizei HalfHeight = GLsizei(_texHeight / 2.0f);

    SetReadBuffer(TEXTURE_TYPE_POSITION);
    glBlitFramebuffer(0, 0, _texWidth, _texHeight,
                    0, 0, HalfWidth, HalfHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);

    SetReadBuffer(TEXTURE_TYPE_DIFFUSE);
    glBlitFramebuffer(0, 0, _texWidth, _texHeight,
                    0, HalfHeight, HalfWidth, _texHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);

    SetReadBuffer(TEXTURE_TYPE_NORMAL);
    glBlitFramebuffer(0, 0, _texWidth, _texHeight,
                    HalfWidth, HalfHeight, _texWidth, _texHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); 
 }

Arghk!!! Arghk!

So I expected that texture parameters were not mandatory, but as I looked at some code, I just tried to specify my texture parameters. 所以我期望纹理参数不是强制性的,但是当我查看一些代码时,我只是尝试指定我的纹理参数。 When generating the FBO textures, I use now 生成FBO纹理时,我现在使用

for (unsigned int i = 0 ; i < NUM; i++) {
    glBindTexture(GL_TEXTURE_2D, _textures[i]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WindowWidth, WindowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i + _firstIndex, GL_TEXTURE_2D, _textures[i], 0);
}

And with this change, I get the expected result (with only c in the fragment shader, and similar correct results if I switch to visualizing the normal / position). 通过这个改变,我得到了预期的结果(在片段着色器中只有c ,如果切换到可视化正常/位置,则类似的正确结果)。

Conclusion : one must specify the texture parameters for deferred shading to work (at least with the graphics setup of my application / machine). 结论 :必须指定延迟着色的纹理参数才能工作(至少使用我的应用程序/机器的图形设置)。

正确的兔子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM