Cycles: Query XYZ to/from Scene Linear conversion from OCIO instead of assuming sRGB
authorLukas Stockner <lukas.stockner@freenet.de>
Thu, 14 Jun 2018 15:48:19 +0000 (17:48 +0200)
committerLukas Stockner <lukas.stockner@freenet.de>
Thu, 14 Jun 2018 20:21:37 +0000 (22:21 +0200)
I've limited it to just the RGB<->XYZ stuff for now, correct image handling is the next step.

Reviewers: brecht, sergey

Differential Revision: https://developer.blender.org/D3478

32 files changed:
intern/cycles/CMakeLists.txt
intern/cycles/app/CMakeLists.txt
intern/cycles/blender/blender_curves.cpp
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_session.cpp
intern/cycles/cmake/external_libs.cmake
intern/cycles/kernel/kernel_color.h [new file with mode: 0644]
intern/cycles/kernel/kernel_film.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
intern/cycles/kernel/kernels/cuda/kernel.cu
intern/cycles/kernel/kernels/opencl/kernel.cl
intern/cycles/kernel/osl/osl_services.cpp
intern/cycles/kernel/shaders/node_color.h
intern/cycles/kernel/split/kernel_split_common.h
intern/cycles/kernel/svm/svm.h
intern/cycles/kernel/svm/svm_closure.h
intern/cycles/kernel/svm/svm_convert.h
intern/cycles/kernel/svm/svm_image.h
intern/cycles/kernel/svm/svm_math_util.h
intern/cycles/kernel/svm/svm_sky.h
intern/cycles/kernel/svm/svm_wavelength.h
intern/cycles/render/constant_fold.cpp
intern/cycles/render/constant_fold.h
intern/cycles/render/graph.cpp
intern/cycles/render/graph.h
intern/cycles/render/nodes.cpp
intern/cycles/render/shader.cpp
intern/cycles/render/shader.h
intern/cycles/test/CMakeLists.txt
intern/cycles/util/util_color.h
release/datafiles/colormanagement/config.ocio

index 100a52625d159594bd885625db19fafb55ef84f6..233bc639fd8d8f54ed207a0b009a4f620ecdaf69 100644 (file)
@@ -326,6 +326,14 @@ if(WITH_CYCLES_NETWORK)
        add_definitions(-DWITH_NETWORK)
 endif()
 
+if(WITH_OPENCOLORIO)
+       add_definitions(-DWITH_OCIO)
+       include_directories(
+               SYSTEM
+               ${OPENCOLORIO_INCLUDE_DIRS}
+       )
+endif()
+
 if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
        add_subdirectory(app)
 endif()
index d1f86a5fe7d7457c9ed8b0d83d61831e1e1cf8f5..cfca45600a5e3526758c9849b35b7f65b78a65fe 100644 (file)
@@ -80,6 +80,10 @@ macro(cycles_target_link_libraries target)
        if(WITH_CYCLES_OPENSUBDIV)
                target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
        endif()
+       if(WITH_OPENCOLORIO)
+               link_directories(${OPENCOLORIO_LIBPATH})
+               target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
+       endif()
        target_link_libraries(
                ${target}
                ${OPENIMAGEIO_LIBRARIES}
index 81d6a21cd132d13e7d30d80653af4f340795b95b..5fd3455061d794f06e4b8cd8992d034d6260ff5f 100644 (file)
@@ -784,17 +784,18 @@ static void ExportCurveTriangleVcol(ParticleCurveData *CData,
 
                        for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
                                for(int section = 0; section < resol; section++) {
-                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+                                       /* Encode vertex color using the sRGB curve. */
+                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
                                        vertexindex++;
-                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
                                        vertexindex++;
-                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
                                        vertexindex++;
-                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
                                        vertexindex++;
-                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
                                        vertexindex++;
-                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+                                       cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
                                        vertexindex++;
                                }
                        }
@@ -1010,9 +1011,10 @@ void BlenderSync::sync_curves(Mesh *mesh,
                                if(fdata) {
                                        size_t i = 0;
 
+                                       /* Encode vertex color using the sRGB curve. */
                                        for(size_t curve = 0; curve < CData.curve_vcol.size(); curve++)
                                                if(!(CData.curve_keynum[curve] <= 1 || CData.curve_length[curve] == 0.0f))
-                                                       fdata[i++] = color_srgb_to_scene_linear_v3(CData.curve_vcol[curve]);
+                                                       fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]);
                                }
                        }
                }
