diff options
author | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-18 12:16:04 +0300 |
---|---|---|
committer | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-18 12:16:04 +0300 |
commit | e5618725fd1ebdf558e963d959eb3950b5a9874c (patch) | |
tree | d1e02f93f36aefa5bf6a87ca75b91558a34ae5d1 /intern/cycles/kernel | |
parent | e12c17b3054b9a3d9636268c2a2904ecb9df632b (diff) |
Shading: Refactor Math node and use dynamic inputs.
- Implement dynamic inputs. The second input is now unavailable in single
operand math operators.
- Reimplemenet the clamp option using graph expansion for Cycles.
- Clean up code and unify naming between Blender and Cycles.
- Remove unused code.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D5481
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/shaders/node_math.osl | 93 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_math.h | 20 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_math_util.h | 110 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 7 |
4 files changed, 98 insertions, 132 deletions
diff --git a/intern/cycles/kernel/shaders/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl index 8830339e05f..fb59c783770 100644 --- a/intern/cycles/kernel/shaders/node_math.osl +++ b/intern/cycles/kernel/shaders/node_math.osl @@ -17,57 +17,31 @@ #include "stdosl.h" float safe_divide(float a, float b) -{ - float result; - - if (b == 0.0) - result = 0.0; - else - result = a / b; - - return result; +{ + return (b != 0.0) ? a / b : 0.0; } float safe_modulo(float a, float b) { - float result; - - if (b == 0.0) - result = 0.0; - else - result = fmod(a, b); - - return result; + return (b != 0.0) ? fmod(a, b) : 0.0; } float safe_sqrt(float a) { - float result; - - if (a > 0.0) - result = sqrt(a); - else - result = 0.0; - - return result; + return (a > 0.0) ? sqrt(a) : 0.0; } float safe_log(float a, float b) { - if (a < 0.0 || b < 0.0) - return 0.0; - - return log(a) / log(b); + return (a > 0.0 && b > 0.0) ? log(a) / log(b) : 0.0; } +/* OSL asin, acos, and pow functions are safe by default. */ shader node_math(string type = "add", - int use_clamp = 0, - float Value1 = 0.0, - float Value2 = 0.0, + float Value1 = 0.5, + float Value2 = 0.5, output float Value = 0.0) { - /* OSL asin, acos, pow check for values that could give rise to nan */ - if (type == "add") Value = Value1 + Value2; else if (type == "subtract") @@ -76,47 +50,46 @@ shader node_math(string type = "add", Value = Value1 * Value2; else if (type == "divide") Value = safe_divide(Value1, Value2); - else if (type == "sine") - Value = sin(Value1); - else if (type == "cosine") - Value = cos(Value1); - else if (type == "tangent") - Value = tan(Value1); - else if (type == "arcsine") - Value = asin(Value1); - else if (type == "arccosine") - Value = acos(Value1); - else if (type == "arctangent") - Value = atan(Value1); else if (type == "power") Value = pow(Value1, Value2); else if (type == "logarithm") Value = safe_log(Value1, Value2); + else if (type == "sqrt") + Value = safe_sqrt(Value1); + else if (type == "absolute") + Value = fabs(Value1); else if (type == "minimum") Value = min(Value1, Value2); else if (type == "maximum") Value = max(Value1, Value2); - else if (type == "round") - Value = floor(Value1 + 0.5); else if (type == "less_than") Value = Value1 < Value2; else if (type == "greater_than") Value = Value1 > Value2; - else if (type == "modulo") - Value = safe_modulo(Value1, Value2); - else if (type == "absolute") - Value = fabs(Value1); - else if (type == "arctan2") - Value = atan2(Value1, Value2); + else if (type == "round") + Value = floor(Value1 + 0.5); else if (type == "floor") Value = floor(Value1); else if (type == "ceil") Value = ceil(Value1); - else if (type == "fract") + else if (type == "fraction") Value = Value1 - floor(Value1); - else if (type == "sqrt") - Value = safe_sqrt(Value1); - - if (use_clamp) - Value = clamp(Value, 0.0, 1.0); + else if (type == "modulo") + Value = safe_modulo(Value1, Value2); + else if (type == "sine") + Value = sin(Value1); + else if (type == "cosine") + Value = cos(Value1); + else if (type == "tangent") + Value = tan(Value1); + else if (type == "arcsine") + Value = asin(Value1); + else if (type == "arccosine") + Value = acos(Value1); + else if (type == "arctangent") + Value = atan(Value1); + else if (type == "arctan2") + Value = atan2(Value1, Value2); + else + warning("%s", "Unknown math operator!"); } diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h index 5920913825b..402290d7218 100644 --- a/intern/cycles/kernel/svm/svm_math.h +++ b/intern/cycles/kernel/svm/svm_math.h @@ -16,24 +16,22 @@ CCL_NAMESPACE_BEGIN -/* Nodes */ - ccl_device void svm_node_math(KernelGlobals *kg, ShaderData *sd, float *stack, - uint itype, - uint f1_offset, - uint f2_offset, + uint type, + uint inputs_stack_offsets, + uint result_stack_offset, int *offset) { - NodeMath type = (NodeMath)itype; - float f1 = stack_load_float(stack, f1_offset); - float f2 = stack_load_float(stack, f2_offset); - float f = svm_math(type, f1, f2); + uint a_stack_offset, b_stack_offset; + decode_node_uchar4(inputs_stack_offsets, &a_stack_offset, &b_stack_offset, NULL, NULL); - uint4 node1 = read_node(kg, offset); + float a = stack_load_float(stack, a_stack_offset); + float b = stack_load_float(stack, b_stack_offset); + float result = svm_math((NodeMathType)type, a, b); - stack_store_float(stack, node1.y, f); + stack_store_float(stack, result_stack_offset, result); } ccl_device void svm_node_vector_math(KernelGlobals *kg, diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h index e3544515f1b..d8804226487 100644 --- a/intern/cycles/kernel/svm/svm_math_util.h +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -51,64 +51,60 @@ ccl_device void svm_vector_math( } } -ccl_device float svm_math(NodeMath type, float Fac1, float Fac2) +ccl_device float svm_math(NodeMathType type, float a, float b) { - float Fac; - - if (type == NODE_MATH_ADD) - Fac = Fac1 + Fac2; - else if (type == NODE_MATH_SUBTRACT) - Fac = Fac1 - Fac2; - else if (type == NODE_MATH_MULTIPLY) - Fac = Fac1 * Fac2; - else if (type == NODE_MATH_DIVIDE) - Fac = safe_divide(Fac1, Fac2); - else if (type == NODE_MATH_SINE) - Fac = sinf(Fac1); - else if (type == NODE_MATH_COSINE) - Fac = cosf(Fac1); - else if (type == NODE_MATH_TANGENT) - Fac = tanf(Fac1); - else if (type == NODE_MATH_ARCSINE) - Fac = safe_asinf(Fac1); - else if (type == NODE_MATH_ARCCOSINE) - Fac = safe_acosf(Fac1); - else if (type == NODE_MATH_ARCTANGENT) - Fac = atanf(Fac1); - else if (type == NODE_MATH_POWER) - Fac = safe_powf(Fac1, Fac2); - else if (type == NODE_MATH_LOGARITHM) - Fac = safe_logf(Fac1, Fac2); - else if (type == NODE_MATH_MINIMUM) - Fac = fminf(Fac1, Fac2); - else if (type == NODE_MATH_MAXIMUM) - Fac = fmaxf(Fac1, Fac2); - else if (type == NODE_MATH_ROUND) - Fac = floorf(Fac1 + 0.5f); - else if (type == NODE_MATH_LESS_THAN) - Fac = Fac1 < Fac2; - else if (type == NODE_MATH_GREATER_THAN) - Fac = Fac1 > Fac2; - else if (type == NODE_MATH_MODULO) - Fac = safe_modulo(Fac1, Fac2); - else if (type == NODE_MATH_ABSOLUTE) - Fac = fabsf(Fac1); - else if (type == NODE_MATH_ARCTAN2) - Fac = atan2f(Fac1, Fac2); - else if (type == NODE_MATH_FLOOR) - Fac = floorf(Fac1); - else if (type == NODE_MATH_CEIL) - Fac = ceilf(Fac1); - else if (type == NODE_MATH_FRACT) - Fac = Fac1 - floorf(Fac1); - else if (type == NODE_MATH_SQRT) - Fac = safe_sqrtf(Fac1); - else if (type == NODE_MATH_CLAMP) - Fac = saturate(Fac1); - else - Fac = 0.0f; - - return Fac; + switch (type) { + case NODE_MATH_ADD: + return a + b; + case NODE_MATH_SUBTRACT: + return a - b; + case NODE_MATH_MULTIPLY: + return a * b; + case NODE_MATH_DIVIDE: + return safe_divide(a, b); + case NODE_MATH_POWER: + return safe_powf(a, b); + case NODE_MATH_LOGARITHM: + return safe_logf(a, b); + case NODE_MATH_SQRT: + return safe_sqrtf(a); + case NODE_MATH_ABSOLUTE: + return fabsf(a); + case NODE_MATH_MINIMUM: + return fminf(a, b); + case NODE_MATH_MAXIMUM: + return fmaxf(a, b); + case NODE_MATH_LESS_THAN: + return a < b; + case NODE_MATH_GREATER_THAN: + return a > b; + case NODE_MATH_ROUND: + return floorf(a + 0.5f); + case NODE_MATH_FLOOR: + return floorf(a); + case NODE_MATH_CEIL: + return ceilf(a); + case NODE_MATH_FRACTION: + return a - floorf(a); + case NODE_MATH_MODULO: + return safe_modulo(a, b); + case NODE_MATH_SINE: + return sinf(a); + case NODE_MATH_COSINE: + return cosf(a); + case NODE_MATH_TANGENT: + return tanf(a); + case NODE_MATH_ARCSINE: + return safe_asinf(a); + case NODE_MATH_ARCCOSINE: + return safe_acosf(a); + case NODE_MATH_ARCTANGENT: + return atanf(a); + case NODE_MATH_ARCTAN2: + return atan2f(a, b); + default: + return 0.0f; + } } /* Calculate color in range 800..12000 using an approximation diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 9a8a5401297..6b0d10adc74 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -244,7 +244,7 @@ typedef enum NodeMix { NODE_MIX_CLAMP /* used for the clamp UI option */ } NodeMix; -typedef enum NodeMath { +typedef enum NodeMathType { NODE_MATH_ADD, NODE_MATH_SUBTRACT, NODE_MATH_MULTIPLY, @@ -267,10 +267,9 @@ typedef enum NodeMath { NODE_MATH_ARCTAN2, NODE_MATH_FLOOR, NODE_MATH_CEIL, - NODE_MATH_FRACT, + NODE_MATH_FRACTION, NODE_MATH_SQRT, - NODE_MATH_CLAMP /* used for the clamp UI option */ -} NodeMath; +} NodeMathType; typedef enum NodeVectorMath { NODE_VECTOR_MATH_ADD, |