[Bf-blender-cvs] [7c8cbc67abd] tmp-ocio-v2: OpenColorIO: use aces_interchange role to detect CIE XYZ values

Brecht Van Lommel noreply at git.blender.org
Mon Feb 1 15:49:17 CET 2021


Commit: 7c8cbc67abdd0e2293ca810a3832749bb6031649
Author: Brecht Van Lommel
Date:   Sun Jan 31 19:56:00 2021 +0100
Branches: tmp-ocio-v2
https://developer.blender.org/rB7c8cbc67abdd0e2293ca810a3832749bb6031649

OpenColorIO: use aces_interchange role to detect CIE XYZ values

We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.

In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.

Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.

Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.

There is a new cie_xyz_d65_interchange role that we should add support for,
for interchange of display referred colorspace (as opposed to scene referred).
I couldn't immediately understand how that is supposed to be defined, will
probably leave that for another patch unless someone knows how.

===================================================================

M	intern/cycles/render/shader.cpp
M	intern/cycles/render/shader.h
M	intern/opencolorio/ocio_impl.cc
M	release/datafiles/colormanagement/config.ocio
D	release/datafiles/colormanagement/luts/aces_to_xyz.spimtx
D	release/datafiles/colormanagement/luts/rec709_to_aces.spimtx
A	release/datafiles/colormanagement/luts/xyz_to_aces.spimtx

===================================================================

diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 736eb79b09b..0b06edbbef6 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -35,6 +35,7 @@
 #include "util/util_foreach.h"
 #include "util/util_murmurhash.h"
 #include "util/util_task.h"
+#include "util/util_transform.h"
 
 #ifdef WITH_OCIO
 #  include <OpenColorIO/OpenColorIO.h>
@@ -399,43 +400,7 @@ ShaderManager::ShaderManager()
   update_flags = UPDATE_ALL;
   beckmann_table_offset = TABLE_OFFSET_INVALID;
 
-  xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
-  xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
-  xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
-  rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
-
-#ifdef WITH_OCIO
-  OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
-  if (config) {
-    if (config->hasRole("XYZ") && config->hasRole("scene_linear")) {
-      OCIO::ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
-      OCIO::ConstProcessorRcPtr to_xyz_processor = config->getProcessor("scene_linear", "XYZ");
-      if (to_rgb_processor && to_xyz_processor) {
-        OCIO::ConstCPUProcessorRcPtr to_xyz_device_processor =
-            to_xyz_processor->getDefaultCPUProcessor();
-        OCIO::ConstCPUProcessorRcPtr to_rgb_device_processor =
-            to_rgb_processor->getDefaultCPUProcessor();
-        float r[] = {1.0f, 0.0f, 0.0f};
-        float g[] = {0.0f, 1.0f, 0.0f};
-        float b[] = {0.0f, 0.0f, 1.0f};
-        to_xyz_device_processor->applyRGB(r);
-        to_xyz_device_processor->applyRGB(g);
-        to_xyz_device_processor->applyRGB(b);
-        rgb_to_y = make_float3(r[1], g[1], b[1]);
-
-        float x[] = {1.0f, 0.0f, 0.0f};
-        float y[] = {0.0f, 1.0f, 0.0f};
-        float z[] = {0.0f, 0.0f, 1.0f};
-        to_rgb_device_processor->applyRGB(x);
-        to_rgb_device_processor->applyRGB(y);
-        to_rgb_device_processor->applyRGB(z);
-        xyz_to_r = make_float3(x[0], y[0], z[0]);
-        xyz_to_g = make_float3(x[1], y[1], z[1]);
-        xyz_to_b = make_float3(x[2], y[2], z[2]);
-      }
-    }
-  }
-#endif
+  init_xyz_transforms();
 }
 
 ShaderManager::~ShaderManager()
@@ -833,4 +798,89 @@ bool ShaderManager::need_update() const
   return update_flags != UPDATE_NONE;
 }
 
+#ifdef WITH_OCIO
+static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
+                                      const char *colorspace,
+                                      Transform &to_scene_linear)
+{
+  OCIO::ConstProcessorRcPtr processor;
+  try {
+    processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, colorspace);
+  }
+  catch (OCIO::Exception &exception) {
+    return false;
+  }
+
+  if (!processor) {
+    return false;
+  }
+
+  OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
+  if (!device_processor) {
+    return false;
+  }
+
+  to_scene_linear = transform_identity();
+  device_processor->applyRGB(&to_scene_linear.x.x);
+  device_processor->applyRGB(&to_scene_linear.y.x);
+  device_processor->applyRGB(&to_scene_linear.z.x);
+  to_scene_linear = transform_transposed_inverse(to_scene_linear);
+  return true;
+}
+#endif
+
+void ShaderManager::init_xyz_transforms()
+{
+  /* Default to ITU-BT.709 in case no appropriate transform found. */
+  xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
+  xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
+  xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
+  rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
+
+#ifdef WITH_OCIO
+  /* Get from OpenColorO config if it has the required roles. */
+  OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
+  if (!config && config->hasRole(OCIO::ROLE_SCENE_LINEAR)) {
+    return;
+  }
+
+  Transform xyz_to_rgb;
+
+  if (config->hasRole("aces_interchange")) {
+    /* Standard OpenColorIO role, defined as ACES2065-1. */
+    const Transform xyz_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);
+    Transform aces_to_rgb;
+    if (!to_scene_linear_transform(config, "aces_interchange", aces_to_rgb)) {
+      return;
+    }
+
+    xyz_to_rgb = aces_to_rgb * xyz_to_aces;
+  }
+  else if (config->hasRole("XYZ")) {
+    /* Custom role used before the standard existed. */
+    if (!to_scene_linear_transform(config, "XYZ", xyz_to_rgb)) {
+      return;
+    }
+  }
+
+  xyz_to_r = float4_to_float3(xyz_to_rgb.x);
+  xyz_to_g = float4_to_float3(xyz_to_rgb.y);
+  xyz_to_b = float4_to_float3(xyz_to_rgb.z);
+
+  const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb);
+  rgb_to_y = float4_to_float3(rgb_to_xyz.y);
+#endif
+}
+
 CCL_NAMESPACE_END
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 4375ef9e978..f47d64f346c 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -221,6 +221,8 @@ class ShaderManager {
 
   bool need_update() const;
 
+  void init_xyz_transforms();
+
  protected:
   ShaderManager();
 
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index c2fa77e6b1e..92de9199261 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -38,6 +38,7 @@ using namespace OCIO_NAMESPACE;
 
 #include "BLI_math.h"
 #include "BLI_math_color.h"
+#include "BLI_math_matrix.h"
 
 #include "ocio_impl.h"
 
@@ -419,6 +420,43 @@ void OCIOImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *r
   }
 }
 