index 76d17bc1ae6c7a5c393d1799587e957426dc928e..8d2ade1e30b5defbcf1dccb3306620220e4e6f07 100644 (file)
@@ -401,7 +401,8 @@ static void attr_create_vertex_color(Scene *scene,
                                int n = p->loop_total();
                                for(int i = 0; i < n; i++) {
                                        float3 color = get_float3(l->data[p->loop_start() + i].color());
-                                       *(cdata++) = color_float_to_byte(color_srgb_to_scene_linear_v3(color));
+                                       /* Encode vertex color using the sRGB curve. */
+                                       *(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
                                }
                        }
                }
@@ -424,12 +425,13 @@ static void attr_create_vertex_color(Scene *scene,
                                int tri_a[3], tri_b[3];
                                face_split_tri_indices(face_flags[i], tri_a, tri_b);
 
+                               /* Encode vertex color using the sRGB curve. */
                                uchar4 colors[4];
-                               colors[0] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color1())));
-                               colors[1] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color2())));
-                               colors[2] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color3())));
+                               colors[0] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color1())));
+                               colors[1] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color2())));
+                               colors[2] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color3())));
                                if(nverts[i] == 4) {
-                                       colors[3] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color4())));
+                                       colors[3] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color4())));
                                }
 
                                cdata[0] = colors[tri_a[0]];
index 00d23b9095e5fa79000f8276642b3a0aa3f453ad..4affd0479b04fdceb0b7ea1e8973e57f7dc7e855 100644 (file)
@@ -139,6 +139,10 @@ void BlenderSession::create_session()
        scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5);
        scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5);
 
+#ifdef WITH_OCIO
+       scene->film->set_color_config(OCIO_getCurrentConfig());
+#endif
+
        session->scene = scene;
 
        /* create sync */
index 8d04025e6fdb45086b3d8702ebd53bd2addc92c4..2e386a6bfc5b0e1140311c49a586625ecd1ad158 100644 (file)
@@ -97,6 +97,12 @@ if(CYCLES_STANDALONE_REPOSITORY)
                find_package(LLVM REQUIRED)
        endif()
 
+       ####
+       # OpenColorIO
+       if(WITH_OPENCOLORIO)
+               find_package(OpenColorIO REQUIRED)
+       endif()
+
        ####
        # Boost
        set(__boost_packages filesystem regex system thread date_time)
