A little piece of code to reproduce the Levels control of Photoshop…
Input levels:
I already talked about the gamma correction (mid-tone slider), and I won’t explain what the shadows and highlights (black/white points) sliders are doing (excellent article here) but basically these can be used to remap the tonal range of the image. Here is how it’s calculated:
#define GammaCorrection(color, gamma) pow(color, vec3(1.0 / gamma))
#define LevelsControlInputRange(color, minInput, maxInput) min(max(color – vec3(minInput), vec3(0.0)) / (vec3(maxInput) – vec3(minInput)), vec3(1.0))
#define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)
Example with values from the 1st screenshot (blackpoint = 90/255, gamma = 4, whitepoint = 150/255), red: original color, green: blackpoint & whitepoint modified, blue: same with gamma:
Output levels:
This is useful to shorten the tonal range meaning compressing it to reduce contrast and shift it, details here.
#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(vec3(minOutput), vec3(maxOutput), color)
Example with values from the 1st screenshot (min output = 40/255, max output = 180/255), red: original color, green: output levels applied:
Putting it all together:
#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)
Same example but both input and output levels taken into account, red: original color, green: final result:
So these macros make it quite easy to increase or reduce contrast, shift and clip tonal range, lighten or darken shadows and highlights. I added the (GLSL / HLSL) code to the Photoshop Math shaders.