I am running a shader that outputs position and normal data to two different textures (using code very similar to this: https://learnopengl.com/Advanced-Lighting/Deferred-Shading). This works fine on a Nvidia GPU, but on a AMD Radeon RX Vega 6 the position and normal textures are mixed up. I use glBindFragDataLocation to set the order.
Anyone know what I could be doing wrong?
This is the code I use:
// create gBuffer
glGenFramebuffers(1, &m_fboGBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_fboGBuffer);
// position color buffer
glGenTextures(1, &m_idPosition);
glBindTexture(GL_TEXTURE_2D, m_idPosition);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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, GL_TEXTURE_2D, m_idPosition, 0);
// normal color buffer
glGenTextures(1, &m_idNormal);
glBindTexture(GL_TEXTURE_2D, m_idNormal);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_idNormal, 0);
// tell OpenGL which color attachments we'll use (of this framebuffer) for rendering
unsigned int attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, attachments);
// create and attach depth buffer (renderbuffer)
glGenRenderbuffers(1, &m_fboDepth);
glBindRenderbuffer(GL_RENDERBUFFER, m_fboDepth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_fboDepth);
int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
throw RacException("GBuffer not created");
}
Shader* pShader = g_shaderManager.GetShader(shaderGBuffer);
pShader->Activate();
glBindFragDataLocation(pShader->GetID(), 0, "gPosition");
glBindFragDataLocation(pShader->GetID(), 1, "gNormal");
m_ixMatrixM = pShader->AddUniform("matrixM");
// vertex shader
uniform highp mat4 matrixPVM;
uniform highp mat3 matrixVM;
uniform highp mat4 matrixM;
in highp vec3 inVertex;
in lowp vec3 inNorm;
out vec3 outVertex;
out vec3 outNormal;
void main(void)
{
outNormal = normalize(mat3(matrixM) * inNorm);
vec4 viewPos = matrixM * vec4(inVertex, 1.0);
outVertex = viewPos.xyz;
gl_Position = matrixPVM * vec4(inVertex, 1.0);
}
// fragment shader
out vec3 gPosition;
out vec3 gNormal;
in highp vec3 outVertex;
in vec3 outNormal;
void main (void)
{
// store the fragment position vector in the first gbuffer texture
gPosition = outVertex;
// also store the per-fragment normals into the gbuffer
gNormal = normalize(outNormal);
}