diff --git a/intern/cycles/kernel/kernel_color.h b/intern/cycles/kernel/kernel_color.h
new file mode 100644 (file)
index 0000000..d1c3dac
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011-2018 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __KERNEL_COLOR_H__
+#define __KERNEL_COLOR_H__
+
+#include "util/util_color.h"
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device float3 xyz_to_rgb(KernelGlobals *kg, float3 xyz)
+{
+    return make_float3(dot(kernel_data.film.xyz_to_r, xyz),
+                       dot(kernel_data.film.xyz_to_g, xyz),
+                       dot(kernel_data.film.xyz_to_b, xyz));
+}
+
+ccl_device float linear_rgb_to_gray(KernelGlobals *kg, float3 c)
+{
+    return dot(c, kernel_data.film.rgb_to_y);
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __KERNEL_COLOR_H__ */
\ No newline at end of file
index f9e9b41389867df73a8f1ea3f0378f6e3997e194..94815601179721426d9dd354706431c7905c46e8 100644 (file)
@@ -22,9 +22,9 @@ ccl_device float4 film_map(KernelGlobals *kg, float4 irradiance, float scale)
        float4 result = irradiance*scale;
 
        /* conversion to srgb */
-       result.x = color_scene_linear_to_srgb(result.x*exposure);
-       result.y = color_scene_linear_to_srgb(result.y*exposure);
-       result.z = color_scene_linear_to_srgb(result.z*exposure);
+       result.x = color_linear_to_srgb(result.x*exposure);
+       result.y = color_linear_to_srgb(result.y*exposure);
+       result.z = color_linear_to_srgb(result.z*exposure);
 
        /* clamp since alpha might be > 1.0 due to russian roulette */
        result.w = saturate(result.w);
index 5382213e6f7dd6b75a5d2b1eebe4992f1d7e458f..633518c7926b5e9ccb90fb77bfeba5d8ada3d7f6 100644 (file)
@@ -1272,6 +1272,11 @@ typedef struct KernelFilm {
        int pass_denoising_clean;
        int denoising_flags;
 
+       float3 xyz_to_r;
+       float3 xyz_to_g;
+       float3 xyz_to_b;
+       float3 rgb_to_y;
+
        int pad1, pad2, pad3;
 
 #ifdef __KERNEL_DEBUG__
index ccca023a15f36d6b6d08379cc3932b2faca57033..5ec1655ab056efa95f98eb8aa1e9cda1a49100e0 100644 (file)
@@ -30,6 +30,7 @@
 #    include "kernel/split/kernel_split_data.h"
 #    include "kernel/kernel_globals.h"
 
+#    include "kernel/kernel_color.h"
 #    include "kernel/kernels/cpu/kernel_cpu_image.h"
 #    include "kernel/kernel_film.h"
 #    include "kernel/kernel_path.h"
index 3c93e00ccf12bd35a9a54becb3fbb31972955cb6..8a180a509e8f93173e107298de6b5f85cd3d2657 100644 (file)
@@ -26,6 +26,7 @@
 #include "kernel/kernel_math.h"
 #include "kernel/kernel_types.h"
 #include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
 #include "kernel/kernels/cuda/kernel_cuda_image.h"
 #include "kernel/kernel_film.h"
 #include "kernel/kernel_path.h"
index 9d5d784e140c98524e97d7db53d18a39df4df442..63128d0aecf37871ab8204f92ea75b2ce7f0d380 100644 (file)
@@ -20,6 +20,7 @@
 #include "kernel/kernel_math.h"
 #include "kernel/kernel_types.h"
 #include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
 #include "kernel/kernels/opencl/kernel_opencl_image.h"
 
 #include "kernel/kernel_film.h"
index 5f4baf6fda3959d7fc639e4f81b28edd983c1b70..1aca54d2ad56881e52dcbea2f0396449b2b8733c 100644 (file)
@@ -41,6 +41,7 @@
 #include "kernel/kernel_compat_cpu.h"
 #include "kernel/split/kernel_split_data_types.h"
 #include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
 #include "kernel/kernel_random.h"
 #include "kernel/kernel_projection.h"
 #include "kernel/kernel_differential.h"
index 4a17286a07fd6ac2bf8c41113d0e8c68fb90273f..2c3a810cb18a62e32ea42849aec19944efadc441 100644 (file)
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+/* TODO(lukas): Fix colors in OSL. */
+
 float color_srgb_to_scene_linear(float c)
 {
        if (c < 0.04045)
index abe681044493652ee1a0a1af8f243531ed6c21d5..4b86696691a89f3c871faea1dfb4cc9934418840 100644 (file)
@@ -23,6 +23,7 @@
 #include "kernel/split/kernel_split_data.h"
 
 #include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
 
 #ifdef __OSL__
 #  include "kernel/osl/osl_shader.h"
index bfa146f2d93ef53adccd32d99e98732786c5ba09..ce2affe96c871f98089da818cb0706832f7878bf 100644 (file)
@@ -243,7 +243,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
                                svm_node_geometry(kg, sd, stack, node.y, node.z);
                                break;
                        case NODE_CONVERT:
-                               svm_node_convert(sd, stack, node.y, node.z, node.w);
+                               svm_node_convert(kg, sd, stack, node.y, node.z, node.w);
                                break;
                        case NODE_TEX_COORD:
                                svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset);
@@ -465,7 +465,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
                                svm_node_wireframe(kg, sd, stack, node);
                                break;
                        case NODE_WAVELENGTH:
-                               svm_node_wavelength(sd, stack, node.y, node.z);
+                               svm_node_wavelength(kg, sd, stack, node.y, node.z);
                                break;
                        case NODE_BLACKBODY:
                                svm_node_blackbody(kg, sd, stack, node.y, node.z);
index 886a1333fa34087d2c114878226eceec13ca0ccf..76464e37c664dd9283ac612967fe1a46c1855a29 100644 (file)
@@ -217,7 +217,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 
                        /* sheen */
                        if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
-                               float m_cdlum = linear_rgb_to_gray(base_color);
+                               float m_cdlum = linear_rgb_to_gray(kg, base_color);
                                float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
 
                                /* color of the sheen component */
index 34080377083bf7e1e7de84da84605e05fc9e2082..c88ac57e20d80da1823fe859eaf231d2fad31220 100644 (file)
@@ -18,7 +18,7 @@ CCL_NAMESPACE_BEGIN
 
 /* Conversion Nodes */
 
-ccl_device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to)
+ccl_device void svm_node_convert(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint from, uint to)
 {
        switch(type) {
                case NODE_CONVERT_FI: {
@@ -33,13 +33,13 @@ ccl_device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint f
                }
                case NODE_CONVERT_CF: {
                        float3 f = stack_load_float3(stack, from);
-                       float g = linear_rgb_to_gray(f);
+                       float g = linear_rgb_to_gray(kg, f);
                        stack_store_float(stack, to, g);
                        break;
                }
                case NODE_CONVERT_CI: {
                        float3 f = stack_load_float3(stack, from);
-                       int i = (int)linear_rgb_to_gray(f);
+                       int i = (int)linear_rgb_to_gray(kg, f);
                        stack_store_int(stack, to, i);
                        break;
                }
index 4226e7adfe0708bca490d40b085191ce21e11e07..28565308867209b68b12ba286f3656b138b86c0d 100644 (file)
@@ -33,7 +33,8 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
        }
 
        if(srgb) {
-               r = color_srgb_to_scene_linear_v4(r);
+               /* TODO(lukas): Implement proper conversion for image textures. */
+               r = color_srgb_to_linear_v4(r);
        }
 
        return r;
index 8e6bc73ddc760511f65d0e9ad60881f41cb9c1da..caf0addbf35cfdf59558698acbc049b6c87eb945 100644 (file)
@@ -138,6 +138,8 @@ ccl_static_constant float blackbody_table_b[6][4] = {
 
 ccl_device float3 svm_math_blackbody_color(float t)
 {
+       /* TODO(lukas): Reimplement in XYZ. */
+
        if(t >= 12000.0f) {
                return make_float3(0.826270103f, 0.994478524f, 1.56626022f);
        }
index 854e85fd326eb4c70dcf83d0f057eb8ce6a2e16a..b83a716854155c91cd1de3076aa28a31ec941675 100644 (file)
@@ -59,7 +59,7 @@ ccl_device float3 sky_radiance_old(KernelGlobals *kg, float3 dir,
 
        /* convert to RGB */
        float3 xyz = xyY_to_xyz(x, y, Y);
-       return xyz_to_rgb(xyz.x, xyz.y, xyz.z);
+       return xyz_to_rgb(kg, xyz);
 }
 
 /*
@@ -102,7 +102,7 @@ ccl_device float3 sky_radiance_new(KernelGlobals *kg, float3 dir,
        float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z;
 
        /* convert to RGB and adjust strength */
-       return xyz_to_rgb(x, y, z) * (M_2PI_F/683);
+       return xyz_to_rgb(kg, make_float3(x, y, z)) * (M_2PI_F/683);
 }
 
 ccl_device void svm_node_tex_sky(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
index 855b356b397717e9dbb692b7e9f4710496dd1368..62e026278ac82213e30654579ae7686197842467 100644 (file)
@@ -70,7 +70,7 @@ ccl_static_constant float cie_colour_match[81][3] = {
        {0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0000f,0.0000f,0.0000f}
 };
 
-ccl_device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelength, uint color_out)
+ccl_device void svm_node_wavelength(KernelGlobals *kg, ShaderData *sd, float *stack, uint wavelength, uint color_out)
 {      
        float lambda_nm = stack_load_float(stack, wavelength);
        float ii = (lambda_nm-380.0f) * (1.0f/5.0f);  // scaled 0..80
@@ -86,7 +86,7 @@ ccl_device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelengt
                color = interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii);
        }
        
-       color = xyz_to_rgb(color.x, color.y, color.z);
+       color = xyz_to_rgb(kg, color);
        color *= 1.0f/2.52f;    // Empirical scale from lg to make all comps <= 1
        
        /* Clamp to zero if values are smaller */
index 943b218f0e49e6f9b69b6ed64460175a9231f45a..98c3e99996cd2a5d81a8b4bde975f206b47cf64e 100644 (file)
@@ -22,8 +22,8 @@
 
 CCL_NAMESPACE_BEGIN
 
-ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output)
-: graph(graph), node(node), output(output)
+ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output, Scene *scene)
+: graph(graph), node(node), output(output), scene(scene)
 {
 }
 
