diff --git a/shader/ToneMap/AMD.glsl b/shader/ToneMap/AMD.glsl new file mode 100644 index 0000000..987eb84 --- /dev/null +++ b/shader/ToneMap/AMD.glsl @@ -0,0 +1,62 @@ +//-------------------------------------------------------------------------------------- +// AMD Tonemapper +//-------------------------------------------------------------------------------------- +// General tonemapping operator, build 'b' term. +float ColToneB(float hdrMax, float contrast, float shoulder, float midIn, float midOut) +{ + return + -((-pow(midIn, contrast) + (midOut*(pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) - + pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut)) / + (pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut)) / + (pow(midIn, contrast*shoulder)*midOut)); +} + +// General tonemapping operator, build 'c' term. +float ColToneC(float hdrMax, float contrast, float shoulder, float midIn, float midOut) +{ + return (pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) - pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut) / + (pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut); +} + +// General tonemapping operator, p := {contrast,shoulder,b,c}. +float ColTone(float x, vec4 p) +{ + float z = pow(x, p.r); + return z / (pow(z, p.g)*p.b + p.a); +} + +vec3 ToneMapping(vec3 color) +{ + const float hdrMax = 16.0; // How much HDR range before clipping. HDR modes likely need this pushed up to say 25.0. + const float contrast = 2.0; // Use as a baseline to tune the amount of contrast the tonemapper has. + const float shoulder = 1.0; // Likely don�t need to mess with this factor, unless matching existing tonemapper is not working well.. + const float midIn = 0.18; // most games will have a {0.0 to 1.0} range for LDR so midIn should be 0.18. + const float midOut = 0.18; // Use for LDR. For HDR10 10:10:10:2 use maybe 0.18/25.0 to start. For scRGB, I forget what a good starting point is, need to re-calculate. + + float b = ColToneB(hdrMax, contrast, shoulder, midIn, midOut); + float c = ColToneC(hdrMax, contrast, shoulder, midIn, midOut); + + #define EPS 1e-6f + float peak = max(color.r, max(color.g, color.b)); + peak = max(EPS, peak); + + vec3 ratio = color / peak; + peak = ColTone(peak, vec4(contrast, shoulder, b, c) ); + // then process ratio + + // probably want send these pre-computed (so send over saturation/crossSaturation as a constant) + float crosstalk = 4.0; // controls amount of channel crosstalk + float saturation = contrast; // full tonal range saturation control + float crossSaturation = contrast*16.0; // crosstalk saturation + + float white = 1.0; + + // wrap crosstalk in transform + ratio = pow(abs(ratio), vec3(saturation / crossSaturation)); + ratio = mix(ratio, vec3(white), vec3(pow(peak, crosstalk))); + ratio = pow(abs(ratio), vec3(crossSaturation)); + + // then apply ratio to peak + color = peak * ratio; + return color; +} diff --git a/shader/ToneMap/DX11.glsl b/shader/ToneMap/DX11.glsl new file mode 100644 index 0000000..4079305 --- /dev/null +++ b/shader/ToneMap/DX11.glsl @@ -0,0 +1,15 @@ +//-------------------------------------------------------------------------------------- +// The tone mapper used in HDRToneMappingCS11 +//-------------------------------------------------------------------------------------- +vec3 ToneMapping(vec3 color) +{ + float MIDDLE_GRAY = 0.72f; + float LUM_WHITE = 1.5f; + + // Tone mapping + color.rgb *= MIDDLE_GRAY; + color.rgb *= (1.0f + color/LUM_WHITE); + color.rgb /= (1.0f + color); + + return color; +}