Skip to content

Commit

Permalink
ToneMapping: Added AgX tone mapper (close #96)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikhailGorobets authored and TheMostDiligent committed Apr 17, 2024
1 parent 1c4503e commit b67bc2a
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
83 changes: 83 additions & 0 deletions Shaders/PostProcess/ToneMapping/public/ToneMapping.fxh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "ToneMappingStructures.fxh"
#include "SRGBUtilities.fxh"

#ifndef RGB_TO_LUMINANCE
# define RGB_TO_LUMINANCE float3(0.212671, 0.715160, 0.072169)
Expand All @@ -17,6 +18,72 @@ float3 Uncharted2Tonemap(float3 x)
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; // E/F = Toe Angle
}

float3 AgXDefaultContrastApprox(float3 x)
{
float3 x2 = x * x;
float3 x4 = x2 * x2;

return + 15.5 * x4 * x2
- 40.14 * x4 * x
+ 31.96 * x4
- 6.868 * x2 * x
+ 0.4298 * x2
+ 0.1191 * x
- 0.00232;
}

float3 AgX(float3 Color)
{
float3x3 AgXTransform = MatrixFromRows(
float3(0.842479062253094, 0.0784335999999992, 0.0792237451477643),
float3(0.0423282422610123, 0.878468636469772, 0.0791661274605434),
float3(0.0423756549057051, 0.0784336, 0.879142973793104));
// LOG2_MIN = -10.0
// LOG2_MAX = +6.5
// MIDDLE_GRAY = 0.18
const float MinEv = -12.47393f; // log2(pow( 2, LOG2_MIN) * MIDDLE_GRAY)
const float MaxEv = 4.026069f; // log2(pow( 2, LOG2_MAX) * MIDDLE_GRAY)

// Input transform (inset)
Color = mul(AgXTransform, Color);

// Log2 space encoding
Color = clamp(log2(Color), MinEv, MaxEv);
Color = (Color - MinEv) / (MaxEv - MinEv);

// Apply sigmoid function approximation
return AgXDefaultContrastApprox(Color);
}

float3 AgXEotf(float3 Color)
{
float3x3 InvAgXTransform = MatrixFromRows(
float3(+1.19687900512017, -0.0980208811401368, -0.0990297440797205),
float3(-0.0528968517574562, +1.15190312990417, -0.0989611768448433),
float3(-0.0529716355144438, -0.0980434501171241, +1.15107367264116));

// Inverse input transform (outset)
Color = mul(InvAgXTransform, Color);

// sRGB IEC 61966-2-1 2.2 Exponent Reference EOTF Display
// NOTE: We're linearizing the output here. Comment/adjust when
// *not* using a sRGB render target
return SRGBToLinear(Color);
}

float3 AgXPunchyLook(float3 Color, float Saturation)
{
float Lum = dot(Color, RGB_TO_LUMINANCE);

float3 Offset = float3(0.0, 0.0, 0.0);
float3 Slope = float3(1.0, 1.0, 1.0);
float3 Power = float3(1.35, 1.35, 1.35);

// ASC CDL
Color = pow(Color * Slope + Offset, Power);
return Lum + Saturation * (Color - Lum);
}

float3 ToneMap(in float3 f3Color, ToneMappingAttribs Attribs, float fAveLogLum)
{
//const float middleGray = 1.03 - 2 / (2 + log10(fAveLogLum+1));
Expand Down Expand Up @@ -87,6 +154,22 @@ float3 ToneMap(in float3 f3Color, ToneMappingAttribs Attribs, float fAveLogLum)
log(1.0 + fScaledPixelLum) / log( 2.0 + 8.0 * pow( fScaledPixelLum / whitePoint, log(Bias) / log(0.5)) );
return fToneMappedLum * pow(f3Color / fInitialPixelLum, Attribs.fLuminanceSaturation * float3(1.0, 1.0, 1.0));
}
#elif TONE_MAPPING_MODE == TONE_MAPPING_AGX
{
// https://iolite-engine.com/blog_posts/minimal_agx_implementation
float3 f3ToneMappedColor = AgX(f3ScaledColor);
f3ToneMappedColor = AgXEotf(f3ToneMappedColor);
return f3ToneMappedColor;
}
#elif TONE_MAPPING_MODE == TONE_MAPPING_AGX_PUNCHY
{
// https://iolite-engine.com/blog_posts/minimal_agx_implementation
// The constant was chosen experimentally to preserve the brightness when changing the tone mapper
float3 f3ToneMappedColor = AgX(3.0 * f3ScaledColor);
f3ToneMappedColor = AgXPunchyLook(f3ToneMappedColor, 1.4);
f3ToneMappedColor = AgXEotf(f3ToneMappedColor);
return f3ToneMappedColor;
}
#else
{
return f3Color;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#define TONE_MAPPING_FILMIC_ALU 5
#define TONE_MAPPING_LOGARITHMIC 6
#define TONE_MAPPING_ADAPTIVE_LOG 7
#define TONE_MAPPING_AGX 8
#define TONE_MAPPING_AGX_PUNCHY 9

struct ToneMappingAttribs
{
Expand Down

0 comments on commit b67bc2a

Please sign in to comment.