PDA

View Full Version : Deferred renderer issue on AMD only



fredvam
09-24-2013, 03:13 PM
Based on this (http://ogldev.atspace.co.uk/www/tutorial37/tutorial37.html) tutorial,
I had allot of problems getting AMD based GPU's to work.

I will post snippets of code bellow to detail the issue, but a simplistic explanation of the issue is that there is an issue with the depth test. I can see background objects tear infront of closer objects etc.

I contacted the original author regarding the issue, he does not seem to have access to AMD hardware so the question is open to be resolved, and I hope someone here have had similar issues.

The tutorial are covered in 3 stages, basic deferred shading to the final example using stencil buffer to draw a sphere (for point lights) to make GLSL only process the light volume.

Code can be downloaded from the tutorial, but to make it convenient I will post the important areas (and order of execution) here.

Edit:
There are a few additions in the code samples bellow, as compared to the original tutorial, but the same issues are confirmed on AMD gpu's in its original state by multiple systems (6k/7k series).

Static types:


enum GBUFFER_TEXTURE_TYPE {
GBUFFER_TEXTURE_TYPE_POSITION,
GBUFFER_TEXTURE_TYPE_NORMAL,
GBUFFER_TEXTURE_TYPE_TANGENT,
GBUFFER_TEXTURE_TYPE_DIFFUSE_COLOR,
GBUFFER_TEXTURE_TYPE_NORMAL_COLOR,
GBUFFER_TEXTURE_TYPE_SPECULAR_COLOR,
GBUFFER_NUM_TEXTURES


m_shaderLight.setUniform("PositionTex", GBUFFER_TEXTURE_TYPE_POSITION);
m_shaderLight.setUniform("NormalTex", GBUFFER_TEXTURE_TYPE_NORMAL);
m_shaderLight.setUniform("TangentTex", GBUFFER_TEXTURE_TYPE_TANGENT);
m_shaderLight.setUniform("ColorDiffuseTex", GBUFFER_TEXTURE_TYPE_DIFFUSE_COLOR);
m_shaderLight.setUniform("ColorNormalTex", GBUFFER_TEXTURE_TYPE_NORMAL_COLOR);
m_shaderLight.setUniform("ColorSpecularTex", GBUFFER_TEXTURE_TYPE_SPECULAR_COLOR);


};


InitFBO


if (m_fbo != 0) {
glDeleteFramebuffers(1, &m_fbo);
}

if (m_depthTexture != 0) {
glDeleteTextures(1, &m_depthTexture);
}
if (m_finalTexture != 0) {
glDeleteTextures(1, &m_finalTexture);
}

for (size_t i = 0; i < ArraySize(m_textures); i++) {
if (m_textures[i] != 0) {
glDeleteTextures(1, &m_textures[i]);
}
}

// Create the FBO
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);

// Create the gbuffer textures
glGenTextures(ArraySize(m_textures), m_textures);

glGenTextures(1, &m_depthTexture);

glGenTextures(1, &m_finalTexture);

for (unsigned int i = 0 ; i < ArraySize(m_textures) ; i++) {
glBindTexture(GL_TEXTURE_2D, m_textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_windowWidth, m_windowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
}

// depth
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, m_windowWidth, m_windowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

// final
glBindTexture(GL_TEXTURE_2D, m_finalTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_windowWidth, m_windowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT6, GL_TEXTURE_2D, m_finalTexture, 0);

GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

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


Pass Geometry:


glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT6);
glClear(GL_COLOR_BUFFER_BIT);


glViewport(0, 0, m_windowWidth, m_windowHeight);

static GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3,
GL_COLOR_ATTACHMENT4,
GL_COLOR_ATTACHMENT5};

glDrawBuffers(ArraySize(DrawBuffers), DrawBuffers);

// Only the geometry pass updates the depth buffer
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

draw geometry here...

glDepthMask(GL_FALSE);

Pass Light: (Will only demonstrate directional light, stencil done in point light)



glDrawBuffer(GL_COLOR_ATTACHMENT6);

for (unsigned int i = 0 ; i < ArraySize(m_textures); i++) {
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_POSITION + i]);
}

glUniformSubroutinesuiv( GL_FRAGMENT_SHADER, 1, &GLSLSubFSLightDirectional);

glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);

m_shaderLight.setUniform(UniformLightMVP, mat4(1));
// Render the quad
glBindVertexArray(m_quad);
glDrawArrays(GL_TRIANGLES, 0, 6);

glDisable(GL_BLEND);


Then finally...


glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_effectFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
glReadBuffer(GL_COLOR_ATTACHMENT6);

glBlitFramebuffer(0, 0, m_windowWidth, m_windowHeight,
0, 0, m_windowWidth, m_windowHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);


Results:

Nvidia good

1153

AMD

Models disappears or blend into each other depending on camera angle

1152

Any feedback is greatly appreciated, if we find an answer I will credit whomever and let the author update the article so everyone can benefit from it.

Thanks.

Jerran
09-25-2013, 10:00 PM
I have a few AMD cards but not on a Linux system unfortunately. Have you tried rendering the depth buffer to the screen to see if it is valid and correct?

cireneikual
09-29-2013, 09:36 AM
Try GL_DEPTH24_STENCIL8 instead of GL_DEPTH32F_STENCIL8.

fredvam
09-30-2013, 10:11 AM
Try GL_DEPTH24_STENCIL8 instead of GL_DEPTH32F_STENCIL8.

No change :(

fredvam
09-30-2013, 10:12 AM
I have a few AMD cards but not on a Linux system unfortunately. Have you tried rendering the depth buffer to the screen to see if it is valid and correct?

Good point, added some debug overlay (from gbuffer), cant see it in the depth, normal, tangent textures either. So it happens in the geometry pass. Narrows it down a bit.

fredvam
10-13-2013, 06:02 PM
I solved this issue, not sure how to edit the original title (seems to be locked for edit after some period)

Will incorporate the fix in original tutorial, if the fix is working well for everyone. Will need some time to determine the exact issue as I had to rewrite how I set up the color attachments to the FBO, partially based on "OpenGL 4.0 Shading Language" book.