diff options
author | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-21 20:36:33 +0300 |
---|---|---|
committer | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-21 20:36:33 +0300 |
commit | 7f4a2fc437cf9a6decbda152bd7d36ce7a08929f (patch) | |
tree | a0643b42154c44abf8999192e0c640b4c02615ae /intern/cycles | |
parent | 6785da095d66c341ca14eeec5c02ab6e4ad2454f (diff) |
Shading: Add more operators to Vector Math node.
Add Multiply, Divide, Project, Reflect, Distance, Length, Scale, Snap,
Floor, Ceil, Modulo, Fraction, Absolute, Minimum, and Maximum operators
to the Vector Math node. The Value output has been removed from operators
whose output is a vector, and the other way around. All of those removals
has been handled properly in versioning code.
The patch doesn't include tests for the new operators. Tests will be added
in a later patch.
Reviewers: brecht, JacquesLucke
Differential Revision: https://developer.blender.org/D5523
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_vector_math.osl | 83 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_math.h | 32 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_math_util.h | 95 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 27 | ||||
-rw-r--r-- | intern/cycles/render/bake.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/constant_fold.cpp | 39 | ||||
-rw-r--r-- | intern/cycles/render/constant_fold.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 47 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 3 | ||||
-rw-r--r-- | intern/cycles/subd/subd_dice.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/subd/subd_split.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/test/render_graph_finalize_test.cpp | 27 | ||||
-rw-r--r-- | intern/cycles/util/util_math_float3.h | 62 |
15 files changed, 331 insertions, 110 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index d38a97dc4ea..047cc82dbfc 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -1481,8 +1481,8 @@ void BlenderSession::update_resumable_tile_manager(int num_samples) /* Round after doing the multiplications with num_chunks and num_samples_per_chunk * to allow for many small chunks. */ - int rounded_range_start_sample = (int)floor(range_start_sample + 0.5f); - int rounded_range_num_samples = max((int)floor(range_num_samples + 0.5f), 1); + int rounded_range_start_sample = (int)floorf(range_start_sample + 0.5f); + int rounded_range_num_samples = max((int)floorf(range_num_samples + 0.5f), 1); /* Make sure we don't overshoot. */ if (rounded_range_start_sample + rounded_range_num_samples > num_samples) { diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 626a1dad7db..322a1771786 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -333,9 +333,9 @@ static ShaderNode *add_node(Scene *scene, } else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) { BL::ShaderNodeVectorMath b_vector_math_node(b_node); - VectorMathNode *vmath = new VectorMathNode(); - vmath->type = (NodeVectorMath)b_vector_math_node.operation(); - node = vmath; + VectorMathNode *vector_math_node = new VectorMathNode(); + vector_math_node->type = (NodeVectorMathType)b_vector_math_node.operation(); + node = vector_math_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); diff --git a/intern/cycles/kernel/shaders/node_vector_math.osl b/intern/cycles/kernel/shaders/node_vector_math.osl index 10bb0c7283c..fd5e27aa144 100644 --- a/intern/cycles/kernel/shaders/node_vector_math.osl +++ b/intern/cycles/kernel/shaders/node_vector_math.osl @@ -16,34 +16,97 @@ #include "stdosl.h" +float safe_divide(float a, float b) +{ + return (b != 0.0) ? a / b : 0.0; +} + +vector safe_divide(vector a, vector b) +{ + return vector((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); +} + +vector project(vector v, vector v_proj) +{ + float lenSquared = dot(v_proj, v_proj); + return (lenSquared != 0.0) ? (dot(v, v_proj) / lenSquared) * v_proj : vector(0.0); +} + +vector snap(vector a, vector b) +{ + return floor(safe_divide(a, b)) * b; +} + shader node_vector_math(string type = "add", vector Vector1 = vector(0.0, 0.0, 0.0), vector Vector2 = vector(0.0, 0.0, 0.0), + float Scale = 1.0, output float Value = 0.0, output vector Vector = vector(0.0, 0.0, 0.0)) { if (type == "add") { Vector = Vector1 + Vector2; - Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0; } else if (type == "subtract") { Vector = Vector1 - Vector2; - Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0; } - else if (type == "average") { - Value = length(Vector1 + Vector2); - Vector = normalize(Vector1 + Vector2); + else if (type == "multiply") { + Vector = Vector1 * Vector2; + } + else if (type == "divide") { + Vector = safe_divide(Vector1, Vector2); + } + else if (type == "cross_product") { + Vector = cross(Vector1, Vector2); + } + else if (type == "project") { + Vector = project(Vector1, Vector2); + } + else if (type == "reflect") { + Vector = reflect(Vector1, normalize(Vector2)); } else if (type == "dot_product") { Value = dot(Vector1, Vector2); } - else if (type == "cross_product") { - vector c = cross(Vector1, Vector2); - Value = length(c); - Vector = normalize(c); + else if (type == "distance") { + Value = distance(Vector1, Vector2); } - else if (type == "normalize") { + else if (type == "length") { Value = length(Vector1); + } + else if (type == "scale") { + Vector = Vector1 * Scale; + } + else if (type == "normalize") { Vector = normalize(Vector1); } + else if (type == "snap") { + Vector = snap(Vector1, Vector2); + } + else if (type == "floor") { + Vector = floor(Vector1); + } + else if (type == "ceil") { + Vector = ceil(Vector1); + } + else if (type == "modulo") { + Vector = mod(Vector1, Vector2); + } + else if (type == "fraction") { + Vector = Vector1 - floor(Vector1); + } + else if (type == "absolute") { + Vector = abs(Vector1); + } + else if (type == "minimum") { + Vector = min(Vector1, Vector2); + } + else if (type == "maximum") { + Vector = max(Vector1, Vector2); + } + else { + warning("%s", "Unknown vector math operator!"); + } } diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h index 402290d7218..c577a7f13c7 100644 --- a/intern/cycles/kernel/svm/svm_math.h +++ b/intern/cycles/kernel/svm/svm_math.h @@ -37,25 +37,29 @@ ccl_device void svm_node_math(KernelGlobals *kg, ccl_device void svm_node_vector_math(KernelGlobals *kg, ShaderData *sd, float *stack, - uint itype, - uint v1_offset, - uint v2_offset, + uint type, + uint inputs_stack_offsets, + uint outputs_stack_offsets, int *offset) { - NodeVectorMath type = (NodeVectorMath)itype; - float3 v1 = stack_load_float3(stack, v1_offset); - float3 v2 = stack_load_float3(stack, v2_offset); - float f; - float3 v; + uint value_stack_offset, vector_stack_offset; + uint a_stack_offset, b_stack_offset, scale_stack_offset; + decode_node_uchar4( + inputs_stack_offsets, &a_stack_offset, &b_stack_offset, &scale_stack_offset, NULL); + decode_node_uchar4(outputs_stack_offsets, &value_stack_offset, &vector_stack_offset, NULL, NULL); - svm_vector_math(&f, &v, type, v1, v2); + float3 a = stack_load_float3(stack, a_stack_offset); + float3 b = stack_load_float3(stack, b_stack_offset); + float scale = stack_load_float(stack, scale_stack_offset); - uint4 node1 = read_node(kg, offset); + float value; + float3 vector; + svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, scale); - if (stack_valid(node1.y)) - stack_store_float(stack, node1.y, f); - if (stack_valid(node1.z)) - stack_store_float3(stack, node1.z, v); + if (stack_valid(value_stack_offset)) + stack_store_float(stack, value_stack_offset, value); + if (stack_valid(vector_stack_offset)) + stack_store_float3(stack, vector_stack_offset, vector); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h index d8804226487..c87ca0defa7 100644 --- a/intern/cycles/kernel/svm/svm_math_util.h +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -16,38 +16,73 @@ CCL_NAMESPACE_BEGIN -ccl_device float average_fac(float3 v) -{ - return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z)) / 3.0f; -} - ccl_device void svm_vector_math( - float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2) + float *value, float3 *vector, NodeVectorMathType type, float3 a, float3 b, float scale) { - if (type == NODE_VECTOR_MATH_ADD) { - *Vector = Vector1 + Vector2; - *Fac = average_fac(*Vector); - } - else if (type == NODE_VECTOR_MATH_SUBTRACT) { - *Vector = Vector1 - Vector2; - *Fac = average_fac(*Vector); - } - else if (type == NODE_VECTOR_MATH_AVERAGE) { - *Vector = safe_normalize_len(Vector1 + Vector2, Fac); - } - else if (type == NODE_VECTOR_MATH_DOT_PRODUCT) { - *Fac = dot(Vector1, Vector2); - *Vector = make_float3(0.0f, 0.0f, 0.0f); - } - else if (type == NODE_VECTOR_MATH_CROSS_PRODUCT) { - *Vector = safe_normalize_len(cross(Vector1, Vector2), Fac); - } - else if (type == NODE_VECTOR_MATH_NORMALIZE) { - *Vector = safe_normalize_len(Vector1, Fac); - } - else { - *Fac = 0.0f; - *Vector = make_float3(0.0f, 0.0f, 0.0f); + switch (type) { + case NODE_VECTOR_MATH_ADD: + *vector = a + b; + break; + case NODE_VECTOR_MATH_SUBTRACT: + *vector = a - b; + break; + case NODE_VECTOR_MATH_MULTIPLY: + *vector = a * b; + break; + case NODE_VECTOR_MATH_DIVIDE: + *vector = safe_divide_float3_float3(a, b); + break; + case NODE_VECTOR_MATH_CROSS_PRODUCT: + *vector = cross(a, b); + break; + case NODE_VECTOR_MATH_PROJECT: + *vector = project(a, b); + break; + case NODE_VECTOR_MATH_REFLECT: + *vector = reflect(a, b); + break; + case NODE_VECTOR_MATH_DOT_PRODUCT: + *value = dot(a, b); + break; + case NODE_VECTOR_MATH_DISTANCE: + *value = distance(a, b); + break; + case NODE_VECTOR_MATH_LENGTH: + *value = len(a); + break; + case NODE_VECTOR_MATH_SCALE: + *vector = a * scale; + break; + case NODE_VECTOR_MATH_NORMALIZE: + *vector = safe_normalize(a); + break; + case NODE_VECTOR_MATH_SNAP: + *vector = floor(safe_divide_float3_float3(a, b)) * b; + break; + case NODE_VECTOR_MATH_FLOOR: + *vector = floor(a); + break; + case NODE_VECTOR_MATH_CEIL: + *vector = ceil(a); + break; + case NODE_VECTOR_MATH_MODULO: + *vector = make_float3(safe_modulo(a.x, b.x), safe_modulo(a.y, b.y), safe_modulo(a.z, b.z)); + break; + case NODE_VECTOR_MATH_FRACTION: + *vector = fract(a); + break; + case NODE_VECTOR_MATH_ABSOLUTE: + *vector = fabs(a); + break; + case NODE_VECTOR_MATH_MINIMUM: + *vector = min(a, b); + break; + case NODE_VECTOR_MATH_MAXIMUM: + *vector = max(a, b); + break; + default: + *vector = make_float3(0.0f, 0.0f, 0.0f); + *value = 0.0f; } } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 6b0d10adc74..884ad76a9b7 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -271,14 +271,31 @@ typedef enum NodeMathType { NODE_MATH_SQRT, } NodeMathType; -typedef enum NodeVectorMath { +typedef enum NodeVectorMathType { NODE_VECTOR_MATH_ADD, NODE_VECTOR_MATH_SUBTRACT, - NODE_VECTOR_MATH_AVERAGE, - NODE_VECTOR_MATH_DOT_PRODUCT, + NODE_VECTOR_MATH_MULTIPLY, + NODE_VECTOR_MATH_DIVIDE, + NODE_VECTOR_MATH_CROSS_PRODUCT, - NODE_VECTOR_MATH_NORMALIZE -} NodeVectorMath; + NODE_VECTOR_MATH_PROJECT, + NODE_VECTOR_MATH_REFLECT, + NODE_VECTOR_MATH_DOT_PRODUCT, + + NODE_VECTOR_MATH_DISTANCE, + NODE_VECTOR_MATH_LENGTH, + NODE_VECTOR_MATH_SCALE, + NODE_VECTOR_MATH_NORMALIZE, + + NODE_VECTOR_MATH_SNAP, + NODE_VECTOR_MATH_FLOOR, + NODE_VECTOR_MATH_CEIL, + NODE_VECTOR_MATH_MODULO, + NODE_VECTOR_MATH_FRACTION, + NODE_VECTOR_MATH_ABSOLUTE, + NODE_VECTOR_MATH_MINIMUM, + NODE_VECTOR_MATH_MAXIMUM, +} NodeVectorMathType; typedef enum NodeVectorTransformType { NODE_VECTOR_TRANSFORM_TYPE_VECTOR, diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index 73893921500..b906357b7b5 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -124,7 +124,7 @@ BakeData *BakeManager::init(const int object, const size_t tri_offset, const siz void BakeManager::set_shader_limit(const size_t x, const size_t y) { m_shader_limit = x * y; - m_shader_limit = (size_t)pow(2, ceil(log(m_shader_limit) / log(2))); + m_shader_limit = (size_t)pow(2, std::ceil(log(m_shader_limit) / log(2))); } bool BakeManager::bake(Device *device, diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp index d6fdc49434e..851d4b71df8 100644 --- a/intern/cycles/render/constant_fold.cpp +++ b/intern/cycles/render/constant_fold.cpp @@ -359,10 +359,11 @@ void ConstantFolder::fold_math(NodeMathType type) const } } -void ConstantFolder::fold_vector_math(NodeVectorMath type) const +void ConstantFolder::fold_vector_math(NodeVectorMathType type) const { ShaderInput *vector1_in = node->input("Vector1"); ShaderInput *vector2_in = node->input("Vector2"); + ShaderInput *scale_in = node->input("Scale"); switch (type) { case NODE_VECTOR_MATH_ADD: @@ -380,6 +381,27 @@ void ConstantFolder::fold_vector_math(NodeVectorMath type) const try_bypass_or_make_constant(vector1_in); } break; + case NODE_VECTOR_MATH_MULTIPLY: + /* X * 0 == 0 * X == 0 */ + if (is_zero(vector1_in) || is_zero(vector2_in)) { + make_zero(); + } /* X * 1 == 1 * X == X */ + else if (is_one(vector1_in)) { + try_bypass_or_make_constant(vector2_in); + } + else if (is_one(vector2_in)) { + try_bypass_or_make_constant(vector1_in); + } + break; + case NODE_VECTOR_MATH_DIVIDE: + /* X / 0 == 0 / X == 0 */ + if (is_zero(vector1_in) || is_zero(vector2_in)) { + make_zero(); + } /* X / 1 == X */ + else if (is_one(vector2_in)) { + try_bypass_or_make_constant(vector1_in); + } + break; case NODE_VECTOR_MATH_DOT_PRODUCT: case NODE_VECTOR_MATH_CROSS_PRODUCT: /* X * 0 == 0 * X == 0 */ @@ -387,6 +409,21 @@ void ConstantFolder::fold_vector_math(NodeVectorMath type) const make_zero(); } break; + case NODE_VECTOR_MATH_LENGTH: + case NODE_VECTOR_MATH_ABSOLUTE: + if (is_zero(vector1_in)) { + make_zero(); + } + break; + case NODE_VECTOR_MATH_SCALE: + /* X * 0 == 0 * X == 0 */ + if (is_zero(vector1_in) || is_zero(scale_in)) { + make_zero(); + } /* X * 1 == X */ + else if (is_one(scale_in)) { + try_bypass_or_make_constant(vector1_in); + } + break; default: break; } diff --git a/intern/cycles/render/constant_fold.h b/intern/cycles/render/constant_fold.h index d223fd86197..881636a9fe1 100644 --- a/intern/cycles/render/constant_fold.h +++ b/intern/cycles/render/constant_fold.h @@ -65,7 +65,7 @@ class ConstantFolder { /* Specific nodes. */ void fold_mix(NodeMix type, bool clamp) const; void fold_math(NodeMathType type) const; - void fold_vector_math(NodeVectorMath type) const; + void fold_vector_math(NodeVectorMathType type) const; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 642f7beaf3c..8c8bb559c30 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -163,8 +163,10 @@ void TextureMapping::compile(SVMCompiler &compiler, int offset_in, int offset_ou } if (type == NORMAL) { - compiler.add_node(NODE_VECTOR_MATH, NODE_VECTOR_MATH_NORMALIZE, offset_out, offset_out); - compiler.add_node(NODE_VECTOR_MATH, SVM_STACK_INVALID, offset_out); + compiler.add_node(NODE_VECTOR_MATH, + NODE_VECTOR_MATH_NORMALIZE, + compiler.encode_uchar4(offset_out, offset_out, offset_out), + compiler.encode_uchar4(SVM_STACK_INVALID, offset_out)); } } @@ -5496,14 +5498,32 @@ NODE_DEFINE(VectorMathNode) static NodeEnum type_enum; type_enum.insert("add", NODE_VECTOR_MATH_ADD); type_enum.insert("subtract", NODE_VECTOR_MATH_SUBTRACT); - type_enum.insert("average", NODE_VECTOR_MATH_AVERAGE); - type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT); + type_enum.insert("multiply", NODE_VECTOR_MATH_MULTIPLY); + type_enum.insert("divide", NODE_VECTOR_MATH_DIVIDE); + type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT); + type_enum.insert("project", NODE_VECTOR_MATH_PROJECT); + type_enum.insert("reflect", NODE_VECTOR_MATH_REFLECT); + type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT); + + type_enum.insert("distance", NODE_VECTOR_MATH_DISTANCE); + type_enum.insert("length", NODE_VECTOR_MATH_LENGTH); + type_enum.insert("scale", NODE_VECTOR_MATH_SCALE); type_enum.insert("normalize", NODE_VECTOR_MATH_NORMALIZE); + + type_enum.insert("snap", NODE_VECTOR_MATH_SNAP); + type_enum.insert("floor", NODE_VECTOR_MATH_FLOOR); + type_enum.insert("ceil", NODE_VECTOR_MATH_CEIL); + type_enum.insert("modulo", NODE_VECTOR_MATH_MODULO); + type_enum.insert("fraction", NODE_VECTOR_MATH_FRACTION); + type_enum.insert("absolute", NODE_VECTOR_MATH_ABSOLUTE); + type_enum.insert("minimum", NODE_VECTOR_MATH_MINIMUM); + type_enum.insert("maximum", NODE_VECTOR_MATH_MAXIMUM); SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_MATH_ADD); SOCKET_IN_VECTOR(vector1, "Vector1", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_VECTOR(vector2, "Vector2", make_float3(0.0f, 0.0f, 0.0f)); + SOCKET_IN_FLOAT(scale, "Scale", 1.0f); SOCKET_OUT_FLOAT(value, "Value"); SOCKET_OUT_VECTOR(vector, "Vector"); @@ -5521,8 +5541,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder) float3 vector; if (folder.all_inputs_constant()) { - svm_vector_math(&value, &vector, type, vector1, vector2); - + svm_vector_math(&value, &vector, type, vector1, vector2, scale); if (folder.output == output("Value")) { folder.make_constant(value); } @@ -5539,15 +5558,21 @@ void VectorMathNode::compile(SVMCompiler &compiler) { ShaderInput *vector1_in = input("Vector1"); ShaderInput *vector2_in = input("Vector2"); + ShaderInput *scale_in = input("Scale"); ShaderOutput *value_out = output("Value"); ShaderOutput *vector_out = output("Vector"); - compiler.add_node(NODE_VECTOR_MATH, - type, - compiler.stack_assign(vector1_in), - compiler.stack_assign(vector2_in)); + int vector1_stack_offset = compiler.stack_assign(vector1_in); + int vector2_stack_offset = compiler.stack_assign(vector2_in); + int scale_stack_offset = compiler.stack_assign(scale_in); + int value_stack_offset = compiler.stack_assign_if_linked(value_out); + int vector_stack_offset = compiler.stack_assign_if_linked(vector_out); + compiler.add_node( - NODE_VECTOR_MATH, compiler.stack_assign(value_out), compiler.stack_assign(vector_out)); + NODE_VECTOR_MATH, + type, + compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset), + compiler.encode_uchar4(value_stack_offset, vector_stack_offset)); } void VectorMathNode::compile(OSLCompiler &compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 514ab3db8eb..417623c7562 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -1292,7 +1292,8 @@ class VectorMathNode : public ShaderNode { float3 vector1; float3 vector2; - NodeVectorMath type; + float scale; + NodeVectorMathType type; }; class VectorTransformNode : public ShaderNode { diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index fb96be5065b..914b408911e 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -323,8 +323,8 @@ void QuadDice::dice(SubPatch &sub, EdgeFactors &ef) float S = 1.0f; #endif - Mu = max((int)ceil(S * Mu), 2); // XXX handle 0 & 1? - Mv = max((int)ceil(S * Mv), 2); // XXX handle 0 & 1? + Mu = max((int)ceilf(S * Mu), 2); // XXX handle 0 & 1? + Mv = max((int)ceilf(S * Mv), 2); // XXX handle 0 & 1? /* reserve space for new verts */ int offset = params.mesh->verts.size(); diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp index e6603632ba7..e5b85fcfd60 100644 --- a/intern/cycles/subd/subd_split.cpp +++ b/intern/cycles/subd/subd_split.cpp @@ -80,9 +80,9 @@ int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend) Plast = P; } - int tmin = (int)ceil(Lsum / params.dicing_rate); - int tmax = (int)ceil((params.test_steps - 1) * Lmax / - params.dicing_rate); // XXX paper says N instead of N-1, seems wrong? + int tmin = (int)ceilf(Lsum / params.dicing_rate); + int tmax = (int)ceilf((params.test_steps - 1) * Lmax / + params.dicing_rate); // XXX paper says N instead of N-1, seems wrong? if (tmax - tmin > params.split_threshold) return DSPLIT_NON_UNIFORM; @@ -99,7 +99,7 @@ void DiagSplit::partition_edge( *t1 = T(patch, *P, Pend); } else { - int I = (int)floor((float)t * 0.5f); + int I = (int)floorf((float)t * 0.5f); *P = interp(Pstart, Pend, (t == 0) ? 0 : I / (float)t); /* XXX is t faces or verts */ *t0 = I; *t1 = t - I; diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp index 7d4b600350b..ca93f8b02d0 100644 --- a/intern/cycles/test/render_graph_finalize_test.cpp +++ b/intern/cycles/test/render_graph_finalize_test.cpp @@ -1163,21 +1163,14 @@ TEST_F(RenderGraph, constant_fold_part_math_pow_1) TEST_F(RenderGraph, constant_fold_vector_math) { EXPECT_ANY_MESSAGE(log); - CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Value to constant (1)."); CORRECT_INFO_MESSAGE(log, "Folding VectorMath::Vector to constant (3, 0, 0)."); - CORRECT_INFO_MESSAGE(log, "Folding convert_vector_to_float::value_float to constant (1)."); - CORRECT_INFO_MESSAGE(log, "Folding Math::Value to constant (2)."); - CORRECT_INFO_MESSAGE(log, "Folding convert_float_to_color::value_color to constant (2, 2, 2)."); builder .add_node(ShaderNodeBuilder<VectorMathNode>("VectorMath") .set(&VectorMathNode::type, NODE_VECTOR_MATH_SUBTRACT) .set("Vector1", make_float3(1.3f, 0.5f, 0.7f)) .set("Vector2", make_float3(-1.7f, 0.5f, 0.7f))) - .add_node(ShaderNodeBuilder<MathNode>("Math").set(&MathNode::type, NODE_MATH_ADD)) - .add_connection("VectorMath::Vector", "Math::Value1") - .add_connection("VectorMath::Value", "Math::Value2") - .output_color("Math::Value"); + .output_color("VectorMath::Vector"); graph.finalize(scene); } @@ -1187,7 +1180,7 @@ TEST_F(RenderGraph, constant_fold_vector_math) * Includes 2 tests: constant on each side. */ static void build_vecmath_partial_test_graph(ShaderGraphBuilder &builder, - NodeVectorMath type, + NodeVectorMathType type, float3 constval) { builder @@ -1241,22 +1234,6 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_sub_0) } /* - * Tests: partial folding for Vector Math Dot Product with known 0. - */ -TEST_F(RenderGraph, constant_fold_part_vecmath_dot_0) -{ - EXPECT_ANY_MESSAGE(log); - /* X * 0 == 0 * X == X */ - CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Vector to constant (0, 0, 0)."); - CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Vector to constant (0, 0, 0)."); - CORRECT_INFO_MESSAGE(log, "Folding Out::Vector to constant (0, 0, 0)."); - CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode."); - - build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_DOT_PRODUCT, make_float3(0, 0, 0)); - graph.finalize(scene); -} - -/* * Tests: partial folding for Vector Math Cross Product with known 0. */ TEST_F(RenderGraph, constant_fold_part_vecmath_cross_0) diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h index 554b7408148..0d7588da690 100644 --- a/intern/cycles/util/util_math_float3.h +++ b/intern/cycles/util/util_math_float3.h @@ -47,6 +47,7 @@ ccl_device_inline float3 operator/=(float3 &a, float f); ccl_device_inline bool operator==(const float3 &a, const float3 &b); ccl_device_inline bool operator!=(const float3 &a, const float3 &b); +ccl_device_inline float distance(const float3 &a, const float3 &b); ccl_device_inline float dot(const float3 &a, const float3 &b); ccl_device_inline float dot_xy(const float3 &a, const float3 &b); ccl_device_inline float3 cross(const float3 &a, const float3 &b); @@ -58,6 +59,9 @@ ccl_device_inline float3 fabs(const float3 &a); ccl_device_inline float3 mix(const float3 &a, const float3 &b, float t); ccl_device_inline float3 rcp(const float3 &a); ccl_device_inline float3 sqrt(const float3 &a); +ccl_device_inline float3 floor(const float3 &a); +ccl_device_inline float3 ceil(const float3 &a); +ccl_device_inline float3 fract(const float3 &a); #endif /* !__KERNEL_OPENCL__ */ ccl_device_inline float min3(float3 a); @@ -65,10 +69,15 @@ ccl_device_inline float max3(float3 a); ccl_device_inline float len(const float3 a); ccl_device_inline float len_squared(const float3 a); +ccl_device_inline float3 reflect(const float3 incident, const float3 normal); +ccl_device_inline float3 project(const float3 v, const float3 v_proj); + ccl_device_inline float3 saturate3(float3 a); ccl_device_inline float3 safe_normalize(const float3 a); ccl_device_inline float3 normalize_len(const float3 a, float *t); ccl_device_inline float3 safe_normalize_len(const float3 a, float *t); +ccl_device_inline float3 safe_divide_float3_float3(const float3 a, const float3 b); +ccl_device_inline float3 safe_divide_float3_float(const float3 a, const float b); ccl_device_inline float3 interp(float3 a, float3 b, float t); ccl_device_inline float3 sqr3(float3 a); @@ -205,6 +214,11 @@ ccl_device_inline bool operator!=(const float3 &a, const float3 &b) return !(a == b); } +ccl_device_inline float distance(const float3 &a, const float3 &b) +{ + return len(a - b); +} + ccl_device_inline float dot(const float3 &a, const float3 &b) { # if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) @@ -281,6 +295,29 @@ ccl_device_inline float3 sqrt(const float3 &a) # endif } +ccl_device_inline float3 floor(const float3 &a) +{ +# ifdef __KERNEL_SSE__ + return float3(_mm_floor_ps(a)); +# else + return make_float3(floorf(a.x), floorf(a.y), floorf(a.z)); +# endif +} + +ccl_device_inline float3 ceil(const float3 &a) +{ +# ifdef __KERNEL_SSE__ + return float3(_mm_ceil_ps(a)); +# else + return make_float3(ceilf(a.x), ceilf(a.y), ceilf(a.z)); +# endif +} + +ccl_device_inline float3 fract(const float3 &a) +{ + return a - floor(a); +} + ccl_device_inline float3 mix(const float3 &a, const float3 &b, float t) { return a + t * (b - a); @@ -321,6 +358,19 @@ ccl_device_inline float len_squared(const float3 a) return dot(a, a); } +ccl_device_inline float3 reflect(const float3 incident, const float3 normal) +{ + float3 unit_normal = normalize(normal); + return incident - 2.0f * unit_normal * dot(incident, unit_normal); +} + +ccl_device_inline float3 project(const float3 v, const float3 v_proj) +{ + float len_squared = dot(v_proj, v_proj); + return (len_squared != 0.0f) ? (dot(v, v_proj) / len_squared) * v_proj : + make_float3(0.0f, 0.0f, 0.0f); +} + ccl_device_inline float3 saturate3(float3 a) { return make_float3(saturate(a.x), saturate(a.y), saturate(a.z)); @@ -345,6 +395,18 @@ ccl_device_inline float3 safe_normalize_len(const float3 a, float *t) return (*t != 0.0f) ? a / (*t) : a; } +ccl_device_inline float3 safe_divide_float3_float3(const float3 a, const float3 b) +{ + return make_float3((b.x != 0.0f) ? a.x / b.x : 0.0f, + (b.y != 0.0f) ? a.y / b.y : 0.0f, + (b.z != 0.0f) ? a.z / b.z : 0.0f); +} + +ccl_device_inline float3 safe_divide_float3_float(const float3 a, const float b) +{ + return (b != 0.0f) ? a / b : make_float3(0.0f, 0.0f, 0.0f); +} + ccl_device_inline float3 interp(float3 a, float3 b, float t) { return a + t * (b - a); |