Created
August 6, 2018 17:20
-
-
Save knarkowicz/96200ae2ddeb648d0e07446679627bf0 to your computer and use it in GitHub Desktop.
ACES Fitting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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