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 /source/blender/nodes | |
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 'source/blender/nodes')
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_math.c | 368 | ||||
-rw-r--r-- | source/blender/nodes/texture/nodes/node_texture_math.c | 36 |
2 files changed, 67 insertions, 337 deletions
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c index 29c6d855eae..aaedc4aa1b7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.c +++ b/source/blender/nodes/shader/nodes/node_shader_math.c @@ -31,272 +31,6 @@ static bNodeSocketTemplate sh_node_math_in[] = { static bNodeSocketTemplate sh_node_math_out[] = {{SOCK_FLOAT, 0, N_("Value")}, {-1, 0, ""}}; -static void node_shader_exec_math(void *UNUSED(data), - int UNUSED(thread), - bNode *node, - bNodeExecData *UNUSED(execdata), - bNodeStack **in, - bNodeStack **out) -{ - float a, b, r = 0.0f; - - nodestack_get_vec(&a, SOCK_FLOAT, in[0]); - nodestack_get_vec(&b, SOCK_FLOAT, in[1]); - - switch (node->custom1) { - - case NODE_MATH_ADD: - r = a + b; - break; - case NODE_MATH_SUB: - r = a - b; - break; - case NODE_MATH_MUL: - r = a * b; - break; - case NODE_MATH_DIVIDE: { - if (b == 0) { /* We don't want to divide by zero. */ - r = 0.0; - } - else { - r = a / b; - } - break; - } - case NODE_MATH_SIN: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = sinf(a); - } - else { - r = sinf(b); - } - break; - } - case NODE_MATH_COS: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = cosf(a); - } - else { - r = cosf(b); - } - break; - } - case NODE_MATH_TAN: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = tanf(a); - } - else { - r = tanf(b); - } - break; - } - case NODE_MATH_ASIN: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - /* Can't do the impossible... */ - if (a <= 1 && a >= -1) { - r = asinf(a); - } - else { - r = 0.0; - } - } - else { - /* Can't do the impossible... */ - if (b <= 1 && b >= -1) { - r = asinf(b); - } - else { - r = 0.0; - } - } - break; - } - case NODE_MATH_ACOS: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - /* Can't do the impossible... */ - if (a <= 1 && a >= -1) { - r = acosf(a); - } - else { - r = 0.0; - } - } - else { - /* Can't do the impossible... */ - if (b <= 1 && b >= -1) { - r = acosf(b); - } - else { - r = 0.0; - } - } - break; - } - case NODE_MATH_ATAN: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = atan(a); - } - else { - r = atan(b); - } - break; - } - case NODE_MATH_POW: { - /* Only raise negative numbers by full integers */ - if (a >= 0) { - r = pow(a, b); - } - else { - float y_mod_1 = fabsf(fmodf(b, 1.0f)); - - /* if input value is not nearly an integer, - * fall back to zero, nicer than straight rounding. */ - if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) { - r = powf(a, floorf(b + 0.5f)); - } - else { - r = 0.0f; - } - } - - break; - } - case NODE_MATH_LOG: { - /* Don't want any imaginary numbers... */ - if (a > 0 && b > 0) { - r = log(a) / log(b); - } - else { - r = 0.0; - } - break; - } - case NODE_MATH_MIN: { - if (a < b) { - r = a; - } - else { - r = b; - } - break; - } - case NODE_MATH_MAX: { - if (a > b) { - r = a; - } - else { - r = b; - } - break; - } - case NODE_MATH_ROUND: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = (a < 0) ? (int)(a - 0.5f) : (int)(a + 0.5f); - } - else { - r = (b < 0) ? (int)(b - 0.5f) : (int)(b + 0.5f); - } - break; - } - case NODE_MATH_LESS: { - if (a < b) { - r = 1.0f; - } - else { - r = 0.0f; - } - break; - } - case NODE_MATH_GREATER: { - if (a > b) { - r = 1.0f; - } - else { - r = 0.0f; - } - break; - } - case NODE_MATH_MOD: { - if (b == 0.0f) { - r = 0.0f; - } - else { - r = fmod(a, b); - } - break; - } - case NODE_MATH_ABS: { - r = fabsf(a); - break; - } - case NODE_MATH_ATAN2: { - r = atan2(a, b); - break; - } - case NODE_MATH_FLOOR: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = floorf(a); - } - else { - r = floorf(b); - } - break; - } - case NODE_MATH_CEIL: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = ceilf(a); - } - else { - r = ceilf(b); - } - break; - } - case NODE_MATH_FRACT: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - r = a - floorf(a); - } - else { - r = b - floorf(b); - } - break; - } - case NODE_MATH_SQRT: { - /* This one only takes one input, so we've got to choose. */ - if (in[0]->hasinput || !in[1]->hasinput) { - if (a > 0) { - r = sqrt(a); - } - else { - r = 0.0; - } - } - else { - if (b > 0) { - r = sqrt(b); - } - else { - r = 0.0; - } - } - break; - } - } - if (node->custom2 & SHD_MATH_CLAMP) { - CLAMP(r, 0.0f, 1.0f); - } - out[0]->vec[0] = r; -} - static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), @@ -304,68 +38,65 @@ static int gpu_shader_math(GPUMaterial *mat, GPUNodeStack *out) { static const char *names[] = { - "math_add", "math_subtract", "math_multiply", "math_divide", "math_sine", - "math_cosine", "math_tangent", "math_asin", "math_acos", "math_atan", - "math_pow", "math_log", "math_min", "math_max", "math_round", - "math_less_than", "math_greater_than", "math_modulo", "math_abs", "math_atan2", - "math_floor", "math_ceil", "math_fract", "math_sqrt", + [NODE_MATH_ADD] = "math_add", + [NODE_MATH_SUBTRACT] = "math_subtract", + [NODE_MATH_MULTIPLY] = "math_multiply", + [NODE_MATH_DIVIDE] = "math_divide", + + [NODE_MATH_POWER] = "math_power", + [NODE_MATH_LOGARITHM] = "math_logarithm", + [NODE_MATH_SQRT] = "math_sqrt", + [NODE_MATH_ABSOLUTE] = "math_absolute", + + [NODE_MATH_MINIMUM] = "math_minimum", + [NODE_MATH_MAXIMUM] = "math_maximum", + [NODE_MATH_LESS_THAN] = "math_less_than", + [NODE_MATH_GREATER_THAN] = "math_greater_than", + + [NODE_MATH_ROUND] = "math_round", + [NODE_MATH_FLOOR] = "math_floor", + [NODE_MATH_CEIL] = "math_ceil", + [NODE_MATH_FRACTION] = "math_fraction", + [NODE_MATH_MODULO] = "math_modulo", + + [NODE_MATH_SINE] = "math_sine", + [NODE_MATH_COSINE] = "math_cosine", + [NODE_MATH_TANGENT] = "math_tangent", + [NODE_MATH_ARCSINE] = "math_arcsine", + [NODE_MATH_ARCCOSINE] = "math_arccosine", + [NODE_MATH_ARCTANGENT] = "math_arctangent", + [NODE_MATH_ARCTAN2] = "math_arctan2", }; - switch (node->custom1) { - case NODE_MATH_ADD: - case NODE_MATH_SUB: - case NODE_MATH_MUL: - case NODE_MATH_DIVIDE: - case NODE_MATH_POW: - case NODE_MATH_LOG: - case NODE_MATH_MIN: - case NODE_MATH_MAX: - case NODE_MATH_LESS: - case NODE_MATH_GREATER: - case NODE_MATH_MOD: - case NODE_MATH_ATAN2: - GPU_stack_link(mat, node, names[node->custom1], in, out); - break; - case NODE_MATH_SIN: - case NODE_MATH_COS: - case NODE_MATH_TAN: - case NODE_MATH_ASIN: - case NODE_MATH_ACOS: - case NODE_MATH_ATAN: - case NODE_MATH_ROUND: - case NODE_MATH_ABS: - case NODE_MATH_FLOOR: - case NODE_MATH_FRACT: - case NODE_MATH_CEIL: - case NODE_MATH_SQRT: - if (in[0].hasinput || !in[1].hasinput) { - /* use only first item and terminator */ - GPUNodeStack tmp_in[2]; - memcpy(&tmp_in[0], &in[0], sizeof(GPUNodeStack)); - memcpy(&tmp_in[1], &in[2], sizeof(GPUNodeStack)); - GPU_stack_link(mat, node, names[node->custom1], tmp_in, out); - } - else { - /* use only second item and terminator */ - GPUNodeStack tmp_in[2]; - memcpy(&tmp_in[0], &in[1], sizeof(GPUNodeStack)); - memcpy(&tmp_in[1], &in[2], sizeof(GPUNodeStack)); - GPU_stack_link(mat, node, names[node->custom1], tmp_in, out); - } - break; - default: - return 0; - } + GPU_stack_link(mat, node, names[node->custom1], in, out); if (node->custom2 & SHD_MATH_CLAMP) { float min[3] = {0.0f, 0.0f, 0.0f}; float max[3] = {1.0f, 1.0f, 1.0f}; GPU_link(mat, "clamp_value", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link); } - return 1; } +static void node_shader_update_math(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *sock = BLI_findlink(&node->inputs, 1); + nodeSetSocketAvailability(sock, + !ELEM(node->custom1, + NODE_MATH_SQRT, + NODE_MATH_CEIL, + NODE_MATH_SINE, + NODE_MATH_ROUND, + NODE_MATH_FLOOR, + NODE_MATH_COSINE, + NODE_MATH_ARCSINE, + NODE_MATH_TANGENT, + NODE_MATH_ABSOLUTE, + NODE_MATH_FRACTION, + NODE_MATH_ARCCOSINE, + NODE_MATH_ARCTANGENT)); +} + void register_node_type_sh_math(void) { static bNodeType ntype; @@ -373,9 +104,8 @@ void register_node_type_sh_math(void) sh_node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, 0); node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out); node_type_label(&ntype, node_math_label); - node_type_storage(&ntype, "", NULL, NULL); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_math); node_type_gpu(&ntype, gpu_shader_math); + node_type_update(&ntype, node_shader_update_math); nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c index 2eb32e0addc..b1d67a5a953 100644 --- a/source/blender/nodes/texture/nodes/node_texture_math.c +++ b/source/blender/nodes/texture/nodes/node_texture_math.c @@ -46,10 +46,10 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor case NODE_MATH_ADD: *out = in0 + in1; break; - case NODE_MATH_SUB: + case NODE_MATH_SUBTRACT: *out = in0 - in1; break; - case NODE_MATH_MUL: + case NODE_MATH_MULTIPLY: *out = in0 * in1; break; case NODE_MATH_DIVIDE: { @@ -62,19 +62,19 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } break; } - case NODE_MATH_SIN: { + case NODE_MATH_SINE: { *out = sinf(in0); break; } - case NODE_MATH_COS: { + case NODE_MATH_COSINE: { *out = cosf(in0); break; } - case NODE_MATH_TAN: { + case NODE_MATH_TANGENT: { *out = tanf(in0); break; } - case NODE_MATH_ASIN: { + case NODE_MATH_ARCSINE: { /* Can't do the impossible... */ if (in0 <= 1 && in0 >= -1) { *out = asinf(in0); @@ -84,7 +84,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } break; } - case NODE_MATH_ACOS: { + case NODE_MATH_ARCCOSINE: { /* Can't do the impossible... */ if (in0 <= 1 && in0 >= -1) { *out = acosf(in0); @@ -94,11 +94,11 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } break; } - case NODE_MATH_ATAN: { + case NODE_MATH_ARCTANGENT: { *out = atan(in0); break; } - case NODE_MATH_POW: { + case NODE_MATH_POWER: { /* Only raise negative numbers by full integers */ if (in0 >= 0) { out[0] = pow(in0, in1); @@ -114,7 +114,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } break; } - case NODE_MATH_LOG: { + case NODE_MATH_LOGARITHM: { /* Don't want any imaginary numbers... */ if (in0 > 0 && in1 > 0) { *out = log(in0) / log(in1); @@ -124,7 +124,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } break; } - case NODE_MATH_MIN: { + case NODE_MATH_MINIMUM: { if (in0 < in1) { *out = in0; } @@ -133,7 +133,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } break; } - case NODE_MATH_MAX: { + case NODE_MATH_MAXIMUM: { if (in0 > in1) { *out = in0; } @@ -147,7 +147,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; } - case NODE_MATH_LESS: { + case NODE_MATH_LESS_THAN: { if (in0 < in1) { *out = 1.0f; } @@ -157,7 +157,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; } - case NODE_MATH_GREATER: { + case NODE_MATH_GREATER_THAN: { if (in0 > in1) { *out = 1.0f; } @@ -167,7 +167,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; } - case NODE_MATH_MOD: { + case NODE_MATH_MODULO: { if (in1 == 0.0f) { *out = 0.0f; } @@ -177,12 +177,12 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; } - case NODE_MATH_ABS: { + case NODE_MATH_ABSOLUTE: { *out = fabsf(in0); break; } - case NODE_MATH_ATAN2: { + case NODE_MATH_ARCTAN2: { *out = atan2(in0, in1); break; } @@ -197,7 +197,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; } - case NODE_MATH_FRACT: { + case NODE_MATH_FRACTION: { *out = in0 - floorf(in0); break; } |