ACES Fitting
// Mostly code from https://github.com/ampas/aces-dev | |
Vec3 ACES_RRT( Vec3 aces ) | |
{ | |
// --- Glow module --- // | |
float saturation = rgb_2_saturation( aces); | |
float ycIn = rgb_2_yc( aces); | |
float s = sigmoid_shaper( (saturation - 0.4f) / 0.2f); | |
float addedGlow = 1.0f + glow_fwd( ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID); | |
aces = mult_f_f3( addedGlow, aces); | |
// --- Red modifier --- // | |
float hue = rgb_2_hue( aces); | |
float centeredHue = center_hue( hue, RRT_RED_HUE); | |
float hueWeight = cubic_basis_shaper( centeredHue, RRT_RED_WIDTH); | |
aces[0] = aces[0] + hueWeight * saturation * (RRT_RED_PIVOT - aces[0]) * (1.0f - RRT_RED_SCALE); | |
// --- ACES to RGB rendering space --- // | |
aces = clamp( aces, 0.0f, HALF_POS_INF); // avoids saturated negative colors from becoming positive in the matrix | |
Vec3 rgbPre = mult_f3_f33( aces, AP0_2_AP1_MAT); | |
rgbPre = clamp( rgbPre, 0.0f, HALF_MAX); | |
// --- Global desaturation --- // | |
rgbPre = mult_f3_f33( rgbPre, RRT_SAT_MAT); | |
// --- Apply the tonescale independently in rendering-space RGB --- // | |
Vec3 rgbPost; | |
rgbPost[0] = segmented_spline_c5_fwd( rgbPre[0]); | |
rgbPost[1] = segmented_spline_c5_fwd( rgbPre[1]); | |
rgbPost[2] = segmented_spline_c5_fwd( rgbPre[2]); | |
// --- RGB rendering space to OCES --- // | |
Vec3 rgbOces = mult_f3_f33( rgbPost, AP1_2_AP0_MAT); | |
return rgbOces; | |
} | |
Vec3 ACES_ODT( Vec3 oces ) | |
{ | |
// OCES to RGB rendering space | |
Vec3 rgbPre = mult_f3_f33( oces, AP0_2_AP1_MAT); | |
// Apply the tonescale independently in rendering-space RGB | |
Vec3 rgbPost; | |
rgbPost[0] = segmented_spline_c9_fwd( rgbPre[0]); | |
rgbPost[1] = segmented_spline_c9_fwd( rgbPre[1]); | |
rgbPost[2] = segmented_spline_c9_fwd( rgbPre[2]); | |
// Scale luminance to linear code value | |
Vec3 linearCV; | |
linearCV[0] = Y_2_linCV( rgbPost[0], CINEMA_WHITE, CINEMA_BLACK); | |
linearCV[1] = Y_2_linCV( rgbPost[1], CINEMA_WHITE, CINEMA_BLACK); | |
linearCV[2] = Y_2_linCV( rgbPost[2], CINEMA_WHITE, CINEMA_BLACK); | |
// Apply gamma adjustment to compensate for dim surround | |
linearCV = darkSurround_to_dimSurround( linearCV); | |
// Apply desaturation to compensate for luminance difference | |
linearCV = mult_f3_f33( linearCV, ODT_SAT_MAT); | |
// Convert to display primary encoding | |
// Rendering space RGB to XYZ | |
Vec3 XYZ = mult_f3_f33( linearCV, AP1_2_XYZ_MAT); | |
// Apply CAT from ACES white point to assumed observer adapted white point | |
//XYZ = mult_f3_f33( XYZ, D60_2_D65_CAT ); | |
// CIE XYZ to display primaries | |
linearCV = mult_f3_f33( XYZ, XYZ_2_DISPLAY_PRI_MAT); | |
// Handle out-of-gamut values | |
// Clip values < 0 or > 1 (i.e. projecting outside the display primaries) | |
linearCV = clamp( linearCV, 0.0f, 1.0f); | |
return linearCV; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment