blob: 66c0a892cb344d118365e2e41f5bcd2c31670422 [file] [log] [blame]
#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 );
}