+static bool to_scene_linear_matrix(ConstConfigRcPtr &config,
+                                   const char *colorspace,
+                                   float to_scene_linear[3][3])
+{
+  ConstProcessorRcPtr processor;
+  try {
+    processor = config->getProcessor(colorspace, ROLE_SCENE_LINEAR);
+  }
+  catch (Exception &exception) {
+    OCIO_reportException(exception);
+    return false;
+  }
+
+  if (!processor) {
+    return false;
+  }
+
+  ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
+  if (!device_processor) {
+    return false;
+  }
+
+  to_scene_linear[0][0] = 1.0f;
+  to_scene_linear[0][1] = 0.0f;
+  to_scene_linear[0][2] = 0.0f;
+  to_scene_linear[1][0] = 0.0f;
+  to_scene_linear[1][1] = 1.0f;
+  to_scene_linear[1][2] = 0.0f;
+  to_scene_linear[2][0] = 0.0f;
+  to_scene_linear[2][1] = 0.0f;
+  to_scene_linear[2][2] = 1.0f;
+  device_processor->applyRGB(to_scene_linear[0]);
+  device_processor->applyRGB(to_scene_linear[1]);
+  device_processor->applyRGB(to_scene_linear[2]);
+  return true;
+}
+
 void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rgb[3][3])
 {
   ConstConfigRcPtr config = (*(ConstConfigRcPtr *)config_);
@@ -426,26 +464,25 @@ void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rg
   /* Default to ITU-BT.709 in case no appropriate transform found. */
   memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
 
-  /* Auto estimate from XYZ and scene_linear roles, assumed to be a linear transform. */
-  if (config->hasRole("XYZ") && config->hasRole("scene_linear")) {
-    ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
-    if (to_rgb_processor) {
-      ConstCPUProcessorRcPtr device_processor = to_rgb_processor->getDefaultCPUProcessor();
-
-      xyz_to_rgb[0][0] = 1.0f;
-      xyz_to_rgb[0][1] = 0.0f;
-      xyz_to_rgb[0][2] = 0.0f;
-      xyz_to_rgb[1][0] = 0.0f;
-      xyz_to_rgb[1][1] = 1.0f;
-      xyz_to_rgb[1][2] = 0.0f;
-      xyz_to_rgb[2][0] = 0.0f;
-      xyz_to_rgb[2][1] = 0.0f;
-      xyz_to_rgb[2][2] = 1.0f;
-      device_processor->applyRGB(xyz_to_rgb[0]);
-      device_processor->applyRGB(xyz_to_rgb[1]);
-      device_processor->applyRGB(xyz_to_rgb[2]);
+  /* Get from OpenColorO config if it has the required roles. */
+  if (!config->hasRole(ROLE_SCENE_LINEAR)) {
+    return;
+  }
+
+  if (config->hasRole("aces_interchange")) {
+    /* Standard OpenColorIO role, defined as ACES2065-1. */
+    const float xyz_to_aces[3][3] = {{1.0498110175f, -0.4959030231f, 0.0f},
+                                     {0.0f, 1.3733130458f, 0.0f},
+                                     {-0.0000974845f, 0.0982400361f, 0.9912520182f}};
+    float aces_to_rgb[3][3];
+    if (to_scene_linear_matrix(config, "aces_interchange", aces_to_rgb)) {
+      mul_m3_m3m3(xyz_to_rgb, aces_to_rgb, xyz_to_aces);
     }
   }
+  else if (config->hasRole("XYZ")) {
+    /* Custom role used before the standard existed. */
+    to_scene_linear_matrix(config, "XXYZ", xyz_to_rgb);
+  }
 }
 
 int OCIOImpl::configGetNumLooks(OCIO_ConstConfigRcPtr *config)
diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio
index 5ad937e3efb..8da4b13df00 100644
--- a/release/datafiles/colormanagement/config.ocio
+++ b/release/datafiles/colormanagement/config.ocio
@@ -39,8 +39,8 @@ roles:
   # Non-color data
   data: Non-Color
 
-  # CIE XYZ color space
-  XYZ: XYZ
+  # For interop between configs, and to determine XYZ for rendering
+  aces_interchange: Linear ACES
 
   # Specifed by OCIO, not used in Blender
   color_timing: Filmic Log
@@ -97,7 +97,10 @@ colorspaces:
     isdata: false
     allocation: lg2
     allocationvars: [-8.5, 5]
-    to_reference: !<FileTransform> {src: rec709_to_aces.spimtx, interpolation: linear, direction: inverse}
+    from_reference: !<GroupTransform>
+      children:
+        - !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear}
+        - !<FileTran

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list