From 4fd273648767a736f79acd3edc3d7f332129b46f Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 2 Dec 2011 16:57:37 +0000 Subject: HSV Color Node for Cycles ......................... note, the OSL code has a problem. In the original node the input and output nodes have the same name (Color). So this will be fixed here once Brecht come up with a nice autorenaming (or we do a doversion patch) for that. --- intern/cycles/kernel/CMakeLists.txt | 1 + intern/cycles/kernel/osl/nodes/CMakeLists.txt | 1 + intern/cycles/kernel/osl/nodes/node_color.h | 75 +++++++++++++++ intern/cycles/kernel/osl/nodes/node_hsv.osl | 42 +++++++++ intern/cycles/kernel/osl/nodes/node_mix.osl | 74 +-------------- intern/cycles/kernel/svm/svm.h | 4 + intern/cycles/kernel/svm/svm_hsv.h | 131 ++++++++++++++++++++++++++ intern/cycles/kernel/svm/svm_mix.h | 76 +-------------- intern/cycles/kernel/svm/svm_types.h | 3 +- 9 files changed, 259 insertions(+), 148 deletions(-) create mode 100644 intern/cycles/kernel/osl/nodes/node_hsv.osl create mode 100644 intern/cycles/kernel/svm/svm_hsv.h (limited to 'intern/cycles/kernel') diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index abe81103d80..a09fe1d726e 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -60,6 +60,7 @@ set(SRC_SVM_HEADERS svm/svm_fresnel.h svm/svm_geometry.h svm/svm_gradient.h + svm/svm_hsv.h svm/svm_image.h svm/svm_light_path.h svm/svm_magic.h diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt index 34729145f28..50e763a6b83 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRC_OSL node_geometry.osl node_glass_bsdf.osl node_glossy_bsdf.osl + node_hsv.osl node_image_texture.osl node_light_path.osl node_magic_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_color.h b/intern/cycles/kernel/osl/nodes/node_color.h index b92973d1dfe..37d092eae78 100644 --- a/intern/cycles/kernel/osl/nodes/node_color.h +++ b/intern/cycles/kernel/osl/nodes/node_color.h @@ -48,3 +48,78 @@ color color_scene_linear_to_srgb(color c) color_scene_linear_to_srgb(c[2])); } +/* Color Operations */ + +color rgb_to_hsv(color rgb) +{ + float cmax, cmin, h, s, v, cdelta; + color c; + + cmax = max(rgb[0], max(rgb[1], rgb[2])); + cmin = min(rgb[0], min(rgb[1], rgb[2])); + cdelta = cmax - cmin; + + v = cmax; + + if(cmax != 0.0) { + s = cdelta/cmax; + } + else { + s = 0.0; + h = 0.0; + } + + if(s == 0.0) { + h = 0.0; + } + else { + c = (color(cmax, cmax, cmax) - rgb)/cdelta; + + if(rgb[0] == cmax) h = c[2] - c[1]; + else if(rgb[1] == cmax) h = 2.0 + c[0] - c[2]; + else h = 4.0 + c[1] - c[0]; + + h /= 6.0; + + if(h < 0.0) + h += 1.0; + } + + return color(h, s, v); +} + +color hsv_to_rgb(color hsv) +{ + float i, f, p, q, t, h, s, v; + color rgb; + + h = hsv[0]; + s = hsv[1]; + v = hsv[2]; + + if(s==0.0) { + rgb = color(v, v, v); + } + else { + if(h==1.0) + h = 0.0; + + h *= 6.0; + i = floor(h); + f = h - i; + rgb = color(f, f, f); + p = v*(1.0-s); + q = v*(1.0-(s*f)); + t = v*(1.0-(s*(1.0-f))); + + if(i == 0.0) rgb = color(v, t, p); + else if(i == 1.0) rgb = color(q, v, p); + else if(i == 2.0) rgb = color(p, v, t); + else if(i == 3.0) rgb = color(p, q, v); + else if(i == 4.0) rgb = color(t, p, v); + else rgb = color(v, p, q); + } + + return rgb; +} + diff --git a/intern/cycles/kernel/osl/nodes/node_hsv.osl b/intern/cycles/kernel/osl/nodes/node_hsv.osl new file mode 100644 index 00000000000..da776c8909e --- /dev/null +++ b/intern/cycles/kernel/osl/nodes/node_hsv.osl @@ -0,0 +1,42 @@ +/* + * Copyright 2011, 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. + */ + +#include "stdosl.h" +#include "node_color.h" + +shader node_hsv( + float Hue = 0.5, + float Saturation = 1.0, + float Value = 1.0, + float Fac = 0.5, + color ColorIn = color(0.0, 0.0, 0.0), + output color ColorOut = color(0.0, 0.0, 0.0)) +{ + float t = clamp(Fac, 0.0, 1.0); + color Color = rgb_to_hsv(ColorIn); + + Color[0] += Hue - 0.5; + Color[0] = fmod(Color[0], 1.0); + Color[1] *= Saturation; + Color[2] *= Value; + + Color = hsv_to_rgb(Color); + + ColorOut = mix(Color, ColorIn, t); +} + diff --git a/intern/cycles/kernel/osl/nodes/node_mix.osl b/intern/cycles/kernel/osl/nodes/node_mix.osl index 582aa7b3c60..8a462c995d3 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix.osl +++ b/intern/cycles/kernel/osl/nodes/node_mix.osl @@ -17,79 +17,7 @@ */ #include "stdosl.h" - -color rgb_to_hsv(color rgb) -{ - float cmax, cmin, h, s, v, cdelta; - color c; - - cmax = max(rgb[0], max(rgb[1], rgb[2])); - cmin = min(rgb[0], min(rgb[1], rgb[2])); - cdelta = cmax - cmin; - - v = cmax; - - if(cmax != 0.0) { - s = cdelta/cmax; - } - else { - s = 0.0; - h = 0.0; - } - - if(s == 0.0) { - h = 0.0; - } - else { - c = (color(cmax, cmax, cmax) - rgb)/cdelta; - - if(rgb[0] == cmax) h = c[2] - c[1]; - else if(rgb[1] == cmax) h = 2.0 + c[0] - c[2]; - else h = 4.0 + c[1] - c[0]; - - h /= 6.0; - - if(h < 0.0) - h += 1.0; - } - - return color(h, s, v); -} - -color hsv_to_rgb(color hsv) -{ - float i, f, p, q, t, h, s, v; - color rgb; - - h = hsv[0]; - s = hsv[1]; - v = hsv[2]; - - if(s==0.0) { - rgb = color(v, v, v); - } - else { - if(h==1.0) - h = 0.0; - - h *= 6.0; - i = floor(h); - f = h - i; - rgb = color(f, f, f); - p = v*(1.0-s); - q = v*(1.0-(s*f)); - t = v*(1.0-(s*(1.0-f))); - - if(i == 0.0) rgb = color(v, t, p); - else if(i == 1.0) rgb = color(q, v, p); - else if(i == 2.0) rgb = color(p, v, t); - else if(i == 3.0) rgb = color(p, q, v); - else if(i == 4.0) rgb = color(t, p, v); - else rgb = color(v, p, q); - } - - return rgb; -} +#include "node_color.h" color node_mix_blend(float t, color col1, color col2) { diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 3073aefc272..004875b0de5 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -127,6 +127,7 @@ CCL_NAMESPACE_END #include "svm_displace.h" #include "svm_fresnel.h" #include "svm_geometry.h" +#include "svm_hsv.h" #include "svm_image.h" #include "svm_light_path.h" #include "svm_magic.h" @@ -261,6 +262,9 @@ __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_HSV: + svm_node_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); + break; case NODE_ATTR: svm_node_attr(kg, sd, stack, node); break; diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h new file mode 100644 index 00000000000..fc927f297f5 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_hsv.h @@ -0,0 +1,131 @@ +/* + * Copyright 2011, 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. + */ + +#ifndef __SVM_HSV_H__ +#define __SVM_HSV_H__ + +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 = floor(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 */ + uint4 node1 = read_node(kg, offset); + + float fac = stack_load_float(stack, fac_offset); + float3 in_color = stack_load_float3(stack, in_color_offset); + float3 color = in_color; + + float hue = stack_load_float(stack, node1.y); + float sat = stack_load_float(stack, node1.z); + float val = stack_load_float(stack, node1.w); + + color = rgb_to_hsv(color); + + color.x += hue - 0.5f; + color.x = fmod(color.x, 1.0f); + color.y *= sat; + color.z *= val; + + color = hsv_to_rgb(color); + + color.x = fac*color.x + (1.0f - fac)*in_color.x; + color.y = fac*color.y + (1.0f - fac)*in_color.y; + color.z = fac*color.z + (1.0f - fac)*in_color.z; + + if (stack_valid(out_color_offset)) + stack_store_float3(stack, out_color_offset, color); +} + +CCL_NAMESPACE_END + +#endif /* __SVM_HSV_H__ */ + diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h index c9e6cdf43b9..e2274a2e691 100644 --- a/intern/cycles/kernel/svm/svm_mix.h +++ b/intern/cycles/kernel/svm/svm_mix.h @@ -16,81 +16,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -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; +#include "svm_hsv.h" - 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 = floor(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; -} +CCL_NAMESPACE_BEGIN __device float3 svm_lerp(const float3 a, const float3 b, float t) { diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index cde5e662fa7..53bba644e41 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -81,7 +81,8 @@ typedef enum NodeType { NODE_LAYER_WEIGHT = 4800, NODE_CLOSURE_VOLUME = 4900, NODE_SEPARATE_RGB = 5000, - NODE_COMBINE_RGB = 5100 + NODE_COMBINE_RGB = 5100, + NODE_HSV = 5200 } NodeType; typedef enum NodeAttributeType { -- cgit v1.2.3