@@ -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//
4949half3 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