index 33f93b8c0ab65ffcb03ef7a7957dec56ca3d3dd8..cc24d61420687aef2f51f83eb0a062565ab23d54 100644 (file)
@@ -22,6 +22,7 @@
 
 CCL_NAMESPACE_BEGIN
 
+class Scene;
 class ShaderGraph;
 class ShaderInput;
 class ShaderNode;
@@ -33,7 +34,9 @@ public:
        ShaderNode *const node;
        ShaderOutput *const output;
 
-       ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output);
+       Scene *scene;
+
+       ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output, Scene *scene);
 
        bool all_inputs_constant() const;
 
index e1c09373004b444ac140c77c74d823de171bda96..8b179f742c4b0cf7f29ac0080bab153242a99804 100644 (file)
@@ -496,7 +496,7 @@ void ShaderGraph::remove_proxy_nodes()
  * Try to constant fold some nodes, and pipe result directly to
  * the input socket of connected nodes.
  */
-void ShaderGraph::constant_fold()
+void ShaderGraph::constant_fold(Scene *scene)
 {
        ShaderNodeSet done, scheduled;
        queue<ShaderNode*> traverse_queue;
@@ -536,7 +536,7 @@ void ShaderGraph::constant_fold()
                                }
                        }
                        /* Optimize current node. */
-                       ConstantFolder folder(this, node, output);
+                       ConstantFolder folder(this, node, output, scene);
                        node->constant_fold(folder);
                }
        }
