Skip to content
This repository was archived by the owner on Nov 30, 2020. It is now read-only.

Commit 700c855

Browse files
committed
Implement proper "ACES" tone curve fitting on "RRT.a1.0.3 + ODT.Academy.RGBmonitor_100nits_dim.a1.0.3" combination.
1 parent c724179 commit 700c855

1 file changed

Lines changed: 27 additions & 14 deletions

File tree

PostProcessing/Resources/Shaders/Tonemapping.cginc

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ half3 NeutralTonemap(half3 x, half4 params1, half4 params2)
4343
}
4444

4545
//
46-
// Filmic tonemapping (pre-exposed ACES approximation, unless TONEMAPPING_USE_FULL_ACES is set to 1)
46+
// Filmic tonemapping (ACES fitting, unless TONEMAPPING_USE_FULL_ACES is set to 1)
4747
// Input is ACES2065-1 (AP0 w/ linear encoding)
4848
//
4949
half3 FilmicTonemap(half3 aces)
@@ -81,25 +81,38 @@ half3 FilmicTonemap(half3 aces)
8181
//acescg = mul(RRT_SAT_MAT, acescg);
8282
acescg = lerp(dot(acescg, AP1_RGB2Y).xxx, acescg, RRT_SAT_FACTOR.xxx);
8383

84-
// Quick'n'dirty approximation of the ACES tonemapper - pre-exposed RRT(ODT())
85-
// Adapted from https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ to
86-
// fit our range & exposure.
87-
const half a = 2.5;
88-
const half b = 0.03;
89-
const half c = 2.49;
90-
const half d = 0.6;
91-
const half e = 0.2;
84+
// Luminance fitting of *RRT.a1.0.3 + ODT.Academy.RGBmonitor_100nits_dim.a1.0.3*.
85+
// https://github.com/colour-science/colour-unity/blob/master/Assets/Colour/Notebooks/CIECAM02_Unity.ipynb
86+
// RMSE: 0.0012846272106
87+
const half a = 278.5085;
88+
const half b = 10.7772;
89+
const half c = 293.6045;
90+
const half d = 88.7122;
91+
const half e = 80.6889;
9292
half3 x = acescg;
93-
half3 color = (x * (a * x + b)) / (x * (c * x + d) + e);
93+
half3 rgbPost = (x * (a * x + b)) / (x * (c * x + d) + e);
94+
95+
// Scale luminance to linear code value
96+
// half3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK);
9497

9598
// Apply gamma adjustment to compensate for dim surround
96-
color = darkSurround_to_dimSurround(color);
99+
half3 linearCV = darkSurround_to_dimSurround(rgbPost);
97100

98101
// Apply desaturation to compensate for luminance difference
99-
//color = mul(ODT_SAT_MAT, color);
100-
color = lerp(dot(color, AP1_RGB2Y).xxx, color, ODT_SAT_FACTOR.xxx);
102+
//linearCV = mul(ODT_SAT_MAT, color);
103+
linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx);
104+
105+
// Convert to display primary encoding
106+
// Rendering space RGB to XYZ
107+
half3 XYZ = mul(AP1_2_XYZ_MAT, linearCV);
108+
109+
// Apply CAT from ACES white point to assumed observer adapted white point
110+
XYZ = mul(D60_2_D65_CAT, XYZ);
111+
112+
// CIE XYZ to display primaries
113+
linearCV = mul(XYZ_2_REC709_MAT, XYZ);
101114

102-
return ACEScg_to_unity(color);
115+
return linearCV;
103116

104117
#endif
105118
}

0 commit comments

Comments
 (0)