diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index ee6a0887d45..a1aeceeb216 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -250,6 +250,14 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()]; node = vmath; } + else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) { + BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); + VectorTransformNode *vtransform = new VectorTransformNode(); + vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.type()]; + vtransform->convert_from = VectorTransformNode::convert_from_enum[b_vector_transform_node.convert_from()]; + vtransform->convert_to = VectorTransformNode::convert_to_enum[b_vector_transform_node.convert_to()]; + node = vtransform; + } else if (b_node.is_a(&RNA_ShaderNodeNormal)) { BL::Node::outputs_iterator out_it; b_node.outputs.begin(out_it); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 753d32f5182..eda7fef67ef 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -105,6 +105,7 @@ set(SRC_SVM_HEADERS svm/svm_texture.h svm/svm_types.h svm/svm_value.h + svm/svm_vector_transform.h svm/svm_voronoi.h svm/svm_wave.h ) diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index f8454d3ad40..db20dd43ca7 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -64,6 +64,7 @@ set(SRC_OSL node_value.osl node_vector_curves.osl node_vector_math.osl + node_vector_transform.osl node_velvet_bsdf.osl node_voronoi_texture.osl node_ward_bsdf.osl diff --git a/intern/cycles/kernel/shaders/node_vector_transform.osl b/intern/cycles/kernel/shaders/node_vector_transform.osl new file mode 100644 index 00000000000..ae0cb1c7a49 --- /dev/null +++ b/intern/cycles/kernel/shaders/node_vector_transform.osl @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#include "stdosl.h" + +shader node_vector_transform( + string type = "Vector", + string convert_from = "World", + string convert_to = "Object", + vector VectorIn = vector(0.0, 0.0, 0.0), + output vector VectorOut = vector(0.0, 0.0, 0.0)) +{ + /* OSL uses lower case variable names here */ + string from = "world"; + string to = "object"; + + if (convert_from == "Object") + from = "object"; + else if (convert_from == "Camera") + from = "camera"; + + if (convert_to == "World") + to = "world"; + else if (convert_to == "Camera") + to = "camera"; + + if (type == "Vector") { + VectorOut = transform(from, to, VectorIn); + } + else if (type == "Point") { + point Point = point(VectorIn[0], VectorIn[1], VectorIn[2]); + VectorOut = transform(from, to, Point); + } +} + 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 + diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index cd893652dac..f215d9e75be 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3153,6 +3153,76 @@ void VectorMathNode::compile(OSLCompiler& compiler) compiler.add(this, "node_vector_math"); } +/* VectorTransform */ + +VectorTransformNode::VectorTransformNode() +: ShaderNode("vector_transform") +{ + type = ustring("Vector"); + convert_from = ustring("World"); + convert_to = ustring("Object"); + + add_input("Vector", SHADER_SOCKET_VECTOR); + add_output("Vector", SHADER_SOCKET_VECTOR); +} + +static ShaderEnum vector_transform_type_init() +{ + ShaderEnum enm; + + enm.insert("Vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR); + enm.insert("Point", NODE_VECTOR_TRANSFORM_TYPE_POINT); + + return enm; +} + +static ShaderEnum vector_transform_convert_from_init() +{ + ShaderEnum enm; + + enm.insert("World", NODE_VECTOR_TRANSFORM_CONVERT_FROM_WORLD); + enm.insert("Object", NODE_VECTOR_TRANSFORM_CONVERT_FROM_OBJECT); + enm.insert("Camera", NODE_VECTOR_TRANSFORM_CONVERT_FROM_CAMERA); + + return enm; +} + +static ShaderEnum vector_transform_convert_to_init() +{ + ShaderEnum enm; + + enm.insert("World", NODE_VECTOR_TRANSFORM_CONVERT_TO_WORLD); + enm.insert("Object", NODE_VECTOR_TRANSFORM_CONVERT_TO_OBJECT); + enm.insert("Camera", NODE_VECTOR_TRANSFORM_CONVERT_TO_CAMERA); + + return enm; +} + +ShaderEnum VectorTransformNode::type_enum = vector_transform_type_init(); +ShaderEnum VectorTransformNode::convert_from_enum = vector_transform_convert_from_init(); +ShaderEnum VectorTransformNode::convert_to_enum = vector_transform_convert_to_init(); + +void VectorTransformNode::compile(SVMCompiler& compiler) +{ + ShaderInput *vector_in = input("Vector"); + ShaderOutput *vector_out = output("Vector"); + + compiler.stack_assign(vector_in); + compiler.stack_assign(vector_out); + + compiler.add_node(NODE_VECTOR_TRANSFORM, + compiler.encode_uchar4(type_enum[type], convert_from_enum[convert_from], convert_to_enum[convert_to]), + compiler.encode_uchar4(vector_in->stack_offset, vector_out->stack_offset)); +} + +void VectorTransformNode::compile(OSLCompiler& compiler) +{ + compiler.parameter("type", type); + compiler.parameter("convert_from", convert_from); + compiler.parameter("convert_to", convert_to); + compiler.add(this, "node_vector_transform"); +} + /* BumpNode */ BumpNode::BumpNode() diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 8266e9dec88..72904657390 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -494,6 +494,19 @@ public: static ShaderEnum type_enum; }; +class VectorTransformNode : public ShaderNode { +public: + SHADER_NODE_CLASS(VectorTransformNode) + + ustring type; + ustring convert_from; + ustring convert_to; + + static ShaderEnum type_enum; + static ShaderEnum convert_from_enum; + static ShaderEnum convert_to_enum; +}; + class BumpNode : public ShaderNode { public: SHADER_NODE_CLASS(BumpNode)