@@ -734,7 +734,7 @@ void ShaderGraph::clean(Scene *scene)
        /* Graph simplification */
 
        /* NOTE: Remove proxy nodes was already done. */
-       constant_fold();
+       constant_fold(scene);
        simplify_settings(scene);
        deduplicate_nodes();
        verify_volume_output();
index 2c134932b3cbfcf72ec510cb111eb9666cfb1b79..5d986ae48277239c60a96e1668aa9b690c706fed 100644 (file)
@@ -285,7 +285,7 @@ protected:
 
        /* Graph simplification routines. */
        void clean(Scene *scene);
-       void constant_fold();
+       void constant_fold(Scene *scene);
        void simplify_settings(Scene *scene);
        void deduplicate_nodes();
        void verify_volume_output();
index 3dad4d1a34627d77df1621c32540ef2780a6e932..0f2581b2a2e89b851e204257ddc8fb887d9f11bc 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "render/film.h"
 #include "render/image.h"
 #include "render/integrator.h"
 #include "render/light.h"
@@ -1673,7 +1674,8 @@ RGBToBWNode::RGBToBWNode()
 void RGBToBWNode::constant_fold(const ConstantFolder& folder)
 {
        if(folder.all_inputs_constant()) {
-               folder.make_constant(linear_rgb_to_gray(color));
+               float val = folder.scene->shader_manager->linear_rgb_to_gray(color);
+               folder.make_constant(val);
        }
 }
 
