From c99320284ee442491876f5c777ce9fd77bce4b0a Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 28 Dec 2015 03:01:57 +0100 Subject: [PATCH 3/4] Cycles: Switch kernel from hardcoded Rec709/sRGB to the provided color space --- intern/cycles/blender/blender_curves.cpp | 14 ++++---- intern/cycles/blender/blender_mesh.cpp | 8 ++--- intern/cycles/kernel/kernel_film.h | 21 +++++++----- intern/cycles/kernel/osl/osl_services.cpp | 1 + intern/cycles/kernel/svm/svm.h | 4 +-- intern/cycles/kernel/svm/svm_blackbody.h | 5 +-- intern/cycles/kernel/svm/svm_convert.h | 6 ++-- intern/cycles/kernel/svm/svm_hsv.h | 4 +-- intern/cycles/kernel/svm/svm_image.h | 23 +++++++------ intern/cycles/kernel/svm/svm_math_util.h | 23 +++++++++++++ intern/cycles/kernel/svm/svm_mix.h | 44 ++++++++++++------------- intern/cycles/kernel/svm/svm_sepcomb_hsv.h | 4 +-- intern/cycles/kernel/svm/svm_sky.h | 5 ++- intern/cycles/kernel/svm/svm_wavelength.h | 8 ++--- intern/cycles/render/nodes.cpp | 5 ++- intern/cycles/util/util_color.h | 52 ++++++++++++++++++------------ 16 files changed, 136 insertions(+), 91 deletions(-) diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 6a119081..61c3c5f 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -764,17 +764,17 @@ void ExportCurveTriangleVcol(ParticleCurveData *CData, int vert_offset, int reso 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(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear(CData->curve_vcol[curve])); vertexindex++; - cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear(CData->curve_vcol[curve])); + cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear(CData->curve_vcol[curve])); vertexindex++; } } @@ -979,7 +979,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool 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(CData.curve_vcol[curve]); + fdata[i++] = color_srgb_to_linear(CData.curve_vcol[curve]); } } } diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index c2ccef5..b513ab0 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -288,14 +288,14 @@ static void attr_create_vertex_color(Scene *scene, size_t i = 0; for(l->data.begin(c); c != l->data.end(); ++c, ++i) { - cdata[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1()))); - cdata[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2()))); - cdata[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3()))); + cdata[0] = color_float_to_byte(color_srgb_to_linear(get_float3(c->color1()))); + cdata[1] = color_float_to_byte(color_srgb_to_linear(get_float3(c->color2()))); + cdata[2] = color_float_to_byte(color_srgb_to_linear(get_float3(c->color3()))); if(nverts[i] == 4) { cdata[3] = cdata[0]; cdata[4] = cdata[2]; - cdata[5] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4()))); + cdata[5] = color_float_to_byte(color_srgb_to_linear(get_float3(c->color4()))); cdata += 6; } else diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h index 5203ae2..08efda2 100644 --- a/intern/cycles/kernel/kernel_film.h +++ b/intern/cycles/kernel/kernel_film.h @@ -37,6 +37,11 @@ ccl_device float scene_linear_to_gray(KernelGlobals *kg, float3 c) + kernel_data.film.b_to_xyz.y * c.z; } +ccl_device float3 rec709_to_scene_linear(KernelGlobals *kg, float3 rgb) +{ + return xyz_to_scene_linear(kg, rec709_to_xyz(rgb)); +} + /* TODO(lukas): Is there a better approach? */ ccl_device float3 hsv_to_scene_linear(KernelGlobals *kg, float3 hsv) { @@ -51,17 +56,17 @@ ccl_device float3 scene_linear_to_hsv(KernelGlobals *kg, float3 c) ccl_device float4 film_map(KernelGlobals *kg, float4 irradiance, float scale) { float exposure = kernel_data.film.exposure; - float4 result = irradiance*scale; + float3 result = make_float3(irradiance.x, irradiance.y, irradiance.z)*scale; + /* TODO(lukas): Instead of converting to sRGB here and drawing with OCIO sRGB->Display, leave in scene linear and draw with OCIO Scene->Display. */ + result = xyz_to_rec709(scene_linear_to_xyz(kg, result)); /* 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); - - return result; + /* clamp alpha since it might be > 1.0 due to russian roulette */ + return make_float4(result.x, result.y, result.z, saturate(irradiance.w*scale)); } ccl_device uchar4 film_float_to_byte(float4 color) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 9ac8a3e..e961c46 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -40,6 +40,7 @@ #include "kernel_compat_cpu.h" #include "kernel_globals.h" +#include "kernel_film.h" #include "kernel_random.h" #include "kernel_projection.h" #include "kernel_differential.h" diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 69b9806..07d673c 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -237,7 +237,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade 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); @@ -441,7 +441,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade 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); diff --git a/intern/cycles/kernel/svm/svm_blackbody.h b/intern/cycles/kernel/svm/svm_blackbody.h index b750ad8..03900ec 100644 --- a/intern/cycles/kernel/svm/svm_blackbody.h +++ b/intern/cycles/kernel/svm/svm_blackbody.h @@ -39,10 +39,11 @@ ccl_device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *sta /* Input */ float temperature = stack_load_float(stack, temperature_offset); - float3 color_rgb = svm_math_blackbody_color(temperature); + float3 color = svm_math_blackbody_xyz(temperature); + color = xyz_to_scene_linear(kg, color); if(stack_valid(col_offset)) - stack_store_float3(stack, col_offset, color_rgb); + stack_store_float3(stack, col_offset, color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h index 3408037..a35128c 100644 --- a/intern/cycles/kernel/svm/svm_convert.h +++ b/intern/cycles/kernel/svm/svm_convert.h @@ -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 = scene_linear_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)scene_linear_to_gray(kg, f); stack_store_int(stack, to, i); break; } diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h index 1f2cad6..11a0f8a 100644 --- a/intern/cycles/kernel/svm/svm_hsv.h +++ b/intern/cycles/kernel/svm/svm_hsv.h @@ -32,7 +32,7 @@ ccl_device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, ui float sat = stack_load_float(stack, node1.z); float val = stack_load_float(stack, node1.w); - color = rgb_to_hsv(color); + color = scene_linear_to_hsv(kg, color); /* remember: fmod doesn't work for negative numbers here */ color.x += hue + 0.5f; @@ -40,7 +40,7 @@ ccl_device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, ui color.y *= sat; color.z *= val; - color = hsv_to_rgb(color); + color = hsv_to_scene_linear(kg, color); color.x = fac*color.x + (1.0f - fac)*in_color.x; color.y = fac*color.y + (1.0f - fac)*in_color.y; diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index caf0b37..010cbfe 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -120,12 +120,14 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, } if(srgb) { - r.x = color_srgb_to_scene_linear(r.x); - r.y = color_srgb_to_scene_linear(r.y); - r.z = color_srgb_to_scene_linear(r.z); + r.x = color_srgb_to_linear(r.x); + r.y = color_srgb_to_linear(r.y); + r.z = color_srgb_to_linear(r.z); } - return r; + /* TODO(lukas): This assumes that the texture is in Rec709/Linear sRGB, will be replaced with proper CM later on */ + float3 rcol = rec709_to_scene_linear(kg, make_float3(r.x, r.y, r.z)); + return make_float4(rcol.x, rcol.y, rcol.z, r.w); } #else @@ -325,7 +327,7 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, } if(srgb) { - r_ssef = color_srgb_to_scene_linear(r_ssef); + r_ssef = color_srgb_to_linear(r_ssef); r.w = alpha; } #else @@ -343,15 +345,16 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, } if(srgb) { - r.x = color_srgb_to_scene_linear(r.x); - r.y = color_srgb_to_scene_linear(r.y); - r.z = color_srgb_to_scene_linear(r.z); + r.x = color_srgb_to_linear(r.x); + r.y = color_srgb_to_linear(r.y); + r.z = color_srgb_to_linear(r.z); } #endif - return r; + /* TODO(lukas): This assumes that the texture is in Rec709/Linear sRGB, will be replaced with proper CM later on */ + float3 rcol = rec709_to_scene_linear(kg, make_float3(r.x, r.y, r.z)); + return make_float4(rcol.x, rcol.y, rcol.z, r.w); } - #endif /* Remap coordnate from 0..1 box to -1..-1 */ diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h index 3f7d18a..c8765b1 100644 --- a/intern/cycles/kernel/svm/svm_math_util.h +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -104,6 +104,27 @@ ccl_device float svm_math(NodeMath type, float Fac1, float Fac2) return Fac; } +ccl_device float3 svm_math_blackbody_xyz(float t) { + float x_c; + t = clamp(t, 1667.0f, 25000.0f); + float invT = 1000.0f / t; + if(t < 4000.0f) + x_c = ((-0.2661239f * invT - 0.2343580f) * invT + 0.8776956f) * invT + 0.179910f; + else + x_c = ((-3.0258469f * invT + 2.1070379f) * invT + 0.2226347f) * invT + 0.240390f; + + float y_c; + if(t < 2222.0f) + y_c = ((-1.1063814f * x_c - 1.34811020f) * x_c + 2.18555832f) * x_c - 0.20219683f; + else if(t < 4000.0f) + y_c = ((-0.9549276f * x_c - 1.37418593f) * x_c + 2.09137015f) * x_c - 0.16748867f; + else + y_c = (( 3.0817580f * x_c - 5.87338760f) * x_c + 3.75112997f) * x_c - 0.37001483f; + + return xyY_to_xyz(x_c, y_c, 1.0f); +} + +#if 0 ccl_device float3 svm_math_blackbody_color(float t) { /* Calculate color in range 800..12000 using an approximation * a/x+bx+c for R and G and ((at + b)t + c)t + d) for B @@ -166,6 +187,8 @@ ccl_device float3 svm_math_blackbody_color(float t) { return make_float3(4.70366907f, 0.0f, 0.0f); } +#endif + ccl_device_inline float3 svm_math_gamma_color(float3 color, float gamma) { if(color.x > 0.0f) diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h index 6111214..873c040 100644 --- a/intern/cycles/kernel/svm/svm_mix.h +++ b/intern/cycles/kernel/svm/svm_mix.h @@ -171,16 +171,16 @@ ccl_device float3 svm_mix_burn(float t, float3 col1, float3 col2) return outcol; } -ccl_device float3 svm_mix_hue(float t, float3 col1, float3 col2) +ccl_device float3 svm_mix_hue(KernelGlobals *kg, float t, float3 col1, float3 col2) { float3 outcol = col1; - float3 hsv2 = rgb_to_hsv(col2); + float3 hsv2 = scene_linear_to_hsv(kg, col2); if(hsv2.y != 0.0f) { - float3 hsv = rgb_to_hsv(outcol); + float3 hsv = scene_linear_to_hsv(kg, outcol); hsv.x = hsv2.x; - float3 tmp = hsv_to_rgb(hsv); + float3 tmp = hsv_to_scene_linear(kg, hsv); outcol = interp(outcol, tmp, t); } @@ -188,46 +188,46 @@ ccl_device float3 svm_mix_hue(float t, float3 col1, float3 col2) return outcol; } -ccl_device float3 svm_mix_sat(float t, float3 col1, float3 col2) +ccl_device float3 svm_mix_sat(KernelGlobals *kg, float t, float3 col1, float3 col2) { float tm = 1.0f - t; float3 outcol = col1; - float3 hsv = rgb_to_hsv(outcol); + float3 hsv = scene_linear_to_hsv(kg, outcol); if(hsv.y != 0.0f) { - float3 hsv2 = rgb_to_hsv(col2); + float3 hsv2 = scene_linear_to_hsv(kg, col2); hsv.y = tm*hsv.y + t*hsv2.y; - outcol = hsv_to_rgb(hsv); + outcol = hsv_to_scene_linear(kg, hsv); } return outcol; } -ccl_device float3 svm_mix_val(float t, float3 col1, float3 col2) +ccl_device float3 svm_mix_val(KernelGlobals *kg, float t, float3 col1, float3 col2) { float tm = 1.0f - t; - float3 hsv = rgb_to_hsv(col1); - float3 hsv2 = rgb_to_hsv(col2); + float3 hsv = scene_linear_to_hsv(kg, col1); + float3 hsv2 = scene_linear_to_hsv(kg, col2); hsv.z = tm*hsv.z + t*hsv2.z; - return hsv_to_rgb(hsv); + return hsv_to_scene_linear(kg, hsv); } -ccl_device float3 svm_mix_color(float t, float3 col1, float3 col2) +ccl_device float3 svm_mix_color(KernelGlobals *kg, float t, float3 col1, float3 col2) { float3 outcol = col1; - float3 hsv2 = rgb_to_hsv(col2); + float3 hsv2 = scene_linear_to_hsv(kg, col2); if(hsv2.y != 0.0f) { - float3 hsv = rgb_to_hsv(outcol); + float3 hsv = scene_linear_to_hsv(kg, outcol); hsv.x = hsv2.x; hsv.y = hsv2.y; - float3 tmp = hsv_to_rgb(hsv); + float3 tmp = hsv_to_scene_linear(kg, hsv); outcol = interp(outcol, tmp, t); } @@ -261,7 +261,7 @@ ccl_device float3 svm_mix_clamp(float3 col) return outcol; } -ccl_device float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2) +ccl_device float3 svm_mix(KernelGlobals *kg, NodeMix type, float fac, float3 c1, float3 c2) { float t = saturate(fac); @@ -278,10 +278,10 @@ ccl_device float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2) case NODE_MIX_LIGHT: return svm_mix_light(t, c1, c2); case NODE_MIX_DODGE: return svm_mix_dodge(t, c1, c2); case NODE_MIX_BURN: return svm_mix_burn(t, c1, c2); - case NODE_MIX_HUE: return svm_mix_hue(t, c1, c2); - case NODE_MIX_SAT: return svm_mix_sat(t, c1, c2); - case NODE_MIX_VAL: return svm_mix_val (t, c1, c2); - case NODE_MIX_COLOR: return svm_mix_color(t, c1, c2); + case NODE_MIX_HUE: return svm_mix_hue(kg, t, c1, c2); + case NODE_MIX_SAT: return svm_mix_sat(kg, t, c1, c2); + case NODE_MIX_VAL: return svm_mix_val(kg, t, c1, c2); + case NODE_MIX_COLOR: return svm_mix_color(kg, t, c1, c2); case NODE_MIX_SOFT: return svm_mix_soft(t, c1, c2); case NODE_MIX_LINEAR: return svm_mix_linear(t, c1, c2); case NODE_MIX_CLAMP: return svm_mix_clamp(c1); @@ -300,7 +300,7 @@ ccl_device void svm_node_mix(KernelGlobals *kg, ShaderData *sd, float *stack, ui float fac = stack_load_float(stack, fac_offset); float3 c1 = stack_load_float3(stack, c1_offset); float3 c2 = stack_load_float3(stack, c2_offset); - float3 result = svm_mix((NodeMix)node1.y, fac, c1, c2); + float3 result = svm_mix(kg, (NodeMix)node1.y, fac, c1, c2); stack_store_float3(stack, node1.z, result); } diff --git a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h index 6f51b16..2585bbb 100644 --- a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h +++ b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h @@ -26,7 +26,7 @@ ccl_device void svm_node_combine_hsv(KernelGlobals *kg, ShaderData *sd, float *s float value = stack_load_float(stack, value_in); /* Combine, and convert back to RGB */ - float3 color = hsv_to_rgb(make_float3(hue, saturation, value)); + float3 color = hsv_to_scene_linear(kg, make_float3(hue, saturation, value)); if(stack_valid(color_out)) stack_store_float3(stack, color_out, color); @@ -40,7 +40,7 @@ ccl_device void svm_node_separate_hsv(KernelGlobals *kg, ShaderData *sd, float * float3 color = stack_load_float3(stack, color_in); /* Convert to HSV */ - color = rgb_to_hsv(color); + color = scene_linear_to_hsv(kg, color); if(stack_valid(hue_out)) stack_store_float(stack, hue_out, color.x); diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h index 4c8e3a3..4589971 100644 --- a/intern/cycles/kernel/svm/svm_sky.h +++ b/intern/cycles/kernel/svm/svm_sky.h @@ -58,8 +58,7 @@ ccl_device float3 sky_radiance_old(KernelGlobals *kg, float3 dir, float Y = radiance_x * sky_perez_function(config_x, theta, gamma); /* convert to RGB */ - float3 xyz = xyY_to_xyz(x, y, Y); - return xyz_to_rgb(xyz.x, xyz.y, xyz.z); + return xyz_to_scene_linear(kg, xyY_to_xyz(x, y, Y)); } /* @@ -102,7 +101,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_scene_linear(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) diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h index 57030f39..01a86e9 100644 --- a/intern/cycles/kernel/svm/svm_wavelength.h +++ b/intern/cycles/kernel/svm/svm_wavelength.h @@ -34,7 +34,7 @@ CCL_NAMESPACE_BEGIN /* Wavelength to RGB */ -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) { // CIE colour matching functions xBar, yBar, and zBar for // wavelengths from 380 through 780 nanometers, every 5 @@ -85,9 +85,9 @@ ccl_device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelengt const float *c = cie_colour_match[i]; 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 *= 1.0f/2.52f; // Empirical scale from lg to make all comps <= 1 + + color *= 1.0f/2.52f; /* Empirical factor from old code */ + color = xyz_to_scene_linear(kg, color); /* Clamp to zero if values are smaller */ color = max(color, make_float3(0.0f, 0.0f, 0.0f)); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 870efda..b1fbc24 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1648,7 +1648,7 @@ bool ConvertNode::constant_fold(ShaderOutput *socket, float3 *optimized_value) else if(to == SHADER_SOCKET_FLOAT) { if(from == SHADER_SOCKET_COLOR) /* color to float */ - optimized_value->x = linear_rgb_to_gray(value); + return false; /* TODO(lukas): Do correct conversion (depending on color space) here. */ else /* vector/point/normal to float */ optimized_value->x = average(value); @@ -4038,6 +4038,8 @@ BlackbodyNode::BlackbodyNode() bool BlackbodyNode::constant_fold(ShaderOutput *socket, float3 *optimized_value) { + return false; +#if 0 /* TODO(lukas): Fold with correct colorspace here. */ ShaderInput *temperature_in = input("Temperature"); if(socket == output("Color")) { @@ -4049,6 +4051,7 @@ bool BlackbodyNode::constant_fold(ShaderOutput *socket, float3 *optimized_value) } return false; +#endif } void BlackbodyNode::compile(SVMCompiler& compiler) diff --git a/intern/cycles/util/util_color.h b/intern/cycles/util/util_color.h index d3598f8..bd21fe2 100644 --- a/intern/cycles/util/util_color.h +++ b/intern/cycles/util/util_color.h @@ -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; @@ -63,7 +63,7 @@ ccl_device float color_scene_linear_to_srgb(float c) return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; } -ccl_device float3 rgb_to_hsv(float3 rgb) +ccl_device float3 rec709_to_hsv(float3 rgb) { float cmax, cmin, h, s, v, cdelta; float3 c; @@ -102,7 +102,7 @@ ccl_device float3 rgb_to_hsv(float3 rgb) return make_float3(h, s, v); } -ccl_device float3 hsv_to_rgb(float3 hsv) +ccl_device float3 hsv_to_rec709(float3 hsv) { float i, f, p, q, t, h, s, v; float3 rgb; @@ -150,23 +150,38 @@ 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) +ccl_device float3 rec709_to_xyz(float r, float g, float b) +{ + return make_float3(0.412453f * r + 0.357580f * g + 0.180423f * b, + 0.212671f * r + 0.715160f * g + 0.072169f * b, + 0.019334f * r + 0.119194f * g + 0.950227f * b); +} + +ccl_device float3 xyz_to_rec709(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); } -#ifndef __KERNEL_OPENCL__ +ccl_device float3 xyz_to_rec709(float3 xyz) +{ + return xyz_to_rec709(xyz.x, xyz.y, xyz.z); +} -ccl_device float3 color_srgb_to_scene_linear(float3 c) +ccl_device float3 rec709_to_xyz(float3 rgb) { - 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 rec709_to_xyz(rgb.x, rgb.y, rgb.z); } +#ifndef __KERNEL_OPENCL__ +ccl_device float3 color_srgb_to_linear(float3 c) +{ + return make_float3( + color_srgb_to_linear(c.x), + color_srgb_to_linear(c.y), + color_srgb_to_linear(c.z)); +} #ifdef __KERNEL_SSE2__ /* * Calculate initial guess for arg^exp based on float representation @@ -214,7 +229,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)); @@ -224,21 +239,16 @@ ccl_device ssef color_srgb_to_scene_linear(const ssef &c) } #endif -ccl_device float3 color_scene_linear_to_srgb(float3 c) +ccl_device float3 color_linear_to_srgb(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)); + color_linear_to_srgb(c.x), + color_linear_to_srgb(c.y), + color_linear_to_srgb(c.z)); } #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__ */ -- 1.9.1