| #include "luminance.glsllib" |
| |
| vec3 RGBToYPbPr( in vec3 v ) |
| { |
| vec3 ypp; |
| ypp.x = luminance( v ); |
| ypp.y = 0.5 * (v.b - ypp.x) / (1.0 - yCoeff_709.b); |
| ypp.z = 0.5 * (v.r - ypp.x) / (1.0 - yCoeff_709.r); |
| |
| return ypp; |
| } |
| |
| vec3 YPbPrToRGB( in vec3 v ) |
| { |
| vec3 outRGB; |
| outRGB.x = dot(vec3(1.0, 0.0, 1.575), v); |
| outRGB.y = dot(vec3(1.0, -0.187, -0.468), v); |
| outRGB.z = dot(vec3(1.0, 1.856, 0.0), v); |
| |
| return outRGB; |
| } |
| |
| float remapLum( float inLum, float whitePt ) |
| { |
| return clamp( inLum / whitePt, 0.0, 1.0 ); |
| } |
| |
| float exposeLum( float inLum, float exposure ) |
| { |
| return 1.0 - exp2( -inLum / exposure ); |
| } |
| |
| vec3 gammaCorrect( vec3 inColor, float gammaExp ) |
| { |
| return pow( inColor, vec3( 1.0 / gammaExp ) ); |
| } |
| |
| vec3 adjSaturation( vec3 inRGB, float satFactor ) |
| { |
| // Must be done in linear space (before gamma correction) |
| float P = sqrt( luminance( inRGB * inRGB ) ); |
| vec3 outCol; |
| outCol = (inRGB - vec3(P)) * satFactor; |
| outCol += vec3(P); |
| return outCol; |
| } |
| |
| float curveCompute( float inLum, float slope0, float slope1 ) |
| { |
| float a1 = slope0; |
| float a2 = 3.0 - 2.0 * slope0 - slope1; |
| float a3 = slope1 + slope0 - 2.0; |
| |
| // Cubic curve fit. This results in a curve that is 0 where inColor is 0 |
| // equals 1 when inColor is 1, and the derivative at 0 is slope0 and the |
| // derivative at 1 is slope1 |
| return ((((a3 * inLum) + a2)*inLum) + a1)*inLum; |
| } |
| |
| float toeEmphasize( float inParam ) |
| { |
| float a1 = 1.0 - toeEmphasis; |
| float a2 = 2.0 * toeEmphasis; |
| float a3 = -toeEmphasis; |
| |
| return ((((a3 * inParam) + a2) * inParam) + a1) * inParam; |
| } |
| |
| float shoulderEmphasize( float inParam ) |
| { |
| float a1 = 1.0; |
| float a2 = shoulderEmphasis; |
| float a3 = -shoulderEmphasis; |
| |
| return ((((a3 * inParam) + a2) * inParam) + a1) * inParam; |
| } |
| |
| void frag() |
| { |
| // k = shadow slope, m = midtone slope, n = highlight slope |
| float k = toeSlope; |
| float m = 1.0 + contrastBoost; |
| float n = shoulderSlope; |
| |
| //vec4 sourceColor = texture(SourceSampler, TexCoord); |
| vec4 sourceColor = texture(Texture0, TexCoord); |
| vec3 sourceSep = RGBToYPbPr(sourceColor.rgb); |
| |
| float lum = sourceSep.r; |
| |
| if (useExposure) |
| lum = exposeLum( lum, exposureValue ); |
| else |
| lum = remapLum( lum, whitePoint ); |
| |
| float param0 = toeEmphasize( 2.0 * lum ); // Parametrization for Curve Part 1 |
| float param1 = shoulderEmphasize( 2.0 * lum - 1.0 ); // Parametrization for Curve Part 2 |
| |
| float lum0 = 0.5 * curveCompute( param0, k, m ); |
| float lum1 = 0.5 * curveCompute( param1, m, n ) + 0.5; |
| sourceSep.r = (lum > 0.5) ? lum1 : lum0; |
| |
| // Convert back to RGB and gamma correct |
| vec3 finalColor = YPbPrToRGB( sourceSep ); |
| finalColor = gammaCorrect( adjSaturation( finalColor, saturationLevel ), gammaValue ); |
| gl_FragColor = vec4( finalColor, sourceColor.a ); |
| } |