High dynamic range (HDR)

Storing the actual energy received from the light. Usually color is mapped to a RGBA value where each component has a range of . HDR ranges are .

However, for our displays to accurately display our render, we do need to convert it back.

Reinhard operator

To go from HDR to sRGB space, the formula is

where is a vec3 that represents the color we want to convert. For example, for a given color value , we use the above formula on each of the values to get a rough sRGB color of .

vec3 reinhardOp(vec3 hdr) {
  return hdr / (vec3(1.f) + hdr);
}

Intuivitely, values with relatively low energy (close to 0) don’t undergo as much transformation as high energy values, which become “collapsed” down

Gamma correction

Applies an inverse curve to your monitor’s curve so that increasing light happens on a linear scale instead of a curved scale

  • Gamma factor of 2.2 is usually pretty good
  • Always apply HDR to SDR mapping first, and gamma correction second
const float gamma = 2.2f;
 
vec3 gammaCorrect(vec3 col) {
  return pow(col, vec3(1.f / gamma));
}

Also see

LearnOpenGL - Gamma Correction