Skip to content

Commit

Permalink
Introduce Khronos Neutral tonemapper as new default along with debug …
Browse files Browse the repository at this point in the history
…options to control tonemap mix (#2464) (#2468)
  • Loading branch information
RyeMutt committed Aug 30, 2024
1 parent 7ab6144 commit 5b83229
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 16 deletions.
22 changes: 22 additions & 0 deletions indra/newview/app_settings/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9832,6 +9832,28 @@
<key>Value</key>
<real>0.4</real>
</map>
<key>RenderTonemapMix</key>
<map>
<key>Comment</key>
<string>Mix between linear and tonemapped colors (0.0(Linear) - 1.0(Tonemapped)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>RenderTonemapType</key>
<map>
<key>Comment</key>
<string>What tonemapper to use: 0 = Khronos Neutral, 1 = ACES</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>ReplaySession</key>
<map>
<key>Comment</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ out vec4 frag_color;

uniform sampler2D diffuseRect;

uniform float exposure;
uniform float gamma;
uniform float aces_mix;
uniform vec2 screen_res;
in vec2 vary_fragcoord;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,33 @@ vec3 toneMapACES_Hill(vec3 color)
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 gamma;
uniform float aces_mix;
uniform float tonemap_mix;
uniform int tonemap_type;

vec3 toneMap(vec3 color)
{
Expand All @@ -106,8 +130,20 @@ vec3 toneMap(vec3 color)

color *= exposure * exp_scale;

// mix ACES and Linear here as a compromise to avoid over-darkening legacy content
color = mix(toneMapACES_Hill(color), color, aces_mix);
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;
Expand All @@ -125,14 +161,6 @@ void debugExposure(inout vec3 color)
}
}

vec3 legacyGamma(vec3 color)
{
vec3 c = 1. - clamp(color, vec3(0.), vec3(1.));
c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side

return c;
}

void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
Expand Down
10 changes: 8 additions & 2 deletions indra/newview/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7087,10 +7087,16 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst)
F32 e = llclamp(exposure(), 0.5f, 4.f);

static LLStaticHashedString s_exposure("exposure");
static LLStaticHashedString aces_mix("aces_mix");
static LLStaticHashedString tonemap_mix("tonemap_mix");
static LLStaticHashedString tonemap_type("tonemap_type");

shader.uniform1f(s_exposure, e);
shader.uniform1f(aces_mix, gEXRImage.notNull() ? 0.f : 0.3f);

static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U);
shader.uniform1i(tonemap_type, tonemap_type_setting);

static LLCachedControl<F32> tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f);
shader.uniform1f(tonemap_mix, tonemap_mix_setting);

mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
Expand Down

0 comments on commit 5b83229

Please sign in to comment.