Questions on GLSL lighting

I’ve been spending the last few days trying to wrap my mind around GLSL lighting in OpenGL, but I still have a few questions.

So far, this is my understanding of the standard for lighting with deferred shading

  1. Render the scene to an FBO and keep the depth and color textures from the FBO
  2. Render the scene’s normal textures to another FBO
  3. Render each light (using full-screen passes) to another FBO passing the depth, color, and normal textures to the shader (as well as the inverse projection matrix for reconstructing position) using additive blending
  4. Render the color texture from the first FBO as well as the color texture from the FBO with the lights to the scene

If I’m thinking about this completely wrong or any of you know of a good tutorial or a better approach, I would appreciate your input :slight_smile:

You probably don’t want to get into deferred rendering for your first lighting code… Check out forward rendering.

I also strongly recommend you start out with forward shading if you haven’t already done that. It helps you get all the important things together and teaches you a lot of important things (shaders, lighting in general).

You’re a bit off on your idea of deferred rendering. You seem to be describing a variation of deferred lighting, while the most commonly used technique is deferred shading. To do deferred shading, you would do this:

  1. In a single pass, render all geometry to an FBO with multiple render targets, storing diffuse albedo, emissive color, normals, lighting parameters (roughness, specular intensity, specular power, stuff like that) and depth.
  2. Switch to a new FBO and accumulate lighting with additive blending into a texture. Lights are drawn as actual geometry (point lights are spheres, cone lights are cones, directional lights are fullscreen passes) to avoid processing unaffected pixels, or you can use more advanced techniques like tile-based deferred shading, where you determine which tiles on-screen are affected by which light using compute shaders. Lighting is (overly simplified):
    light = calculateDiffuseLighting(diffuseAlbedo, normal, lightDirection) + calculateSpecular(normal, lightDirection, lightingParameters).
  3. After lighting, you have the lit scene in the light buffer. Most likely you have HDR light values to avoid being limited to a (0 - 1) range of light values and need to tone map the values from (0 - infinity) to (0 - 1). You can also do postprocessing like bloom, SSAO, motion blur, etc at this point.

You’re describing an older technique which relied on multiple passes in an attempt to limit the bandwidth used. It was pretty inefficient, and is even more inefficient on today’s hardware.