From da6b534274d88de590ab978c596a5d8b10a70a69 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 17 Feb 2022 19:37:55 +0100 Subject: Fix T95368: wrong white point adaptation for Linear ACES color space This affected loading of EXR files with set to Linear ACES colorspace, as well as the sky texture for in some custom OpenColorIO configurations. Use the builtin OpenColorIO transform from ACES AP0 to XYZ D65 to fix this. --- intern/cycles/scene/shader.cpp | 34 +++++++++++++++++----------------- intern/opencolorio/ocio_impl.cc | 18 ++++++++++-------- 2 files changed, 27 insertions(+), 25 deletions(-) (limited to 'intern') diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index 0b286aba9cf..e6c79c5faf9 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -830,28 +830,28 @@ void ShaderManager::init_xyz_transforms() Transform xyz_to_rgb; if (config->hasRole("aces_interchange")) { - /* Standard OpenColorIO role, defined as ACES2065-1. */ - const Transform xyz_E_to_aces = make_transform(1.0498110175f, - 0.0f, - -0.0000974845f, - 0.0f, - -0.4959030231f, - 1.3733130458f, - 0.0982400361f, - 0.0f, - 0.0f, - 0.0f, - 0.9912520182f, - 0.0f); - const Transform xyz_D65_to_E = make_transform( - 1.0521111f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.9184170f, 0.0f); - + /* Standard OpenColorIO role, defined as ACES AP0 (ACES2065-1). */ Transform aces_to_rgb; if (!to_scene_linear_transform(config, "aces_interchange", aces_to_rgb)) { return; } - xyz_to_rgb = aces_to_rgb * xyz_E_to_aces * xyz_D65_to_E; + /* This is the OpenColorIO builtin transform: + * UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD. */ + const Transform ACES_AP0_to_xyz_D65 = make_transform(0.938280, + -0.004451, + 0.016628, + 0.000000, + 0.337369, + 0.729522, + -0.066890, + 0.000000, + 0.001174, + -0.003711, + 1.091595, + 0.000000); + const Transform xyz_to_aces = transform_inverse(ACES_AP0_to_xyz_D65); + xyz_to_rgb = aces_to_rgb * xyz_to_aces; } else if (config->hasRole("XYZ")) { /* Custom role used before the standard existed. */ diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index b4e48c013c0..7c2f4017143 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -336,16 +336,18 @@ void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rg } if (config->hasRole("aces_interchange")) { - /* Standard OpenColorIO role, defined as ACES2065-1. */ - const float xyz_E_to_aces[3][3] = {{1.0498110175f, -0.4959030231f, 0.0f}, - {0.0f, 1.3733130458f, 0.0f}, - {-0.0000974845f, 0.0982400361f, 0.9912520182f}}; - const float xyz_D65_to_E[3][3] = { - {1.0521111f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.9184170f}}; - + /* Standard OpenColorIO role, defined as ACES AP0 (ACES2065-1). */ float aces_to_rgb[3][3]; if (to_scene_linear_matrix(config, "aces_interchange", aces_to_rgb)) { - mul_m3_series(xyz_to_rgb, aces_to_rgb, xyz_E_to_aces, xyz_D65_to_E); + /* This is the OpenColorIO builtin transform: + * UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD. */ + const float ACES_AP0_to_xyz_D65[3][3] = {{0.938280, 0.337369, 0.001174}, + {-0.004451, 0.729522, -0.003711}, + {0.016628, -0.066890, 1.091595}}; + float xyz_to_aces[3][3]; + invert_m3_m3(xyz_to_aces, ACES_AP0_to_xyz_D65); + + mul_m3_m3m3(xyz_to_rgb, aces_to_rgb, xyz_to_aces); } } else if (config->hasRole("XYZ")) { -- cgit v1.2.3