Gamma correction in openGL is very easily to achieve, but why do you need gamma correction? Let’s keep it simple… First of all your textures you use as input for your openGL renderer are most likely in non linear color space. Your renderer on the other hand is probably calculating light under the assumption of linear color spaced color values in your loaded textures. So you might be working in two different color spaces. After your renderer is done it writes the colors to the screen, which uses non linear color space like your textures do! So what happens is, that your calculation might be visually wrong…

So how can you solve this?

The answer is very easy:

First switch your input textures to sRGB:

//this texture will stay uncorrected if it is non linear
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
 
//this one will be corrected on texture lookups
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);

 

Second switch your final color output to sRGB:

//if you use GLFW
glfwWindowHint(GLFW_SRGB_CAPABLE, TRUE);
//...
glEnable(GL_FRAMEBUFFER_SRGB);
 
 
//if you go full hardcore
//use glRenderbufferStorage() with GL_SRGB instead of GL_RGB
//for your final renderbuffer that uses the final non-sampleable framebuffer
//and dont forget
glEnable(GL_FRAMEBUFFER_SRGB);

 

Thats all you need. If you want more information about gamma correction check this link: GPU Gems 3 Chapter 24

 

 

 

And here’s a screenshot of gamma correction in action (with post processing noise, fxaa and sharpen filter):

gamma_corrected_final

 

This is the skybox side’s input texture:

cubemap_side_input


Leave a Reply

Your email address will not be published. Required fields are marked *