Based on this 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:
Code :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
Code :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:
Code :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)
Code :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...
Code :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
AMD
Models disappears or blend into each other depending on camera angle
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.



Reply With Quote