@@ -1769,7 +1771,8 @@ void ConvertNode::constant_fold(const ConstantFolder& folder)
                        if(to == SocketType::FLOAT) {
                                if(from == SocketType::COLOR) {
                                        /* color to float */
-                                       folder.make_constant(linear_rgb_to_gray(value_color));
+                                       float val = folder.scene->shader_manager->linear_rgb_to_gray(value_color);
+                                       folder.make_constant(val);
                                }
                                else {
                                        /* vector/point/normal to float */
index ec52c51e337f16112f37040541685542b15d0aae..e34f272d9b6dff415d5778f1cf5f8d9382488c0a 100644 (file)
 
 #include "util/util_foreach.h"
 
+#ifdef WITH_OCIO
+#  include <OpenColorIO/OpenColorIO.h>
+namespace OCIO = OCIO_NAMESPACE;
+#endif
+
 CCL_NAMESPACE_BEGIN
 
 thread_mutex ShaderManager::lookup_table_mutex;
@@ -338,6 +343,40 @@ ShaderManager::ShaderManager()
 {
        need_update = true;
        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) {
+                               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_processor->applyRGB(r);
+                               to_xyz_processor->applyRGB(g);
+                               to_xyz_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_processor->applyRGB(x);
+                               to_rgb_processor->applyRGB(y);
+                               to_rgb_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
 }
 
 ShaderManager::~ShaderManager()
@@ -518,6 +557,14 @@ void ShaderManager::device_update_common(Device *device,
        kintegrator->use_volumes = has_volumes;
        /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
        kintegrator->transparent_shadows = has_transparent_shadow;
+
+       /* film */
+       KernelFilm *kfilm = &dscene->data.film;
+       /* color space, needs to be here because e.g. displacement shaders could depend on it */
+       kfilm->xyz_to_r = xyz_to_r;
+       kfilm->xyz_to_g = xyz_to_g;
+       kfilm->xyz_to_b = xyz_to_b;
+       kfilm->rgb_to_y = rgb_to_y;
 }
 
 void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
@@ -643,5 +690,10 @@ void ShaderManager::free_memory()
        beckmann_table.free_memory();
 }
 
+float ShaderManager::linear_rgb_to_gray(float3 c)
+{
+       return dot(c, rgb_to_y);
+}
+
 CCL_NAMESPACE_END
 
index abd483caabc5fd9dfc330544fd90b0d58029d01e..0353da90013aee2de5a3abad7a69c84d41d96f18 100644 (file)
@@ -195,6 +195,8 @@ public:
 
        static void free_memory();
 
+       float linear_rgb_to_gray(float3 c);
+
 protected:
        ShaderManager();
 
@@ -211,6 +213,11 @@ protected:
                                          DeviceRequestedFeatures *requested_features);
 
        thread_spin_lock attribute_lock_;
+
+       float3 xyz_to_r;
+       float3 xyz_to_g;
+       float3 xyz_to_b;
+       float3 rgb_to_y;
 };
 
 CCL_NAMESPACE_END
index f3e49dc0c4e2e29272acf656ae764445dd42d08f..46c525eb3bb1e7f4df599c77f1dc463f05614a9d 100644 (file)
@@ -42,6 +42,11 @@ if(WITH_CYCLES_OSL)
                ${LLVM_LIBRARIES}
        )
 endif()
+if(WITH_OPENCOLORIO)
+       list(APPEND ALL_CYCLES_LIBRARIES
+               ${OPENCOLORIO_LIBRARIES}
+       )
+endif()
 if(WITH_IMAGE_OPENJPEG)
        if(WITH_SYSTEM_OPENJPEG)
                list(APPEND ALL_CYCLES_LIBRARIES ${OPENJPEG_LIBRARIES})
index c73beab98dc70cf6f7baf5f6378c2dc206b72be9..62a9bf8e47dcd172b404d77c86e25f1e01616fff 100644 (file)
@@ -47,7 +47,7 @@ ccl_device_inline float3 color_byte_to_float(uchar4 c)
        return make_float3(c.x*(1.0f/255.0f), c.y*(1.0f/255.0f), c.z*(1.0f/255.0f));
 }
 
-ccl_device float color_srgb_to_scene_linear(float c)
+ccl_device float color_srgb_to_linear(float c)
 {
        if(c < 0.04045f)
                return (c < 0.0f)? 0.0f: c * (1.0f/12.92f);
@@ -55,7 +55,7 @@ ccl_device float color_srgb_to_scene_linear(float c)
                return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
 }
 
-ccl_device float color_scene_linear_to_srgb(float c)
+ccl_device float color_linear_to_srgb(float c)
 {
        if(c < 0.0031308f)
                return (c < 0.0f)? 0.0f: c * 12.92f;
@@ -150,13 +150,6 @@ ccl_device float3 xyY_to_xyz(float x, float y, float Y)
        return make_float3(X, Y, Z);
 }
 
