diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 22 | ||||
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_mapping.osl | 61 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_mapping.h | 28 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_mapping_util.h | 39 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 8 | ||||
-rw-r--r-- | intern/cycles/render/constant_fold.cpp | 17 | ||||
-rw-r--r-- | intern/cycles/render/constant_fold.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 48 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 5 | ||||
-rw-r--r-- | intern/cycles/util/util_transform.h | 26 |
12 files changed, 218 insertions, 44 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index e81336cd692..f5a76002eb6 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -208,24 +208,6 @@ static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping &b_mapping) mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z(); } -static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping &b_mapping) -{ - if (!b_mapping) - return; - - mapping->translation = get_float3(b_mapping.translation()); - mapping->rotation = get_float3(b_mapping.rotation()); - mapping->scale = get_float3(b_mapping.scale()); - mapping->type = (TextureMapping::Type)b_mapping.vector_type(); - - mapping->use_minmax = b_mapping.use_min() || b_mapping.use_max(); - - if (b_mapping.use_min()) - mapping->min = get_float3(b_mapping.min()); - if (b_mapping.use_max()) - mapping->max = get_float3(b_mapping.max()); -} - static ShaderNode *add_node(Scene *scene, BL::RenderEngine &b_engine, BL::BlendData &b_data, @@ -357,9 +339,7 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeMapping)) { BL::ShaderNodeMapping b_mapping_node(b_node); MappingNode *mapping = new MappingNode(); - - get_tex_mapping(&mapping->tex_mapping, b_mapping_node); - + mapping->type = (NodeMappingType)b_mapping_node.vector_type(); node = mapping; } else if (b_node.is_a(&RNA_ShaderNodeFresnel)) { diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 89ecdc6b7ac..04df49aa058 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -201,6 +201,7 @@ set(SRC_SVM_HEADERS svm/svm_magic.h svm/svm_map_range.h svm/svm_mapping.h + svm/svm_mapping_util.h svm/svm_math.h svm/svm_math_util.h svm/svm_mix.h diff --git a/intern/cycles/kernel/shaders/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl index f5cc2d1c5dd..8eed0ae9c48 100644 --- a/intern/cycles/kernel/shaders/node_mapping.osl +++ b/intern/cycles/kernel/shaders/node_mapping.osl @@ -16,17 +16,58 @@ #include "stdosl.h" -shader node_mapping(matrix Matrix = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - point mapping_min = point(0.0, 0.0, 0.0), - point mapping_max = point(0.0, 0.0, 0.0), - int use_minmax = 0, - point VectorIn = point(0.0, 0.0, 0.0), - output point VectorOut = point(0.0, 0.0, 0.0)) +point safe_divide(point a, point b) +{ + return point((b[0] != 0.0) ? a[0] / b[0] : 0.0, + (b[1] != 0.0) ? a[1] / b[1] : 0.0, + (b[2] != 0.0) ? a[2] / b[2] : 0.0); +} + +matrix euler_to_mat(point euler) { - point p = transform(Matrix, VectorIn); + float cx = cos(euler[0]); + float cy = cos(euler[1]); + float cz = cos(euler[2]); + float sx = sin(euler[0]); + float sy = sin(euler[1]); + float sz = sin(euler[2]); + + matrix mat = matrix(1.0); + mat[0][0] = cy * cz; + mat[0][1] = cy * sz; + mat[0][2] = -sy; - if (use_minmax) - p = min(max(mapping_min, p), mapping_max); + mat[1][0] = sy * sx * cz - cx * sz; + mat[1][1] = sy * sx * sz + cx * cz; + mat[1][2] = cy * sx; - VectorOut = p; + mat[2][0] = sy * cx * cz + sx * sz; + mat[2][1] = sy * cx * sz - sx * cz; + mat[2][2] = cy * cx; + return mat; +} + +shader node_mapping(string type = "point", + point VectorIn = point(0.0, 0.0, 0.0), + point Location = point(0.0, 0.0, 0.0), + point Rotation = point(0.0, 0.0, 0.0), + point Scale = point(1.0, 1.0, 1.0), + output point VectorOut = point(0.0, 0.0, 0.0)) +{ + if (type == "point") { + VectorOut = transform(euler_to_mat(Rotation), (VectorIn * Scale)) + Location; + } + else if (type == "texture") { + VectorOut = safe_divide(transform(transpose(euler_to_mat(Rotation)), (VectorIn - Location)), + Scale); + } + else if (type == "vector") { + VectorOut = transform(euler_to_mat(Rotation), (VectorIn * Scale)); + } + else if (type == "normal") { + VectorOut = normalize(transform(euler_to_mat(Rotation), safe_divide(VectorIn, Scale))); + } + else { + warning("%s", "Unknown Mapping vector type!"); + } } diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 95954aaf99e..ce651a1b5ff 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -162,6 +162,7 @@ CCL_NAMESPACE_END #include "kernel/svm/svm_color_util.h" #include "kernel/svm/svm_math_util.h" +#include "kernel/svm/svm_mapping_util.h" #include "kernel/svm/svm_attribute.h" #include "kernel/svm/svm_gradient.h" @@ -405,8 +406,11 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, #endif /* NODES_GROUP(NODE_GROUP_LEVEL_1) */ #if NODES_GROUP(NODE_GROUP_LEVEL_2) + case NODE_TEXTURE_MAPPING: + svm_node_texture_mapping(kg, sd, stack, node.y, node.z, &offset); + break; case NODE_MAPPING: - svm_node_mapping(kg, sd, stack, node.y, node.z, &offset); + svm_node_mapping(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_MIN_MAX: svm_node_min_max(kg, sd, stack, node.y, node.z, &offset); diff --git a/intern/cycles/kernel/svm/svm_mapping.h b/intern/cycles/kernel/svm/svm_mapping.h index 998a29912d4..6e19c859e19 100644 --- a/intern/cycles/kernel/svm/svm_mapping.h +++ b/intern/cycles/kernel/svm/svm_mapping.h @@ -18,7 +18,33 @@ CCL_NAMESPACE_BEGIN /* Mapping Node */ -ccl_device void svm_node_mapping( +ccl_device void svm_node_mapping(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint type, + uint inputs_stack_offsets, + uint result_stack_offset, + int *offset) +{ + uint vector_stack_offset, location_stack_offset, rotation_stack_offset, scale_stack_offset; + svm_unpack_node_uchar4(inputs_stack_offsets, + &vector_stack_offset, + &location_stack_offset, + &rotation_stack_offset, + &scale_stack_offset); + + float3 vector = stack_load_float3(stack, vector_stack_offset); + float3 location = stack_load_float3(stack, location_stack_offset); + float3 rotation = stack_load_float3(stack, rotation_stack_offset); + float3 scale = stack_load_float3(stack, scale_stack_offset); + + float3 result = svm_mapping((NodeMappingType)type, vector, location, rotation, scale); + stack_store_float3(stack, result_stack_offset, result); +} + +/* Texture Mapping */ + +ccl_device void svm_node_texture_mapping( KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset) { float3 v = stack_load_float3(stack, vec_offset); diff --git a/intern/cycles/kernel/svm/svm_mapping_util.h b/intern/cycles/kernel/svm/svm_mapping_util.h new file mode 100644 index 00000000000..ec2c84e0791 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_mapping_util.h @@ -0,0 +1,39 @@ +/* + * Copyright 2011-2014 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +CCL_NAMESPACE_BEGIN + +ccl_device float3 +svm_mapping(NodeMappingType type, float3 vector, float3 location, float3 rotation, float3 scale) +{ + Transform rotationTransform = euler_to_transform(rotation); + switch (type) { + case NODE_MAPPING_TYPE_POINT: + return transform_direction(&rotationTransform, (vector * scale)) + location; + case NODE_MAPPING_TYPE_TEXTURE: + return safe_divide_float3_float3( + transform_direction_transposed(&rotationTransform, (vector - location)), scale); + case NODE_MAPPING_TYPE_VECTOR: + return transform_direction(&rotationTransform, (vector * scale)); + case NODE_MAPPING_TYPE_NORMAL: + return safe_normalize( + transform_direction(&rotationTransform, safe_divide_float3_float3(vector, scale))); + default: + return make_float3(0.0f, 0.0f, 0.0f); + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index a3caa1ab68d..de7114566b3 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -140,6 +140,7 @@ typedef enum ShaderNodeType { NODE_IES, NODE_MAP_RANGE, NODE_CLAMP, + NODE_TEXTURE_MAPPING, NODE_TEX_WHITE_NOISE, } ShaderNodeType; @@ -299,6 +300,13 @@ typedef enum NodeVectorMathType { NODE_VECTOR_MATH_MAXIMUM, } NodeVectorMathType; +typedef enum NodeMappingType { + NODE_MAPPING_TYPE_POINT, + NODE_MAPPING_TYPE_TEXTURE, + NODE_MAPPING_TYPE_VECTOR, + NODE_MAPPING_TYPE_NORMAL +} NodeMappingType; + typedef enum NodeVectorTransformType { NODE_VECTOR_TRANSFORM_TYPE_VECTOR, NODE_VECTOR_TRANSFORM_TYPE_POINT, diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp index 851d4b71df8..f3809ee8d80 100644 --- a/intern/cycles/render/constant_fold.cpp +++ b/intern/cycles/render/constant_fold.cpp @@ -429,4 +429,21 @@ void ConstantFolder::fold_vector_math(NodeVectorMathType type) const } } +void ConstantFolder::fold_mapping(NodeMappingType type) const +{ + ShaderInput *vector_in = node->input("Vector"); + ShaderInput *location_in = node->input("Location"); + ShaderInput *rotation_in = node->input("Rotation"); + ShaderInput *scale_in = node->input("Scale"); + + if (is_zero(scale_in)) { + make_zero(); + } + else if ((is_zero(location_in) || type == NODE_MAPPING_TYPE_VECTOR || + type == NODE_MAPPING_TYPE_NORMAL) && + is_zero(rotation_in) && is_one(scale_in)) { + try_bypass_or_make_constant(vector_in); + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/constant_fold.h b/intern/cycles/render/constant_fold.h index 881636a9fe1..7f622488a88 100644 --- a/intern/cycles/render/constant_fold.h +++ b/intern/cycles/render/constant_fold.h @@ -66,6 +66,7 @@ class ConstantFolder { void fold_mix(NodeMix type, bool clamp) const; void fold_math(NodeMathType type) const; void fold_vector_math(NodeVectorMathType type) const; + void fold_mapping(NodeMappingType type) const; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 24aa9589220..31dc986a4d1 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -25,6 +25,7 @@ #include "kernel/svm/svm_color_util.h" #include "kernel/svm/svm_ramp_util.h" #include "kernel/svm/svm_math_util.h" +#include "kernel/svm/svm_mapping_util.h" #include "render/osl.h" #include "render/constant_fold.h" @@ -149,7 +150,7 @@ bool TextureMapping::skip() void TextureMapping::compile(SVMCompiler &compiler, int offset_in, int offset_out) { - compiler.add_node(NODE_MAPPING, offset_in, offset_out); + compiler.add_node(NODE_TEXTURE_MAPPING, offset_in, offset_out); Transform tfm = compute_transform(); compiler.add_node(tfm.x); @@ -1727,9 +1728,18 @@ NODE_DEFINE(MappingNode) { NodeType *type = NodeType::add("mapping", create, NodeType::SHADER); - TEXTURE_MAPPING_DEFINE(MappingNode); + static NodeEnum type_enum; + type_enum.insert("point", NODE_MAPPING_TYPE_POINT); + type_enum.insert("texture", NODE_MAPPING_TYPE_TEXTURE); + type_enum.insert("vector", NODE_MAPPING_TYPE_VECTOR); + type_enum.insert("normal", NODE_MAPPING_TYPE_NORMAL); + SOCKET_ENUM(type, "Type", type_enum, NODE_MAPPING_TYPE_POINT); SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f)); + SOCKET_IN_POINT(location, "Location", make_float3(0.0f, 0.0f, 0.0f)); + SOCKET_IN_POINT(rotation, "Rotation", make_float3(0.0f, 0.0f, 0.0f)); + SOCKET_IN_POINT(scale, "Scale", make_float3(1.0f, 1.0f, 1.0f)); + SOCKET_OUT_POINT(vector, "Vector"); return type; @@ -1739,22 +1749,42 @@ MappingNode::MappingNode() : ShaderNode(node_type) { } +void MappingNode::constant_fold(const ConstantFolder &folder) +{ + if (folder.all_inputs_constant()) { + float3 result = svm_mapping((NodeMappingType)type, vector, location, rotation, scale); + folder.make_constant(result); + } + else { + folder.fold_mapping((NodeMappingType)type); + } +} + void MappingNode::compile(SVMCompiler &compiler) { ShaderInput *vector_in = input("Vector"); + ShaderInput *location_in = input("Location"); + ShaderInput *rotation_in = input("Rotation"); + ShaderInput *scale_in = input("Scale"); ShaderOutput *vector_out = output("Vector"); - tex_mapping.compile( - compiler, compiler.stack_assign(vector_in), compiler.stack_assign(vector_out)); + int vector_stack_offset = compiler.stack_assign(vector_in); + int location_stack_offset = compiler.stack_assign(location_in); + int rotation_stack_offset = compiler.stack_assign(rotation_in); + int scale_stack_offset = compiler.stack_assign(scale_in); + int result_stack_offset = compiler.stack_assign(vector_out); + + compiler.add_node( + NODE_MAPPING, + type, + compiler.encode_uchar4( + vector_stack_offset, location_stack_offset, rotation_stack_offset, scale_stack_offset), + result_stack_offset); } void MappingNode::compile(OSLCompiler &compiler) { - compiler.parameter("Matrix", tex_mapping.compute_transform()); - compiler.parameter_point("mapping_min", tex_mapping.min); - compiler.parameter_point("mapping_max", tex_mapping.max); - compiler.parameter("use_minmax", tex_mapping.use_minmax); - + compiler.parameter(this, "type"); compiler.add(this, "node_mapping"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 271d60d16b7..769687f1f19 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -391,9 +391,10 @@ class MappingNode : public ShaderNode { { return NODE_GROUP_LEVEL_2; } + void constant_fold(const ConstantFolder &folder); - float3 vector; - TextureMapping tex_mapping; + float3 vector, location, rotation, scale; + NodeMappingType type; }; class RGBToBWNode : public ShaderNode { diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index cfe71d696ed..407654245cb 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -148,6 +148,32 @@ ccl_device_inline Transform make_transform(float a, return t; } +ccl_device_inline Transform euler_to_transform(const float3 euler) +{ + float cx = cosf(euler.x); + float cy = cosf(euler.y); + float cz = cosf(euler.z); + float sx = sinf(euler.x); + float sy = sinf(euler.y); + float sz = sinf(euler.z); + + Transform t; + t.x.x = cy * cz; + t.y.x = cy * sz; + t.z.x = -sy; + + t.x.y = sy * sx * cz - cx * sz; + t.y.y = sy * sx * sz + cx * cz; + t.z.y = cy * sx; + + t.x.z = sy * cx * cz + sx * sz; + t.y.z = sy * cx * sz - sx * cz; + t.z.z = cy * cx; + + t.x.w = t.y.w = t.z.w = 0.0f; + return t; +} + /* Constructs a coordinate frame from a normalized normal. */ ccl_device_inline Transform make_transform_frame(float3 N) { |