diff options
author | Brecht Van Lommel <brecht@blender.org> | 2022-03-22 22:41:46 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2022-04-18 20:14:34 +0300 |
commit | 029b0df81aa116a3e29f405dc8902834242d5338 (patch) | |
tree | b14a14c4480b9ef826c5a786a479a49f0ca9291f /intern/cycles/scene | |
parent | 41b3feea85cd8c323c1c5030f1ab0bc90438df4f (diff) |
Fix Cycles blackbody shader not taking into account OpenColorIO config
Keep the existing Rec.709 fit and convert to other colorspace if needed, it
seems accurate enough in practice, and keeps the same performance for the
default case.
Diffstat (limited to 'intern/cycles/scene')
-rw-r--r-- | intern/cycles/scene/shader.cpp | 39 | ||||
-rw-r--r-- | intern/cycles/scene/shader.h | 5 | ||||
-rw-r--r-- | intern/cycles/scene/shader_nodes.cpp | 4 |
3 files changed, 44 insertions, 4 deletions
diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index 8a08f2a5be9..e1af92ea8cf 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -579,6 +579,10 @@ void ShaderManager::device_update_common(Device * /*device*/, kfilm->xyz_to_g = float3_to_float4(xyz_to_g); kfilm->xyz_to_b = float3_to_float4(xyz_to_b); kfilm->rgb_to_y = float3_to_float4(rgb_to_y); + kfilm->rec709_to_r = float3_to_float4(rec709_to_r); + kfilm->rec709_to_g = float3_to_float4(rec709_to_g); + kfilm->rec709_to_b = float3_to_float4(rec709_to_b); + kfilm->is_rec709 = is_rec709; } void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene) @@ -740,6 +744,11 @@ float ShaderManager::linear_rgb_to_gray(float3 c) return dot(c, rgb_to_y); } +float3 ShaderManager::rec709_to_scene_linear(float3 c) +{ + return make_float3(dot(rec709_to_r, c), dot(rec709_to_g, c), dot(rec709_to_b, c)); +} + string ShaderManager::get_cryptomatte_materials(Scene *scene) { string manifest = "{"; @@ -802,11 +811,29 @@ void ShaderManager::init_xyz_transforms() { /* Default to ITU-BT.709 in case no appropriate transform found. * Note XYZ here is defined as having a D65 white point. */ - 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); + const Transform xyz_to_rec709 = make_transform(3.2404542f, + -1.5371385f, + -0.4985314f, + 0.0f, + -0.9692660f, + 1.8760108f, + 0.0415560f, + 0.0f, + 0.0556434f, + -0.2040259f, + 1.0572252f, + 0.0f); + + xyz_to_r = float4_to_float3(xyz_to_rec709.x); + xyz_to_g = float4_to_float3(xyz_to_rec709.y); + xyz_to_b = float4_to_float3(xyz_to_rec709.z); rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f); + rec709_to_r = make_float3(1.0f, 0.0f, 0.0f); + rec709_to_g = make_float3(0.0f, 1.0f, 0.0f); + rec709_to_b = make_float3(0.0f, 0.0f, 1.0f); + is_rec709 = true; + #ifdef WITH_OCIO /* Get from OpenColorO config if it has the required roles. */ OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); @@ -857,6 +884,12 @@ void ShaderManager::init_xyz_transforms() const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb); rgb_to_y = float4_to_float3(rgb_to_xyz.y); + + const Transform rec709_to_rgb = xyz_to_rgb * transform_inverse(xyz_to_rec709); + rec709_to_r = float4_to_float3(rec709_to_rgb.x); + rec709_to_g = float4_to_float3(rec709_to_rgb.y); + rec709_to_b = float4_to_float3(rec709_to_rgb.z); + is_rec709 = transform_equal_threshold(xyz_to_rgb, xyz_to_rec709, 0.0001f); #endif } diff --git a/intern/cycles/scene/shader.h b/intern/cycles/scene/shader.h index cbe331d8ec2..274bb9b4fa1 100644 --- a/intern/cycles/scene/shader.h +++ b/intern/cycles/scene/shader.h @@ -208,6 +208,7 @@ class ShaderManager { static void free_memory(); float linear_rgb_to_gray(float3 c); + float3 rec709_to_scene_linear(float3 c); string get_cryptomatte_materials(Scene *scene); @@ -239,6 +240,10 @@ class ShaderManager { float3 xyz_to_g; float3 xyz_to_b; float3 rgb_to_y; + float3 rec709_to_r; + float3 rec709_to_g; + float3 rec709_to_b; + bool is_rec709; }; CCL_NAMESPACE_END diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index a951a558731..95fccf725f3 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -5763,7 +5763,9 @@ BlackbodyNode::BlackbodyNode() : ShaderNode(get_node_type()) void BlackbodyNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - folder.make_constant(svm_math_blackbody_color(temperature)); + const float3 rgb_rec709 = svm_math_blackbody_color_rec709(temperature); + const float3 rgb = folder.scene->shader_manager->rec709_to_scene_linear(rgb_rec709); + folder.make_constant(rgb); } } |