How to make Gamma Correction with multiple light pass rendering

Started by
2 comments, last by corysama 5 years, 10 months ago

I'm trying to implement PBR into my simple OpenGL renderer and trying to use multiple lighting passes, I'm using one pass per light for rendering as follow:

1- First pass = depth

2- Second pass = ambient

3- [3 .. n] for all the lights in the scene.

I'm using the blending function glBlendFunc(GL_ONE, GL_ONE) for passes [3..n], and i'm doing a Gamma Correction at the end of each fragment shader.

But i still have a problem with the output image it just looks noisy specially when i'm using texture maps.

Is there anything wrong with those steps or is there any improvement to this process?

Advertisement

I think you are confused, when to apply gamma correction. Usually it is done by:

  1. When rendering albedo, you perform Un-gamma operation so that you are rendering in linear color space
  2. When rendering the lights, you do nothing, which means you render them in linear color space.
  3. After your lighting is complete, perform post-process gamma resolve to come back to gamma color space again 
  4. Output to screen

So, sounds like what you are doing is:


reGamma(Ambient(deGamma(texture)) + reGamma(Light(deGamma(texture))

This doesn't work because reGamma is a non-linear operator.  So, you can't expect a linear operator like + to make sense with it's results.  Instead what you have to do is:


reGamma(Ambient(deGamma(texture) + Light(deGamma(texture))

That means removing the gamma operation from the end of your shader, accumulating linear values into your framebuffer, then switching back to gamma as a post past on the final value.

To make that work, you are going to need to switch to an fp16 format for your framebuffer because the whole point of the gamma curve is that rgb888 isn't enough bits to store linear colors without banding.

 

This topic is closed to new replies.

Advertisement