2
votes

In summary, my full screen shader is not outputting anything,

I am writing a deferred shader in GLSL and I have gotten to the stage where I am applying lights in screen space. I have an ambient pass where I basically write the diffuse intensity from the GBuffer to the default FBO, this works fine. I then apply another full screen quad to calculate the directional light in the scene, again this samples from the GBUffer and should be blended with the default FBO.

The problem I am having is that the directional light shader does not output anything. I use the same matrices and transformations as I do with the ambient pass but nothing changes.

I have tried the following;

  1. Output the same colour at every fragment in the ambient pass to ensure it is outputting at all. (Works)
  2. Output the same colour at every fragment in the directional light pass. (Still get nothing)
  3. Use the screen resolution for XY vertex coordinates as opposed to normalised coordinates;
    • This works for the ambient pass as I can see the results changing as expected.
    • It changes nothing for the directional light pass and I get the same output.
  4. Change the ambient shader to sample from the normal or position buffers to ensure the textures can be sampled from (Working)

Here's the application code;

glBindFramebuffer(GL_READ_FRAMEBUFFER, m_GeometryBuffer->m_Name);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffers(1,draw_buffers);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

m_AmbientShader->Begin();
    m_AmbientShader->SetUniformInt1("Diffuse",m_DiffuseTexture->m_TextureUnit);
    // Draw full screen quad
    glBegin(GL_QUADS);
        glMultiTexCoord2i(GL_TEXTURE0,0,0);
        glVertex2i(-1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,0);
        glVertex2i(1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,1);
        glVertex2i(1,1);
        glMultiTexCoord2i(GL_TEXTURE0,0,1);
        glVertex2i(-1,1);
    glEnd();
m_AmbientShader->End();

const DirectionalLight& dl = scene.GetDirectionalLight();

glDrawBuffers(1, draw_buffers);
m_DirectionalLightShader->Begin();
m_DirectionalLightShader->SetUniformInt1("Diffuse",m_DiffuseTexture->m_TextureUnit);
m_DirectionalLightShader->SetUniformInt1("Position",m_PositionTexture->m_TextureUnit);
m_DirectionalLightShader->SetUniformInt1("Normal",m_NormalTexture->m_TextureUnit);
m_DirectionalLightShader->SetUniformFloat3("LightDir",dl.GetDirection());
m_DirectionalLightShader->SetUniformFloat3("LightAmb",dl.GetAmb());
m_DirectionalLightShader->SetUniformFloat3("LightDiff",dl.GetDiff());
m_DirectionalLightShader->SetUniformFloat3("LightSpec",dl.GetSpec());
m_DirectionalLightShader->SetUniformFloat3("LightAtt",dl.GetAtt());
m_DirectionalLightShader->SetUniformFloat1("LightIntensity",dl.GetIntensity());
    // Draw full screen quad
    glBegin(GL_QUADS);
        glMultiTexCoord2i(GL_TEXTURE0,0,0);
        glVertex2i(-1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,0);
        glVertex2i(1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,1);
        glVertex2i(1,1);
        glMultiTexCoord2i(GL_TEXTURE0,0,1);
        glVertex2i(-1,1);
    glEnd();
m_DirectionalLightShader->End();

Please excuse me if my math is wrong, I have been messing around with the shaders to try and get any sort of output but here are the shader source files;

<-- directional_light.vert -->

varying out vec2 ScreenPos;

varying out vec3 VSLightDir;

uniform vec3 LightDir;
uniform vec3 LightAmb;
uniform vec3 LightDiff;
uniform vec3 LightSpec;
uniform float LightIntensity;

void main()
{
    gl_Position = gl_Vertex;
    ScreenPos = gl_MultiTexCoord0.st;
    VSLightDir = normalize((gl_ModelViewMatrix * vec4(LightDir,0.0)).xyz);
}

<-- directional_light.frag -->

// Gbuffer textures
uniform sampler2D Diffuse;
uniform sampler2D Position;
uniform sampler2D Normal;

in vec2 ScreenPos;
uniform vec3 LightDir;
uniform vec3 LightAmb;
uniform vec3 LightDiff;
uniform vec3 LightSpec;
uniform float LightIntensity;

in vec3 VSLightDir;
out vec4 OutColour;

void main()
{
    // Sample from the GBuffer
    vec4 Diffuse = texture2D(Diffuse, ScreenPos);
    vec4 VSPos = texture2D(Position, ScreenPos);
    vec4 MRT2 = texture2D(Normal, ScreenPos);
    vec3 VSNormal = normalize(MRT2.xyz);
    float Shininess = MRT2.w;

    float LDotN = dot(VSNormal, VSLightDir);

    vec3 View = -normalize(VSPos.xyz);

    // Compute ambient contribution
    vec3 ambient = LightIntensity * LightAmb * Diffuse.xyz;

    // Compute diffuse contribution
    vec3 diffuse = LightIntensity * LightDiff * Diffuse.xyz * max(0.0, LDotN);

    // Compute specular contribution
    vec3 HalfWay = normalize(LightDir + View);
    vec3 specular = (LDotN <= 0.0)
                ? vec3(0.0)
                : LightIntensity * LightSpec * Diffuse.xyz * pow(max(0.0, dot(VSNormal,HalfWay)), Shininess);

    OutColour = vec4(ambient + diffuse + specular, Diffuse.a);
    //OutColour = vec4(0.0,0.0,1.0,1.0); //Debug line
}

<-- ambient.vert -->

varying out vec2 ScreenPos;

void main()
{
    gl_Position = gl_Vertex;

    // Used for the position to sample from GBuffer
    ScreenPos = gl_MultiTexCoord0.st;
}

<-- ambient.frag -->

// Gbuffer textures
uniform sampler2D Diffuse;

in vec2 ScreenPos;

out vec4 OutColour;

void main()
{
    OutColour = texture2D(Diffuse, ScreenPos);
    //OutColour = vec4(0.0,0.0,1.0,1.0);
}
1

1 Answers

3
votes

Do you have depth test enabled? I see you're clearing the depth buffer so I suspect maybe, but you're drawing the second texture at the exact same depth as the first. With the glDepthFunc default of GL_LESS that would cause the second draw to get totally rejected.

Or otherwise how do you want the two draws to be combined? Should there be some blending involved?