Deferred Point Light Frustration

Hello, I want to render point lights inside a scene but using view-space which has hit a snag. I believe this is either to do with the coordinate space or pipeline switches; knowing my luck it is probably both. I still cannot figure it out after many hours mostly trial and error :rolleyes:.

Foremost, everything in the shader should be in view-space as the primary working space since both the compressed normals and positions (based on depth) are too.

Here you can see the issue(s) in a GIF: OpenGL Coding Error
[i]

[ol]
[li]Spheres rendering in a chequered pattern? not a main concern yet [/li][li]Spheres change with the camera (because view-space) but they render through the main scene geometry as well. [/li][/ol]
[/i]

C++ Snippet:

// Force the lights to function in view-space before sending.
for (auto& light : convertLights)
{
    light.position = static_cast<glm::mat4x3>(view) * glm::vec4 (light.position, 1);
    light.direction = static_cast<glm::mat3>(view) * light.direction;
}

// Further down the code...
// Pipeline switches
    glEnable (GL_BLEND);
    glBlendEquation (GL_FUNC_ADD);
    glBlendFunc (GL_ONE, GL_ONE);

    glEnable (GL_CULL_FACE);
    glCullFace (GL_FRONT);

    glEnable (GL_DEPTH_TEST);
    glDepthMask (GL_FALSE);        // Disable writing too the depth buffer.
    glDepthFunc (GL_GREATER);    // Check in-front of the back fragments.

    glEnable (GL_STENCIL_TEST);
    glStencilFunc (GL_NOTEQUAL, 255, ~0);
    glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);

// These are reset after draw has been called!

Vertex Shader Snippet:

void main (void)
{
    // +5 to skip other lights since this is point light stuff.
    v_instanceID = 5 + gl_InstanceID; // Point lights have been instanced.
    Light light = lights[v_instanceID]; // All lights are stored in a UBO.

    vec3 transLight = a_position * light.range + light.position;
    gl_Position = projection * vec4 (transLight, 1.f);
}

Fragment Shader Snippet:

    vec3 L = normalize (lights[v_instanceID].position - decodedPosition);
    float LdotN = max (0, dot (L, decodeNormal));

Unfortunately it has been a while since I have worked with OpenGL and specifically on this project. Please forgive my ignorance, I know it will be something obvious which is why I’m asking for assistance.

By “view space”, are you referring to eye space or screen space (i.e. something affine to clip space or NDC)?

Screen space isn’t affine to world space, so many of the properties which are normally used for lighting calculations don’t apply. E.g. vectors which are parallel or perpendicular in screen space typically aren’t parallel or perpendicular in world space.

Deferred lighting stores normals in eye space, while positions are explicitly transformed from NDC to eye-space. Dot products and distance measurements are performed in eye space.

[QUOTE=GClements;1282362]By “view space”, are you referring to eye space or screen space (i.e. something affine to clip space or NDC)?

Screen space isn’t affine to world space, so many of the properties which are normally used for lighting calculations don’t apply. E.g. vectors which are parallel or perpendicular in screen space typically aren’t parallel or perpendicular in world space.

Deferred lighting stores normals in eye space, while positions are explicitly transformed from NDC to eye-space. Dot products and distance measurements are performed in eye space.[/QUOTE]

Ah, I see. Yes I’m referring to Eye-Space, sorry for the confusion.

Before this thread becomes dead, I did manage to solve both issues.

Firstly the triangle chequered spheres were nothing more than stupidity within the C++ code which resulted in broken element offsets. The last issue was the result of the decoded positions (from depth) not being computed correctly :doh:.