diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class1/deferred')
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl | 129 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl | 180 | 
2 files changed, 181 insertions, 128 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl index fc6d4d7727..c4610bffac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl @@ -28,138 +28,11 @@  out vec4 frag_color;  uniform sampler2D diffuseRect; -uniform sampler2D exposureMap; -uniform vec2 screen_res;  in vec2 vary_fragcoord;  vec3 linear_to_srgb(vec3 cl); - -//=============================================================== -// tone mapping taken from Khronos sample implementation -//=============================================================== - -// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT -const mat3 ACESInputMat = mat3 -( -    0.59719, 0.07600, 0.02840, -    0.35458, 0.90834, 0.13383, -    0.04823, 0.01566, 0.83777 -); - - -// ODT_SAT => XYZ => D60_2_D65 => sRGB -const mat3 ACESOutputMat = mat3 -( -    1.60475, -0.10208, -0.00327, -    -0.53108,  1.10813, -0.07276, -    -0.07367, -0.00605,  1.07602 -); - -// ACES tone map (faster approximation) -// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ -vec3 toneMapACES_Narkowicz(vec3 color) -{ -    const float A = 2.51; -    const float B = 0.03; -    const float C = 2.43; -    const float D = 0.59; -    const float E = 0.14; -    return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); -} - - -// ACES filmic tone map approximation -// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl -vec3 RRTAndODTFit(vec3 color) -{ -    vec3 a = color * (color + 0.0245786) - 0.000090537; -    vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; -    return a / b; -} - - -// tone mapping -vec3 toneMapACES_Hill(vec3 color) -{ -    color = ACESInputMat * color; - -    // Apply RRT and ODT -    color = RRTAndODTFit(color); - -    color = ACESOutputMat * color; - -    // Clamp to [0, 1] -    color = clamp(color, 0.0, 1.0); - -    return color; -} - -// Khronos Neutral tonemapping -// https://github.com/KhronosGroup/ToneMapping/tree/main -// Input color is non-negative and resides in the Linear Rec. 709 color space. -// Output color is also Linear Rec. 709, but in the [0, 1] range. -vec3 PBRNeutralToneMapping( vec3 color ) -{ -  const float startCompression = 0.8 - 0.04; -  const float desaturation = 0.15; - -  float x = min(color.r, min(color.g, color.b)); -  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; -  color -= offset; - -  float peak = max(color.r, max(color.g, color.b)); -  if (peak < startCompression) return color; - -  const float d = 1. - startCompression; -  float newPeak = 1. - d * d / (peak + d - startCompression); -  color *= newPeak / peak; - -  float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); -  return mix(color, newPeak * vec3(1, 1, 1), g); -} - -uniform float exposure; -uniform float tonemap_mix; -uniform int tonemap_type; - -vec3 toneMap(vec3 color) -{ -#ifndef NO_POST -    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - -    color *= exposure * exp_scale; - -    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); - -    switch(tonemap_type) -    { -    case 0: -        color = PBRNeutralToneMapping(color); -        break; -    case 1: -        color = toneMapACES_Hill(color); -        break; -    } - -    // mix tonemapped and linear here to provide adjustment -    color = mix(clamped_color, color, tonemap_mix); -#endif - -    return color; -} - -//=============================================================== - -void debugExposure(inout vec3 color) -{ -    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; -    exp_scale *= 0.5; -    if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) -    { -        color = vec3(1,0,0); -    } -} +vec3 toneMap(vec3 color);  void main()  { diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl new file mode 100644 index 0000000000..a63b8d7c2b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl @@ -0,0 +1,180 @@ +/** + * @file postDeferredTonemap.glsl + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +uniform sampler2D exposureMap; +uniform vec2 screen_res; +in vec2 vary_fragcoord; + +//=============================================================== +// tone mapping taken from Khronos sample implementation +//=============================================================== + +// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT +const mat3 ACESInputMat = mat3 +( +    0.59719, 0.07600, 0.02840, +    0.35458, 0.90834, 0.13383, +    0.04823, 0.01566, 0.83777 +); + + +// ODT_SAT => XYZ => D60_2_D65 => sRGB +const mat3 ACESOutputMat = mat3 +( +    1.60475, -0.10208, -0.00327, +    -0.53108,  1.10813, -0.07276, +    -0.07367, -0.00605,  1.07602 +); + +// ACES tone map (faster approximation) +// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +vec3 toneMapACES_Narkowicz(vec3 color) +{ +    const float A = 2.51; +    const float B = 0.03; +    const float C = 2.43; +    const float D = 0.59; +    const float E = 0.14; +    return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); +} + + +// ACES filmic tone map approximation +// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl +vec3 RRTAndODTFit(vec3 color) +{ +    vec3 a = color * (color + 0.0245786) - 0.000090537; +    vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; +    return a / b; +} + + +// tone mapping +vec3 toneMapACES_Hill(vec3 color) +{ +    color = ACESInputMat * color; + +    // Apply RRT and ODT +    color = RRTAndODTFit(color); + +    color = ACESOutputMat * color; + +    // Clamp to [0, 1] +    color = clamp(color, 0.0, 1.0); + +    return color; +} + +// Khronos Neutral tonemapping +// https://github.com/KhronosGroup/ToneMapping/tree/main +// Input color is non-negative and resides in the Linear Rec. 709 color space. +// Output color is also Linear Rec. 709, but in the [0, 1] range. +vec3 PBRNeutralToneMapping( vec3 color ) +{ +  const float startCompression = 0.8 - 0.04; +  const float desaturation = 0.15; + +  float x = min(color.r, min(color.g, color.b)); +  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; +  color -= offset; + +  float peak = max(color.r, max(color.g, color.b)); +  if (peak < startCompression) return color; + +  const float d = 1. - startCompression; +  float newPeak = 1. - d * d / (peak + d - startCompression); +  color *= newPeak / peak; + +  float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); +  return mix(color, newPeak * vec3(1, 1, 1), g); +} + +uniform float exposure; +uniform float tonemap_mix; +uniform int tonemap_type; + +vec3 toneMap(vec3 color) +{ +#ifndef NO_POST +    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; + +    color *= exposure * exp_scale; + +    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + +    switch(tonemap_type) +    { +    case 0: +        color = PBRNeutralToneMapping(color); +        break; +    case 1: +        color = toneMapACES_Hill(color); +        break; +    } + +    // mix tonemapped and linear here to provide adjustment +    color = mix(clamped_color, color, tonemap_mix); +#endif + +    return color; +} + + +vec3 toneMapNoExposure(vec3 color) +{ +#ifndef NO_POST +    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + +    switch(tonemap_type) +    { +    case 0: +        color = PBRNeutralToneMapping(color); +        break; +    case 1: +        color = toneMapACES_Hill(color); +        break; +    } + +    // mix tonemapped and linear here to provide adjustment +    color = mix(clamped_color, color, tonemap_mix); +#endif + +    return color; +} + + +//=============================================================== + +void debugExposure(inout vec3 color) +{ +    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; +    exp_scale *= 0.5; +    if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) +    { +        color = vec3(1,0,0); +    } +} | 
