diff options
Diffstat (limited to 'drivers/gles3/shaders/tonemap.glsl')
| -rw-r--r-- | drivers/gles3/shaders/tonemap.glsl | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index dd6d78849b..f1fe1742eb 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -124,13 +124,16 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) { #endif vec3 tonemap_filmic(vec3 color, float white) { - const float A = 0.15f; - const float B = 0.50f; + // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers + // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) + // has no effect on the curve's general shape or visual properties + const float exposure_bias = 2.0f; + const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance + const float B = 0.30f * exposure_bias; const float C = 0.10f; const float D = 0.20f; - const float E = 0.02f; + const float E = 0.01f; const float F = 0.30f; - const float W = 11.2f; vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F; @@ -139,10 +142,11 @@ vec3 tonemap_filmic(vec3 color, float white) { } vec3 tonemap_aces(vec3 color, float white) { - const float A = 2.51f; - const float B = 0.03f; - const float C = 2.43f; - const float D = 0.59f; + const float exposure_bias = 0.85f; + const float A = 2.51f * exposure_bias * exposure_bias; + const float B = 0.03f * exposure_bias; + const float C = 2.43f * exposure_bias * exposure_bias; + const float D = 0.59f * exposure_bias; const float E = 0.14f; vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E); @@ -151,8 +155,8 @@ vec3 tonemap_aces(vec3 color, float white) { return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); } -vec3 tonemap_reindhart(vec3 color, float white) { - return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here! +vec3 tonemap_reinhard(vec3 color, float white) { + return clamp((white * color + color) / (color * white + white), vec3(0.0f), vec3(1.0f)); } vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1] @@ -160,9 +164,10 @@ vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); } -vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color -#ifdef USE_REINDHART_TONEMAPPER - return tonemap_reindhart(color, white); +// inputs are LINEAR, If Linear tonemapping is selected no transform is performed else outputs are clamped [0, 1] color +vec3 apply_tonemapping(vec3 color, float white) { +#ifdef USE_REINHARD_TONEMAPPER + return tonemap_reinhard(color, white); #endif #ifdef USE_FILMIC_TONEMAPPER @@ -173,7 +178,7 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o return tonemap_aces(color, white); #endif - return clamp(color, vec3(0.0f), vec3(1.0f)); // no other selected -> linear + return color; // no other selected -> linear: no color transform applied } vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels @@ -216,10 +221,14 @@ vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blendi #endif #ifdef USE_GLOW_SCREEN + //need color clamping + color = clamp(color, vec3(0.0f), vec3(1.0f)); color = max((color + glow) - (color * glow), vec3(0.0)); #endif #ifdef USE_GLOW_SOFTLIGHT + //need color clamping + color = clamp(color, vec3(0.0f), vec3(1.0)); glow = glow * vec3(0.5f) + vec3(0.5f); color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r))); @@ -261,14 +270,16 @@ void main() { color *= exposure; - // Early Tonemap & SRGB Conversion + // Early Tonemap & SRGB Conversion; note that Linear tonemapping does not clamp to [0, 1]; some operations below expect a [0, 1] range and will clamp color = apply_tonemapping(color, white); #ifdef KEEP_3D_LINEAR // leave color as is (-> don't convert to SRGB) #else - color = linear_to_srgb(color); // regular linear -> SRGB conversion + //need color clamping + color = clamp(color, vec3(0.0f), vec3(1.0f)); + color = linear_to_srgb(color); // regular linear -> SRGB conversion (needs clamped values) #endif // Glow @@ -278,6 +289,7 @@ void main() { // high dynamic range -> SRGB glow = apply_tonemapping(glow, white); + glow = clamp(glow, vec3(0.0f), vec3(1.0f)); glow = linear_to_srgb(glow); color = apply_glow(color, glow); |