Skip to content

Commit c3f7e73

Browse files
Added PBR-neutral tone mapping (close #247)
1 parent 6cc5e6e commit c3f7e73

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

Components/src/ToneMapping.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ bool ToneMappingUpdateUI(HLSL::ToneMappingAttribs& Attribs, float* AverageLogLum
8686
{
8787
bool AttribsChanged = false;
8888
{
89-
std::array<const char*, 10> ToneMappingMode{};
89+
std::array<const char*, TONE_MAPPING_MODE_COUNT> ToneMappingMode{};
9090
ToneMappingMode[TONE_MAPPING_MODE_NONE] = "None";
9191
ToneMappingMode[TONE_MAPPING_MODE_EXP] = "Exp";
9292
ToneMappingMode[TONE_MAPPING_MODE_REINHARD] = "Reinhard";
@@ -97,6 +97,8 @@ bool ToneMappingUpdateUI(HLSL::ToneMappingAttribs& Attribs, float* AverageLogLum
9797
ToneMappingMode[TONE_MAPPING_ADAPTIVE_LOG] = "Adaptive log";
9898
ToneMappingMode[TONE_MAPPING_AGX] = "AgX";
9999
ToneMappingMode[TONE_MAPPING_AGX_CUSTOM] = "AgX Custom";
100+
ToneMappingMode[TONE_MAPPING_PBR_NEUTRAL] = "PBR Neutral";
101+
static_assert(TONE_MAPPING_MODE_COUNT == 11, "Please update ToneMappingMode array");
100102
if (ImGui::Combo("Tone Mapping Mode", &Attribs.iToneMappingMode, ToneMappingMode.data(), static_cast<int>(ToneMappingMode.size())))
101103
AttribsChanged = true;
102104
}

Shaders/PostProcess/ToneMapping/public/ToneMapping.fxh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,28 @@ float3 ToneMap(in float3 f3Color, ToneMappingAttribs Attribs, float fAveLogLum)
170170
f3ToneMappedColor = AgXEotf(f3ToneMappedColor);
171171
return f3ToneMappedColor;
172172
}
173+
#elif TONE_MAPPING_MODE == TONE_MAPPING_PBR_NEUTRAL
174+
{
175+
// https://modelviewer.dev/examples/tone-mapping
176+
// https://github.com/KhronosGroup/ToneMapping/blob/main/PBR_Neutral/README.md#pbr-neutral-specification
177+
float F90 = 0.04; // Fresnel reflection at normal incidence
178+
float Ks = 0.8 - F90; // Highlight compression start
179+
float Kd = 0.15; // Speed of desaturation
180+
181+
float x = min(f3Color.r, min(f3Color.g, f3Color.b));
182+
float Offset = (x <= 2.0 * F90) ? (x - x * x / (4.0 * F90)) : F90;
183+
float3 f3ToneMappedColor = f3Color - float3(Offset, Offset, Offset);
184+
185+
float Peak = max(f3ToneMappedColor.r, max(f3ToneMappedColor.g, f3ToneMappedColor.b));
186+
if (Peak > Ks)
187+
{
188+
float NewPeak = 1.0 - (1.0 - Ks) * (1.0 - Ks) / (Peak + 1.0 - 2.0 * Ks);
189+
f3ToneMappedColor *= NewPeak / Peak;
190+
float g = 1.0 / (Kd * (Peak - NewPeak) + 1.0);
191+
f3ToneMappedColor = lerp(float3(NewPeak, NewPeak, NewPeak), f3ToneMappedColor, g);
192+
}
193+
return f3ToneMappedColor;
194+
}
173195
#else
174196
{
175197
return f3Color;

Shaders/PostProcess/ToneMapping/public/ToneMappingStructures.fxh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#define TONE_MAPPING_ADAPTIVE_LOG 7
1919
#define TONE_MAPPING_AGX 8
2020
#define TONE_MAPPING_AGX_CUSTOM 9
21+
#define TONE_MAPPING_PBR_NEUTRAL 10
22+
#define TONE_MAPPING_MODE_COUNT 11
23+
2124

2225
struct AgXAttribs
2326
{

0 commit comments

Comments
 (0)