Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmarSquircleArt <omar.squircleart@gmail.com>2019-08-18 12:16:04 +0300
committerOmarSquircleArt <omar.squircleart@gmail.com>2019-08-18 12:16:04 +0300
commite5618725fd1ebdf558e963d959eb3950b5a9874c (patch)
treed1e02f93f36aefa5bf6a87ca75b91558a34ae5d1 /source/blender/nodes/shader/nodes/node_shader_math.c
parente12c17b3054b9a3d9636268c2a2904ecb9df632b (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/shader/nodes/node_shader_math.c')
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c368
1 files changed, 49 insertions, 319 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);
}