From 0dfc5fc3421adc9f5a44f59128363c51efb7ba4a Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 10 Jun 2013 00:01:52 +0000 Subject: Cycles / Code cleanup: * Move hsv and xyz color functions into the dedicated util files (util_color.h and node_color.h). * svm_lerp moved into util_math.h and renamed to lerp_interp, as it's used for the wavelength node now as well. --- intern/cycles/kernel/svm/svm_hsv.h | 74 ------------------------------- intern/cycles/kernel/svm/svm_mix.h | 21 +++------ intern/cycles/kernel/svm/svm_sky.h | 20 --------- intern/cycles/kernel/svm/svm_wavelength.h | 17 +------ 4 files changed, 9 insertions(+), 123 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h index 348f13f59f2..6e6a9dff159 100644 --- a/intern/cycles/kernel/svm/svm_hsv.h +++ b/intern/cycles/kernel/svm/svm_hsv.h @@ -21,80 +21,6 @@ CCL_NAMESPACE_BEGIN -__device float3 rgb_to_hsv(float3 rgb) -{ - float cmax, cmin, h, s, v, cdelta; - float3 c; - - cmax = fmaxf(rgb.x, fmaxf(rgb.y, rgb.z)); - cmin = min(rgb.x, min(rgb.y, rgb.z)); - cdelta = cmax - cmin; - - v = cmax; - - if(cmax != 0.0f) { - s = cdelta/cmax; - } - else { - s = 0.0f; - h = 0.0f; - } - - if(s == 0.0f) { - h = 0.0f; - } - else { - float3 cmax3 = make_float3(cmax, cmax, cmax); - c = (cmax3 - rgb)/cdelta; - - if(rgb.x == cmax) h = c.z - c.y; - else if(rgb.y == cmax) h = 2.0f + c.x - c.z; - else h = 4.0f + c.y - c.x; - - h /= 6.0f; - - if(h < 0.0f) - h += 1.0f; - } - - return make_float3(h, s, v); -} - -__device float3 hsv_to_rgb(float3 hsv) -{ - float i, f, p, q, t, h, s, v; - float3 rgb; - - h = hsv.x; - s = hsv.y; - v = hsv.z; - - if(s == 0.0f) { - rgb = make_float3(v, v, v); - } - else { - if(h == 1.0f) - h = 0.0f; - - h *= 6.0f; - i = floorf(h); - f = h - i; - rgb = make_float3(f, f, f); - p = v*(1.0f-s); - q = v*(1.0f-(s*f)); - t = v*(1.0f-(s*(1.0f-f))); - - if(i == 0.0f) rgb = make_float3(v, t, p); - else if(i == 1.0f) rgb = make_float3(q, v, p); - else if(i == 2.0f) rgb = make_float3(p, v, t); - else if(i == 3.0f) rgb = make_float3(p, q, v); - else if(i == 4.0f) rgb = make_float3(t, p, v); - else rgb = make_float3(v, p, q); - } - - return rgb; -} - __device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_color_offset, uint fac_offset, uint out_color_offset, int *offset) { /* read extra data */ diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h index 888e4d9645e..6bbbce3f945 100644 --- a/intern/cycles/kernel/svm/svm_mix.h +++ b/intern/cycles/kernel/svm/svm_mix.h @@ -16,28 +16,21 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "svm_hsv.h" - CCL_NAMESPACE_BEGIN -__device float3 svm_lerp(const float3 a, const float3 b, float t) -{ - return (a * (1.0f - t) + b * t); -} - __device float3 svm_mix_blend(float t, float3 col1, float3 col2) { - return svm_lerp(col1, col2, t); + return lerp_interp(col1, col2, t); } __device float3 svm_mix_add(float t, float3 col1, float3 col2) { - return svm_lerp(col1, col1 + col2, t); + return lerp_interp(col1, col1 + col2, t); } __device float3 svm_mix_mul(float t, float3 col1, float3 col2) { - return svm_lerp(col1, col1 * col2, t); + return lerp_interp(col1, col1 * col2, t); } __device float3 svm_mix_screen(float t, float3 col1, float3 col2) @@ -75,7 +68,7 @@ __device float3 svm_mix_overlay(float t, float3 col1, float3 col2) __device float3 svm_mix_sub(float t, float3 col1, float3 col2) { - return svm_lerp(col1, col1 - col2, t); + return lerp_interp(col1, col1 - col2, t); } __device float3 svm_mix_div(float t, float3 col1, float3 col2) @@ -93,7 +86,7 @@ __device float3 svm_mix_div(float t, float3 col1, float3 col2) __device float3 svm_mix_diff(float t, float3 col1, float3 col2) { - return svm_lerp(col1, fabs(col1 - col2), t); + return lerp_interp(col1, fabs(col1 - col2), t); } __device float3 svm_mix_dark(float t, float3 col1, float3 col2) @@ -191,7 +184,7 @@ __device float3 svm_mix_hue(float t, float3 col1, float3 col2) hsv.x = hsv2.x; float3 tmp = hsv_to_rgb(hsv); - outcol = svm_lerp(outcol, tmp, t); + outcol = lerp_interp(outcol, tmp, t); } return outcol; @@ -238,7 +231,7 @@ __device float3 svm_mix_color(float t, float3 col1, float3 col2) hsv.y = hsv2.y; float3 tmp = hsv_to_rgb(hsv); - outcol = svm_lerp(outcol, tmp, t); + outcol = lerp_interp(outcol, tmp, t); } return outcol; diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h index eaba4d18365..8b4e35816d0 100644 --- a/intern/cycles/kernel/svm/svm_sky.h +++ b/intern/cycles/kernel/svm/svm_sky.h @@ -18,26 +18,6 @@ CCL_NAMESPACE_BEGIN -__device float3 xyY_to_xyz(float x, float y, float Y) -{ - float X, Z; - - if(y != 0.0f) X = (x / y) * Y; - else X = 0.0f; - - if(y != 0.0f && Y != 0.0f) Z = (1.0f - x - y) / y * Y; - else Z = 0.0f; - - return make_float3(X, Y, Z); -} - -__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); -} - /* * "A Practical Analytic Model for Daylight" * A. J. Preetham, Peter Shirley, Brian Smits diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h index 2ae17b8a224..97d6f82f85e 100644 --- a/intern/cycles/kernel/svm/svm_wavelength.h +++ b/intern/cycles/kernel/svm/svm_wavelength.h @@ -34,19 +34,6 @@ CCL_NAMESPACE_BEGIN /* Wavelength to RGB */ -/* ToDo: Move these 2 functions to an util file */ -__device float3 xyz_to_rgb_wave(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); -} - -__device float3 wavelength_lerp(const float3 a, const float3 b, float t) -{ - return (a * (1.0f - t) + b * t); -} - __device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelength, uint color_out) { // CIE colour matching functions xBar, yBar, and zBar for @@ -96,10 +83,10 @@ __device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelength, else { ii -= i; float *c = cie_colour_match[i]; - rgb = wavelength_lerp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii); + rgb = lerp_interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii); } - rgb = xyz_to_rgb_wave(rgb.x, rgb.y, rgb.z); + rgb = xyz_to_rgb(rgb.x, rgb.y, rgb.z); rgb *= 1.0/2.52; // Empirical scale from lg to make all comps <= 1 /* Clamp to Zero if values are smaller */ -- cgit v1.2.3 From ad2509b20d95ccdce83fd17a63bf0e6af06e0ce4 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 10 Jun 2013 08:28:39 +0000 Subject: Cycles / Wavelength Node: * Fix for OpenCL compilation, tested with Intel and nVidia. It didn't like an implicit double promotion. * Some small variable renaming. --- intern/cycles/kernel/svm/svm_wavelength.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h index 97d6f82f85e..4f2d5bd2492 100644 --- a/intern/cycles/kernel/svm/svm_wavelength.h +++ b/intern/cycles/kernel/svm/svm_wavelength.h @@ -73,27 +73,27 @@ __device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelength, }; float lambda_nm = stack_load_float(stack, wavelength); - float3 rgb; - float ii = (lambda_nm-380.0f) / 5.0f; // scaled 0..80 int i = float_to_int(ii); + float3 color; + if (i < 0 || i >= 80) { - rgb = make_float3(0.0f, 0.0f, 0.0f); + color = make_float3(0.0f, 0.0f, 0.0f); } else { ii -= i; float *c = cie_colour_match[i]; - rgb = lerp_interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii); + color = lerp_interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii); } - rgb = xyz_to_rgb(rgb.x, rgb.y, rgb.z); - rgb *= 1.0/2.52; // Empirical scale from lg to make all comps <= 1 + color = xyz_to_rgb(color.x, color.y, color.z); + color *= 1.0f/2.52f; // Empirical scale from lg to make all comps <= 1 - /* Clamp to Zero if values are smaller */ - rgb = max(rgb, make_float3(0.0f, 0.0f, 0.0f)); + /* Clamp to zero if values are smaller */ + color = max(color, make_float3(0.0f, 0.0f, 0.0f)); if(stack_valid(color_out)) - stack_store_float3(stack, color_out, rgb); + stack_store_float3(stack, color_out, color); } CCL_NAMESPACE_END -- cgit v1.2.3 From c14a4d9ed9d597043fead48fd43adb22b65bce4e Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 10 Jun 2013 21:35:32 +0000 Subject: Cycles / Wavelength node: * Fixed some things which came up during code review. --- intern/cycles/kernel/svm/svm_mix.h | 14 ++++++------ intern/cycles/kernel/svm/svm_wavelength.h | 36 +++++++++++++++---------------- 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h index 6bbbce3f945..d6a306af64d 100644 --- a/intern/cycles/kernel/svm/svm_mix.h +++ b/intern/cycles/kernel/svm/svm_mix.h @@ -20,17 +20,17 @@ CCL_NAMESPACE_BEGIN __device float3 svm_mix_blend(float t, float3 col1, float3 col2) { - return lerp_interp(col1, col2, t); + return interp(col1, col2, t); } __device float3 svm_mix_add(float t, float3 col1, float3 col2) { - return lerp_interp(col1, col1 + col2, t); + return interp(col1, col1 + col2, t); } __device float3 svm_mix_mul(float t, float3 col1, float3 col2) { - return lerp_interp(col1, col1 * col2, t); + return interp(col1, col1 * col2, t); } __device float3 svm_mix_screen(float t, float3 col1, float3 col2) @@ -68,7 +68,7 @@ __device float3 svm_mix_overlay(float t, float3 col1, float3 col2) __device float3 svm_mix_sub(float t, float3 col1, float3 col2) { - return lerp_interp(col1, col1 - col2, t); + return interp(col1, col1 - col2, t); } __device float3 svm_mix_div(float t, float3 col1, float3 col2) @@ -86,7 +86,7 @@ __device float3 svm_mix_div(float t, float3 col1, float3 col2) __device float3 svm_mix_diff(float t, float3 col1, float3 col2) { - return lerp_interp(col1, fabs(col1 - col2), t); + return interp(col1, fabs(col1 - col2), t); } __device float3 svm_mix_dark(float t, float3 col1, float3 col2) @@ -184,7 +184,7 @@ __device float3 svm_mix_hue(float t, float3 col1, float3 col2) hsv.x = hsv2.x; float3 tmp = hsv_to_rgb(hsv); - outcol = lerp_interp(outcol, tmp, t); + outcol = interp(outcol, tmp, t); } return outcol; @@ -231,7 +231,7 @@ __device float3 svm_mix_color(float t, float3 col1, float3 col2) hsv.y = hsv2.y; float3 tmp = hsv_to_rgb(hsv); - outcol = lerp_interp(outcol, tmp, t); + outcol = interp(outcol, tmp, t); } return outcol; diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h index 4f2d5bd2492..f9dd24dacef 100644 --- a/intern/cycles/kernel/svm/svm_wavelength.h +++ b/intern/cycles/kernel/svm/svm_wavelength.h @@ -10,13 +10,13 @@ * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -37,12 +37,12 @@ CCL_NAMESPACE_BEGIN __device void svm_node_wavelength(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 - // nanometers. For a wavelength lambda in this range: - // cie_colour_match[(lambda - 380) / 5][0] = xBar - // cie_colour_match[(lambda - 380) / 5][1] = yBar - // cie_colour_match[(lambda - 380) / 5][2] = zBar - float cie_colour_match[81][3] = { + // wavelengths from 380 through 780 nanometers, every 5 + // nanometers. For a wavelength lambda in this range: + // cie_colour_match[(lambda - 380) / 5][0] = xBar + // cie_colour_match[(lambda - 380) / 5][1] = yBar + // cie_colour_match[(lambda - 380) / 5][2] = zBar + const float cie_colour_match[81][3] = { {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201}, {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102}, {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456}, @@ -73,21 +73,21 @@ __device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelength, }; float lambda_nm = stack_load_float(stack, wavelength); - float ii = (lambda_nm-380.0f) / 5.0f; // scaled 0..80 - int i = float_to_int(ii); + float ii = (lambda_nm-380.0f) * (1.0f/5.0f); // scaled 0..80 + int i = float_to_int(ii); float3 color; - if (i < 0 || i >= 80) { - color = make_float3(0.0f, 0.0f, 0.0f); + if (i < 0 || i >= 80) { + color = make_float3(0.0f, 0.0f, 0.0f); } else { ii -= i; - float *c = cie_colour_match[i]; - color = lerp_interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii); + 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 scale from lg to make all comps <= 1 /* Clamp to zero if values are smaller */ color = max(color, make_float3(0.0f, 0.0f, 0.0f)); -- cgit v1.2.3 From d523d27e621f92c2fd9cb53f9dbbb62750bacc2c Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 13 Jun 2013 08:55:51 +0000 Subject: Cycles / Blackbody node: * First step towards a Blackbody to RGB converter. You can specify a color in Kelvin inside the node. * Only implemented for OSL atm, SVM will follow. --- intern/cycles/kernel/svm/svm_types.h | 1 + 1 file changed, 1 insertion(+) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index e5b3e2b972f..e4bc7efd272 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -53,6 +53,7 @@ typedef enum NodeType { NODE_FRESNEL, NODE_WIREFRAME, NODE_WAVELENGTH, + NODE_BLACKBODY, NODE_EMISSION_WEIGHT, NODE_TEX_GRADIENT, NODE_TEX_VORONOI, -- cgit v1.2.3 From 9e16c5a9e429e0d00801a4dd6ee71a8fbf6691f0 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 15 Jun 2013 23:47:09 +0000 Subject: Cycles / Blackbody node: * First (brute force) implementation for SVM. This works and delivers the same result as OSL, but it's slow. * Code inside svm_blackbody.h inspired by a patch by Philipp Oeser (#35698), thanks. Ideas: * Use a lookup table to perform the calculations on render/ level. * Implement it as a RNA property only, and do the calculation like Sun/Sky precompute. --- intern/cycles/kernel/svm/svm.h | 4 ++ intern/cycles/kernel/svm/svm_blackbody.h | 108 +++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 intern/cycles/kernel/svm/svm_blackbody.h (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 7f0bb3163a1..e08e41e78e5 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -146,6 +146,7 @@ CCL_NAMESPACE_END #include "svm_attribute.h" #include "svm_gradient.h" +#include "svm_blackbody.h" #include "svm_closure.h" #include "svm_noisetex.h" #include "svm_convert.h" @@ -366,6 +367,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_WAVELENGTH: svm_node_wavelength(sd, stack, node.y, node.z); break; + case NODE_BLACKBODY: + svm_node_blackbody(kg, sd, stack, node.y, node.z); + break; case NODE_SET_DISPLACEMENT: svm_node_set_displacement(sd, stack, node.y); break; diff --git a/intern/cycles/kernel/svm/svm_blackbody.h b/intern/cycles/kernel/svm/svm_blackbody.h new file mode 100644 index 00000000000..cc0a3630494 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_blackbody.h @@ -0,0 +1,108 @@ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2013, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +CCL_NAMESPACE_BEGIN + +/* Blackbody Node */ + +__device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset) +{ + /* Output */ + float3 color_rgb; + + /* Input */ + float temperature = stack_load_float(stack, temperature_offset); + + /* ToDo: Use a lookup table to speed this up and outsource it from the kernel */ + float X = 0, Y = 0, Z = 0; + + const float cie_colour_match[81][3] = { + {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201}, + {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102}, + {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456}, + {0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230}, + {0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721}, + {0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281}, + {0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130}, + {0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533}, + {0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582}, + {0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573}, + {0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203}, + {0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057}, + {0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021}, + {0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014}, + {1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008}, + {1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002}, + {0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000}, + {0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000}, + {0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000}, + {0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000}, + {0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000}, + {0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000}, + {0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000}, + {0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000}, + {0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000}, + {0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000}, + {0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000} + }; + + const float c1 = 3.74183e-16; // 2*pi*h*c^2, W*m^2 + const float c2 = 1.4388e-2; // h*c/k, m*K, h is Planck's const, k is Boltzmann's + const float dlambda = 5.0f * 1e-9; // in meters + + for (int i = 0; i < 81; ++i) { + float lambda = 380.0f + 5.0f * i; + float wlm = lambda * 1e-9; // Wavelength in meters + // N.B. spec_intens returns result in W/m^2 but it's a differential, + // needs to be scaled by dlambda! + float spec_intens = (c1 * powf(wlm, -5.0)) / (expf(c2 / (wlm * temperature)) -1.0f); + float Me = spec_intens * dlambda; + + X += Me * cie_colour_match[i][0]; + Y += Me * cie_colour_match[i][1]; + Z += Me * cie_colour_match[i][2]; + } + + /* Convert to RGB */ + color_rgb = xyz_to_rgb(X, Y, Z); + + /* Clamp to zero if values are smaller */ + color_rgb = max(color_rgb, make_float3(0.0f, 0.0f, 0.0f)); + + /* Scale color by luminance */ + color_rgb /= Y; + + if (stack_valid(col_offset)) + stack_store_float3(stack, col_offset, color_rgb); +} + +CCL_NAMESPACE_END -- cgit v1.2.3 From a841813cd9154ba952f27cf0a43fa24a5ea946ca Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 16 Jun 2013 16:08:11 +0000 Subject: Cycles / Blackbody node: * Replaced the Brute Force version with a nice lookup table, this speeds it up a lot. Patch by Philipp Oeser (lichtwerk) with some cleanup and changes by myself. Thanks! ToDo: * Temperature values between 800 and 804 Kelvin are wrong in SVM, check on this. --- intern/cycles/kernel/svm/svm_blackbody.h | 88 +++++++++++++------------------- 1 file changed, 35 insertions(+), 53 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_blackbody.h b/intern/cycles/kernel/svm/svm_blackbody.h index cc0a3630494..eb8282cc842 100644 --- a/intern/cycles/kernel/svm/svm_blackbody.h +++ b/intern/cycles/kernel/svm/svm_blackbody.h @@ -36,70 +36,52 @@ CCL_NAMESPACE_BEGIN __device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset) { + /* ToDo: move those defines to kernel_types.h ? */ + float bb_drapper = 800.0f; + float bb_max_table_range = 12000.0f; + float bb_table_xpower = 1.5f; + float bb_table_ypower = 5.0f; + float bb_table_spacing = 2.0f; + /* Output */ - float3 color_rgb; + float3 color_rgb = make_float3(0.0f, 0.0f, 0.0f); /* Input */ float temperature = stack_load_float(stack, temperature_offset); - /* ToDo: Use a lookup table to speed this up and outsource it from the kernel */ - float X = 0, Y = 0, Z = 0; + if (temperature < bb_drapper) { + /* just return very very dim red */ + color_rgb = make_float3(1.0e-6f,0.0f,0.0f); + } + else if (temperature <= bb_max_table_range) { + /* This is the overall size of the table (317*3+3) */ + const int lookuptablesize = 954; + const float lookuptablesizef = 954.0f; - const float cie_colour_match[81][3] = { - {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201}, - {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102}, - {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456}, - {0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230}, - {0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721}, - {0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281}, - {0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130}, - {0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533}, - {0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582}, - {0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573}, - {0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203}, - {0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057}, - {0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021}, - {0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014}, - {1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008}, - {1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002}, - {0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000}, - {0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000}, - {0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000}, - {0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000}, - {0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000}, - {0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000}, - {0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000}, - {0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000}, - {0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000}, - {0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000}, - {0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000} - }; + /* reconstruct a proper index for the table lookup, compared to OSL we don't look up two colors + just one (the OSL-lerp is also automatically done for us by "lookup_table_read") */ + float t = powf ((temperature - bb_drapper) / bb_table_spacing, 1.0f/bb_table_xpower); - const float c1 = 3.74183e-16; // 2*pi*h*c^2, W*m^2 - const float c2 = 1.4388e-2; // h*c/k, m*K, h is Planck's const, k is Boltzmann's - const float dlambda = 5.0f * 1e-9; // in meters + int blackbody_table_offset = kernel_data.blackbody.table_offset; - for (int i = 0; i < 81; ++i) { - float lambda = 380.0f + 5.0f * i; - float wlm = lambda * 1e-9; // Wavelength in meters - // N.B. spec_intens returns result in W/m^2 but it's a differential, - // needs to be scaled by dlambda! - float spec_intens = (c1 * powf(wlm, -5.0)) / (expf(c2 / (wlm * temperature)) -1.0f); - float Me = spec_intens * dlambda; + /* Retrieve colors from the lookup table */ + float lutval = t/lookuptablesizef; + float R = lookup_table_read(kg, lutval, blackbody_table_offset, lookuptablesize); + lutval = (t + 317.0f*1.0f)/lookuptablesizef; + float G = lookup_table_read(kg, lutval, blackbody_table_offset, lookuptablesize); + lutval = (t + 317.0f*2.0f)/lookuptablesizef; + float B = lookup_table_read(kg, lutval, blackbody_table_offset, lookuptablesize); - X += Me * cie_colour_match[i][0]; - Y += Me * cie_colour_match[i][1]; - Z += Me * cie_colour_match[i][2]; - } + R = powf(R, bb_table_ypower); + G = powf(G, bb_table_ypower); + B = powf(B, bb_table_ypower); - /* Convert to RGB */ - color_rgb = xyz_to_rgb(X, Y, Z); + /* Luminance */ + float l = linear_rgb_to_gray(make_float3(R, G, B)); - /* Clamp to zero if values are smaller */ - color_rgb = max(color_rgb, make_float3(0.0f, 0.0f, 0.0f)); - - /* Scale color by luminance */ - color_rgb /= Y; + color_rgb = make_float3(R, G, B); + color_rgb /= l; + } if (stack_valid(col_offset)) stack_store_float3(stack, col_offset, color_rgb); -- cgit v1.2.3 From ac4058a2117a24901f2462ba34d49e6714532148 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 17 Jun 2013 16:12:55 +0000 Subject: Cycles / Blackbody node: * Code cleanup to avoid duplicated table defines, moved them into kernel_types.h. --- intern/cycles/kernel/svm/svm_blackbody.h | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_blackbody.h b/intern/cycles/kernel/svm/svm_blackbody.h index eb8282cc842..46b2f910f74 100644 --- a/intern/cycles/kernel/svm/svm_blackbody.h +++ b/intern/cycles/kernel/svm/svm_blackbody.h @@ -36,31 +36,24 @@ CCL_NAMESPACE_BEGIN __device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset) { - /* ToDo: move those defines to kernel_types.h ? */ - float bb_drapper = 800.0f; - float bb_max_table_range = 12000.0f; - float bb_table_xpower = 1.5f; - float bb_table_ypower = 5.0f; - float bb_table_spacing = 2.0f; - /* Output */ float3 color_rgb = make_float3(0.0f, 0.0f, 0.0f); /* Input */ float temperature = stack_load_float(stack, temperature_offset); - if (temperature < bb_drapper) { + if (temperature < BB_DRAPPER) { /* just return very very dim red */ color_rgb = make_float3(1.0e-6f,0.0f,0.0f); } - else if (temperature <= bb_max_table_range) { + else if (temperature <= BB_MAX_TABLE_RANGE) { /* This is the overall size of the table (317*3+3) */ const int lookuptablesize = 954; const float lookuptablesizef = 954.0f; /* reconstruct a proper index for the table lookup, compared to OSL we don't look up two colors just one (the OSL-lerp is also automatically done for us by "lookup_table_read") */ - float t = powf ((temperature - bb_drapper) / bb_table_spacing, 1.0f/bb_table_xpower); + float t = powf ((temperature - BB_DRAPPER) / BB_TABLE_SPACING, 1.0f/BB_TABLE_XPOWER); int blackbody_table_offset = kernel_data.blackbody.table_offset; @@ -72,9 +65,9 @@ __device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack lutval = (t + 317.0f*2.0f)/lookuptablesizef; float B = lookup_table_read(kg, lutval, blackbody_table_offset, lookuptablesize); - R = powf(R, bb_table_ypower); - G = powf(G, bb_table_ypower); - B = powf(B, bb_table_ypower); + R = powf(R, BB_TABLE_YPOWER); + G = powf(G, BB_TABLE_YPOWER); + B = powf(B, BB_TABLE_YPOWER); /* Luminance */ float l = linear_rgb_to_gray(make_float3(R, G, B)); -- cgit v1.2.3 From 230f4e7ca2f4861c6bc828f5f0c618a7988607f0 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 20 Jun 2013 15:14:14 +0000 Subject: Cycles / GPU Image Textures: * On nvidia Kepler GPUs (sm_30 and above), there are now 145 byte images available, instead of 95. We could extend this to about 200 if needed. Could not test this, as I don't have a Kepler GPU, so feedback on this would be appreciated. Thanks to Brecht for review and some fixes. :) --- intern/cycles/kernel/svm/svm_image.h | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 57adaa863f1..037bfa2d9b9 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -229,6 +229,60 @@ __device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, u case 97: r = kernel_tex_image_interp(__tex_image_097, x, y); break; case 98: r = kernel_tex_image_interp(__tex_image_098, x, y); break; case 99: r = kernel_tex_image_interp(__tex_image_099, x, y); break; +#if defined(__KERNEL_CUDA__) && __CUDA_ARCH__ >= 300 + case 100: r = kernel_tex_image_interp(__tex_image_100, x, y); break; + case 101: r = kernel_tex_image_interp(__tex_image_101, x, y); break; + case 102: r = kernel_tex_image_interp(__tex_image_102, x, y); break; + case 103: r = kernel_tex_image_interp(__tex_image_103, x, y); break; + case 104: r = kernel_tex_image_interp(__tex_image_104, x, y); break; + case 105: r = kernel_tex_image_interp(__tex_image_105, x, y); break; + case 106: r = kernel_tex_image_interp(__tex_image_106, x, y); break; + case 107: r = kernel_tex_image_interp(__tex_image_107, x, y); break; + case 108: r = kernel_tex_image_interp(__tex_image_108, x, y); break; + case 109: r = kernel_tex_image_interp(__tex_image_109, x, y); break; + case 110: r = kernel_tex_image_interp(__tex_image_110, x, y); break; + case 111: r = kernel_tex_image_interp(__tex_image_111, x, y); break; + case 112: r = kernel_tex_image_interp(__tex_image_112, x, y); break; + case 113: r = kernel_tex_image_interp(__tex_image_113, x, y); break; + case 114: r = kernel_tex_image_interp(__tex_image_114, x, y); break; + case 115: r = kernel_tex_image_interp(__tex_image_115, x, y); break; + case 116: r = kernel_tex_image_interp(__tex_image_116, x, y); break; + case 117: r = kernel_tex_image_interp(__tex_image_117, x, y); break; + case 118: r = kernel_tex_image_interp(__tex_image_118, x, y); break; + case 119: r = kernel_tex_image_interp(__tex_image_119, x, y); break; + case 120: r = kernel_tex_image_interp(__tex_image_120, x, y); break; + case 121: r = kernel_tex_image_interp(__tex_image_121, x, y); break; + case 122: r = kernel_tex_image_interp(__tex_image_122, x, y); break; + case 123: r = kernel_tex_image_interp(__tex_image_123, x, y); break; + case 124: r = kernel_tex_image_interp(__tex_image_124, x, y); break; + case 125: r = kernel_tex_image_interp(__tex_image_125, x, y); break; + case 126: r = kernel_tex_image_interp(__tex_image_126, x, y); break; + case 127: r = kernel_tex_image_interp(__tex_image_127, x, y); break; + case 128: r = kernel_tex_image_interp(__tex_image_128, x, y); break; + case 129: r = kernel_tex_image_interp(__tex_image_129, x, y); break; + case 130: r = kernel_tex_image_interp(__tex_image_130, x, y); break; + case 131: r = kernel_tex_image_interp(__tex_image_131, x, y); break; + case 132: r = kernel_tex_image_interp(__tex_image_132, x, y); break; + case 133: r = kernel_tex_image_interp(__tex_image_133, x, y); break; + case 134: r = kernel_tex_image_interp(__tex_image_134, x, y); break; + case 135: r = kernel_tex_image_interp(__tex_image_135, x, y); break; + case 136: r = kernel_tex_image_interp(__tex_image_136, x, y); break; + case 137: r = kernel_tex_image_interp(__tex_image_137, x, y); break; + case 138: r = kernel_tex_image_interp(__tex_image_138, x, y); break; + case 139: r = kernel_tex_image_interp(__tex_image_139, x, y); break; + case 140: r = kernel_tex_image_interp(__tex_image_140, x, y); break; + case 141: r = kernel_tex_image_interp(__tex_image_141, x, y); break; + case 142: r = kernel_tex_image_interp(__tex_image_142, x, y); break; + case 143: r = kernel_tex_image_interp(__tex_image_143, x, y); break; + case 144: r = kernel_tex_image_interp(__tex_image_144, x, y); break; + case 145: r = kernel_tex_image_interp(__tex_image_145, x, y); break; + case 146: r = kernel_tex_image_interp(__tex_image_146, x, y); break; + case 147: r = kernel_tex_image_interp(__tex_image_147, x, y); break; + case 148: r = kernel_tex_image_interp(__tex_image_148, x, y); break; + case 149: r = kernel_tex_image_interp(__tex_image_149, x, y); break; + case 150: r = kernel_tex_image_interp(__tex_image_150, x, y); break; +#endif + default: kernel_assert(0); return make_float4(0.0f, 0.0f, 0.0f, 0.0f); -- cgit v1.2.3 From e4ef608020e3d77f05ec869e598dfa42d525da66 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 23 Jun 2013 17:51:08 +0000 Subject: Cycles / Vector Transform Node: * Implementation of Vector Transform Node into Cycles. * OSL backend is done, SVM needs the matrices still. --- intern/cycles/kernel/svm/svm.h | 4 +++ intern/cycles/kernel/svm/svm_types.h | 18 ++++++++++ intern/cycles/kernel/svm/svm_vector_transform.h | 44 +++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 intern/cycles/kernel/svm/svm_vector_transform.h (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 0a8896f3c44..20dba59d2d0 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -177,6 +177,7 @@ CCL_NAMESPACE_END #include "svm_voronoi.h" #include "svm_checker.h" #include "svm_brick.h" +#include "svm_vector_transform.h" CCL_NAMESPACE_BEGIN @@ -382,6 +383,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_VECTOR_MATH: svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset); break; + case NODE_VECTOR_TRANSFORM: + svm_node_vector_transform(kg, sd, stack, node); + break; case NODE_NORMAL: svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset); break; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index e4bc7efd272..9d9cb71f0f9 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -68,6 +68,7 @@ typedef enum NodeType { NODE_SET_BUMP, NODE_MATH, NODE_VECTOR_MATH, + NODE_VECTOR_TRANSFORM, NODE_MAPPING, NODE_TEX_COORD, NODE_TEX_COORD_BUMP_DX, @@ -226,6 +227,23 @@ typedef enum NodeVectorMath { NODE_VECTOR_MATH_NORMALIZE } NodeVectorMath; +typedef enum NodeVectorTransformType { + NODE_VECTOR_TRANSFORM_TYPE_VECTOR, + NODE_VECTOR_TRANSFORM_TYPE_POINT +} NodeVectorTransformType; + +typedef enum NodeVectorTransformConvertFrom { + NODE_VECTOR_TRANSFORM_CONVERT_FROM_WORLD, + NODE_VECTOR_TRANSFORM_CONVERT_FROM_OBJECT, + NODE_VECTOR_TRANSFORM_CONVERT_FROM_CAMERA +} NodeVectorTransformConvertFrom; + +typedef enum NodeVectorTransformConvertTo { + NODE_VECTOR_TRANSFORM_CONVERT_TO_WORLD, + NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT, + NODE_VECTOR_TRANSFORM_CONVERT_TO_CAMERA +} NodeVectorTransformConvertTo; + typedef enum NodeConvert { NODE_CONVERT_FV, NODE_CONVERT_FI, diff --git a/intern/cycles/kernel/svm/svm_vector_transform.h b/intern/cycles/kernel/svm/svm_vector_transform.h new file mode 100644 index 00000000000..b3268ba636e --- /dev/null +++ b/intern/cycles/kernel/svm/svm_vector_transform.h @@ -0,0 +1,44 @@ +/* + * Copyright 2013, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +CCL_NAMESPACE_BEGIN + +/* Vector Transform */ + +__device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) +{ + uint itype, ifrom, ito; + uint vector_in, vector_out; + + float3 out = make_float3(0.0f, 0.0f, 0.0f); + + decode_node_uchar4(node.y, &itype, &ifrom, &ito, NULL); + decode_node_uchar4(node.z, &vector_in, &vector_out, NULL, NULL); + + NodeVectorTransformType type = (NodeVectorTransformType)itype; + NodeVectorTransformConvertFrom from = (NodeVectorTransformConvertFrom)ifrom; + NodeVectorTransformConvertTo to = (NodeVectorTransformConvertTo)ito; + + float3 vec_in = stack_load_float3(stack, vector_in); + + if(stack_valid(vector_out)) + stack_store_float3(stack, vector_out, out); +} + +CCL_NAMESPACE_END + -- cgit v1.2.3 From 7f1005cd6a97f9ae44ee2b2243da66b91bffb7a1 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 1 Jul 2013 22:56:56 +0000 Subject: Cycles / Vector Transform Node: * Implementation of the node for SVM. This covers all possible transformations: World <> Object <> Camera space. As far as I can tell, it also works fine with Motion Blur enabled. ToDo: * SVM differs from OSL, when the node is used on the world. --- intern/cycles/kernel/svm/svm_vector_transform.h | 68 +++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_vector_transform.h b/intern/cycles/kernel/svm/svm_vector_transform.h index b3268ba636e..aa2c30a4831 100644 --- a/intern/cycles/kernel/svm/svm_vector_transform.h +++ b/intern/cycles/kernel/svm/svm_vector_transform.h @@ -18,6 +18,11 @@ CCL_NAMESPACE_BEGIN +/* ToDo +* if (object != ~0) null check? +* differs from OSL when used for the world +*/ + /* Vector Transform */ __device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) @@ -25,19 +30,72 @@ __device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float uint itype, ifrom, ito; uint vector_in, vector_out; - float3 out = make_float3(0.0f, 0.0f, 0.0f); - decode_node_uchar4(node.y, &itype, &ifrom, &ito, NULL); decode_node_uchar4(node.z, &vector_in, &vector_out, NULL, NULL); + float3 in = stack_load_float3(stack, vector_in); + NodeVectorTransformType type = (NodeVectorTransformType)itype; NodeVectorTransformConvertFrom from = (NodeVectorTransformConvertFrom)ifrom; NodeVectorTransformConvertTo to = (NodeVectorTransformConvertTo)ito; - float3 vec_in = stack_load_float3(stack, vector_in); + Transform tfm; + + /* From world */ + if(from == NODE_VECTOR_TRANSFORM_CONVERT_FROM_WORLD) { + if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_CAMERA) { + tfm = kernel_data.cam.worldtocamera; + if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) + in = transform_direction(&tfm, in); + else + in = transform_point(&tfm, in); + } + else if (to == NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT) { + if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) + object_inverse_dir_transform(kg, sd, &in); + else + object_inverse_position_transform(kg, sd, &in); + } + } + + /* From camera */ + else if (from == NODE_VECTOR_TRANSFORM_CONVERT_FROM_CAMERA) { + if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT) { + tfm = kernel_data.cam.cameratoworld; + if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) + in = transform_direction(&tfm, in); + else + in = transform_point(&tfm, in); + } + if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT) { + if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) + object_inverse_dir_transform(kg, sd, &in); + else + object_inverse_position_transform(kg, sd, &in); + } + } + + /* From object */ + else if(from == NODE_VECTOR_TRANSFORM_CONVERT_FROM_OBJECT) { + if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_TO_CAMERA) { + if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) + object_dir_transform(kg, sd, &in); + else + object_position_transform(kg, sd, &in); + } + if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_CAMERA) { + tfm = kernel_data.cam.worldtocamera; + if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) + in = transform_direction(&tfm, in); + else + in = transform_point(&tfm, in); + } + } - if(stack_valid(vector_out)) - stack_store_float3(stack, vector_out, out); + /* Output */ + if(stack_valid(vector_out)) { + stack_store_float3(stack, vector_out, in); + } } CCL_NAMESPACE_END -- cgit v1.2.3 From 3a6e382d4aef6ad4bcba8a482d6d5fb5f96a6618 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 1 Jul 2013 23:17:24 +0000 Subject: Cycles / Vector Transform Node: * After some more thinking, solved the remaining ToDos. :) * Added is_object check to check if we have a valid object. * If we operate on the world, and try to convert from/to object space, we now assume world space instead, same as OSL. --- intern/cycles/kernel/svm/svm_vector_transform.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm_vector_transform.h b/intern/cycles/kernel/svm/svm_vector_transform.h index aa2c30a4831..8b5369ab626 100644 --- a/intern/cycles/kernel/svm/svm_vector_transform.h +++ b/intern/cycles/kernel/svm/svm_vector_transform.h @@ -18,11 +18,6 @@ CCL_NAMESPACE_BEGIN -/* ToDo -* if (object != ~0) null check? -* differs from OSL when used for the world -*/ - /* Vector Transform */ __device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) @@ -40,6 +35,7 @@ __device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float NodeVectorTransformConvertTo to = (NodeVectorTransformConvertTo)ito; Transform tfm; + int is_object = (sd->object != ~0); /* From world */ if(from == NODE_VECTOR_TRANSFORM_CONVERT_FROM_WORLD) { @@ -50,7 +46,7 @@ __device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float else in = transform_point(&tfm, in); } - else if (to == NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT) { + else if (to == NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT && is_object) { if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) object_inverse_dir_transform(kg, sd, &in); else @@ -67,7 +63,7 @@ __device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float else in = transform_point(&tfm, in); } - if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT) { + if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT && is_object) { if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) object_inverse_dir_transform(kg, sd, &in); else @@ -77,7 +73,7 @@ __device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float /* From object */ else if(from == NODE_VECTOR_TRANSFORM_CONVERT_FROM_OBJECT) { - if(to == NODE_VECTOR_TRANSFORM_CONVERT_TO_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_TO_CAMERA) { + if((to == NODE_VECTOR_TRANSFORM_CONVERT_TO_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_TO_CAMERA) && is_object) { if(type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR) object_dir_transform(kg, sd, &in); else -- cgit v1.2.3 From 285ef99931447646b20ec968ec87f7c68939a104 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 3 Jul 2013 23:46:56 +0000 Subject: Cycles: * Added 2 new nodes to combine and separate HSV colors. Screenshot: http://www.pasteall.org/pic/show.php?id=54828 --- intern/cycles/kernel/svm/svm.h | 7 ++++ intern/cycles/kernel/svm/svm_sepcomb_hsv.h | 56 ++++++++++++++++++++++++++++++ intern/cycles/kernel/svm/svm_types.h | 2 ++ 3 files changed, 65 insertions(+) create mode 100644 intern/cycles/kernel/svm/svm_sepcomb_hsv.h (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 20dba59d2d0..5380bdad1ae 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -170,6 +170,7 @@ CCL_NAMESPACE_END #include "svm_mix.h" #include "svm_ramp.h" #include "svm_sepcomb_rgb.h" +#include "svm_sepcomb_hsv.h" #include "svm_musgrave.h" #include "svm_sky.h" #include "svm_tex_coord.h" @@ -340,6 +341,12 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_COMBINE_RGB: svm_node_combine_rgb(sd, stack, node.y, node.z, node.w); break; + case NODE_SEPARATE_HSV: + svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); + break; + case NODE_COMBINE_HSV: + svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); + break; case NODE_HSV: svm_node_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); break; diff --git a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h new file mode 100644 index 00000000000..d349d0efe87 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h @@ -0,0 +1,56 @@ +/* + * Copyright 2013, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +CCL_NAMESPACE_BEGIN + +__device void svm_node_combine_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint hue_in, uint saturation_in, uint value_in, int *offset) +{ + uint4 node1 = read_node(kg, offset); + uint color_out = node1.y; + + float hue = stack_load_float(stack, hue_in); + float saturation = stack_load_float(stack, saturation_in); + float value = stack_load_float(stack, value_in); + + /* Combine, and convert back to RGB */ + float3 color = hsv_to_rgb(make_float3(hue, saturation, value)); + + if (stack_valid(color_out)) + stack_store_float3(stack, color_out, color); +} + +__device void svm_node_separate_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint color_in, uint hue_out, uint saturation_out, int *offset) +{ + uint4 node1 = read_node(kg, offset); + uint value_out = node1.y; + + float3 color = stack_load_float3(stack, color_in); + + /* Convert to HSV */ + color = rgb_to_hsv(color); + + if (stack_valid(hue_out)) + stack_store_float(stack, hue_out, color.x); + if (stack_valid(saturation_out)) + stack_store_float(stack, saturation_out, color.y); + if (stack_valid(value_out)) + stack_store_float(stack, value_out, color.z); +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 9d9cb71f0f9..6c47fbc14be 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -83,6 +83,8 @@ typedef enum NodeType { NODE_CLOSURE_VOLUME, NODE_SEPARATE_RGB, NODE_COMBINE_RGB, + NODE_SEPARATE_HSV, + NODE_COMBINE_HSV, NODE_HSV, NODE_CAMERA, NODE_INVERT, -- cgit v1.2.3