-ccl_device float3 xyz_to_rgb(float x, float y, float z)
-{
-       return make_float3(3.240479f * x + -1.537150f * y + -0.498535f * z,
-                         -0.969256f * x +  1.875991f * y +  0.041556f * z,
-                          0.055648f * x + -0.204043f * y +  1.057311f * z);
-}
-
 #ifdef __KERNEL_SSE2__
 /*
  * Calculate initial guess for arg^exp based on float representation
@@ -204,7 +197,7 @@ ccl_device_inline ssef fastpow24(const ssef &arg)
        return x * (x * x);
 }
 
-ccl_device ssef color_srgb_to_scene_linear(const ssef &c)
+ccl_device ssef color_srgb_to_linear(const ssef &c)
 {
        sseb cmp = c < ssef(0.04045f);
        ssef lt = max(c * ssef(1.0f/12.92f), ssef(0.0f));
@@ -214,42 +207,37 @@ ccl_device ssef color_srgb_to_scene_linear(const ssef &c)
 }
 #endif  /* __KERNEL_SSE2__ */
 
-ccl_device float3 color_srgb_to_scene_linear_v3(float3 c)
+ccl_device float3 color_srgb_to_linear_v3(float3 c)
 {
-       return make_float3(color_srgb_to_scene_linear(c.x),
-                          color_srgb_to_scene_linear(c.y),
-                          color_srgb_to_scene_linear(c.z));
+       return make_float3(color_srgb_to_linear(c.x),
+                          color_srgb_to_linear(c.y),
+                          color_srgb_to_linear(c.z));
 }
 
-ccl_device float3 color_scene_linear_to_srgb_v3(float3 c)
+ccl_device float3 color_linear_to_srgb_v3(float3 c)
 {
-       return make_float3(color_scene_linear_to_srgb(c.x),
-                          color_scene_linear_to_srgb(c.y),
-                          color_scene_linear_to_srgb(c.z));
+       return make_float3(color_linear_to_srgb(c.x),
+                          color_linear_to_srgb(c.y),
+                          color_linear_to_srgb(c.z));
 }
 
-ccl_device float4 color_srgb_to_scene_linear_v4(float4 c)
+ccl_device float4 color_srgb_to_linear_v4(float4 c)
 {
 #ifdef __KERNEL_SSE2__
        ssef r_ssef;
        float4 &r = (float4 &)r_ssef;
        r = c;
-       r_ssef = color_srgb_to_scene_linear(r_ssef);
+       r_ssef = color_srgb_to_linear(r_ssef);
        r.w = c.w;
        return r;
 #else
-       return make_float4(color_srgb_to_scene_linear(c.x),
-                          color_srgb_to_scene_linear(c.y),
-                          color_srgb_to_scene_linear(c.z),
+       return make_float4(color_srgb_to_linear(c.x),
+                          color_srgb_to_linear(c.y),
+                          color_srgb_to_linear(c.z),
                           c.w);
 #endif
 }
 
-ccl_device float linear_rgb_to_gray(float3 c)
-{
-       return c.x*0.2126f + c.y*0.7152f + c.z*0.0722f;
-}
-
 CCL_NAMESPACE_END
 
 #endif /* __UTIL_COLOR_H__ */
index 71223ea828e7a23be8ba7b110d6569483539f2bb..ce79dfeb5406287b58d668e415c10b922804e14b 100644 (file)
@@ -40,6 +40,9 @@ roles:
   # Non-color data
   data: Non-Color
 
+  # CIE XYZ color space
+  XYZ: XYZ
+
 displays:
   sRGB:
     - !<View> {name: Default, colorspace: sRGB}
@@ -188,8 +191,7 @@ colorspaces:
     allocationvars: [-8.5, 5]
     from_reference: !<GroupTransform>
       children:
-        - !<FileTransform> {src: rec709_to_aces.spimtx, interpolation: linear}
-        - !<FileTransform> {src: aces_to_xyz.spimtx, interpolation: linear}
+        - !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear}
 
   - !<ColorSpace>
     name: rrt_xyz