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:
authorLukas Tönne <lukas.toenne@gmail.com>2014-02-25 13:11:48 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2014-02-25 13:15:28 +0400
commit3ae641eb020ea61a595840eee8cbcc9f7ee36043 (patch)
treef9b216c63088ce3513c299c20ae9a73ead08c221 /source/blender/nodes
parentbf547a19837f112c4846c236427cd36bedf9ed6a (diff)
Fix T38773: Inconsistent conversion of colors and float values in
Blender Internal shader nodes. All nodes now use the `nodestack_get_vec` function to convert whatever input values are connected to the desired type, instead of using the stack values directly regardless of what they contain. Note that this might break old node setups that have been adapted to the faulty behavior, but as discussed in the bug report the 2.70 version is the right time to fix this.
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hueSatVal.c29
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_invert.c24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c109
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c15
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c20
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.c4
7 files changed, 119 insertions, 88 deletions
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 94b667c5f6d..5e067e6c630 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -101,13 +101,15 @@ static bNodeSocketTemplate sh_node_curve_rgb_out[] = {
static void node_shader_exec_curve_rgb(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
+ float fac;
/* stack order input: vec */
/* stack order output: vec */
+ nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
curvemapping_evaluateRGBF(node->storage, out[0]->vec, vec);
- if (in[0]->vec[0] != 1.0f) {
- interp_v3_v3v3(out[0]->vec, vec, out[0]->vec, *in[0]->vec);
+ if (fac != 1.0f) {
+ interp_v3_v3v3(out[0]->vec, vec, out[0]->vec, fac);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
index e4f0e6eb80e..6fe6a33010a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
@@ -48,21 +48,21 @@ static bNodeSocketTemplate sh_node_hue_sat_out[] = {
};
/* note: it would be possible to use CMP version for both nodes */
-static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float *hue, float *sat, float *val, float *in, float *fac)
+static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat, float val, float in[4], float fac)
{
- if (*fac != 0.0f && (*hue != 0.5f || *sat != 1.0f || *val != 1.0f)) {
- float col[3], hsv[3], mfac = 1.0f - *fac;
+ if (fac != 0.0f && (hue != 0.5f || sat != 1.0f || val != 1.0f)) {
+ float col[3], hsv[3], mfac = 1.0f - fac;
rgb_to_hsv(in[0], in[1], in[2], hsv, hsv + 1, hsv + 2);
- hsv[0] += (*hue - 0.5f);
+ hsv[0] += (hue - 0.5f);
if (hsv[0] > 1.0f) hsv[0] -= 1.0f; else if (hsv[0] < 0.0f) hsv[0] += 1.0f;
- hsv[1] *= *sat;
- hsv[2] *= *val;
+ hsv[1] *= sat;
+ hsv[2] *= val;
hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col + 1, col + 2);
- out[0] = mfac * in[0] + *fac * col[0];
- out[1] = mfac * in[1] + *fac * col[1];
- out[2] = mfac * in[2] + *fac * col[2];
+ out[0] = mfac * in[0] + fac * col[0];
+ out[1] = mfac * in[1] + fac * col[1];
+ out[2] = mfac * in[2] + fac * col[2];
}
else {
copy_v4_v4(out, in);
@@ -70,8 +70,15 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float *hue, float *s
}
static void node_shader_exec_hue_sat(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
-{
- do_hue_sat_fac(node, out[0]->vec, in[0]->vec, in[1]->vec, in[2]->vec, in[4]->vec, in[3]->vec);
+{
+ float hue, sat, val, fac;
+ float col[4];
+ nodestack_get_vec(&hue, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(&sat, SOCK_FLOAT, in[1]);
+ nodestack_get_vec(&val, SOCK_FLOAT, in[2]);
+ nodestack_get_vec(&fac, SOCK_FLOAT, in[3]);
+ nodestack_get_vec(col, SOCK_RGBA, in[4]);
+ do_hue_sat_fac(node, out[0]->vec, hue, sat, val, col, fac);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c
index 6e0dbf6b87e..27450ba0fe6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_invert.c
+++ b/source/blender/nodes/shader/nodes/node_shader_invert.c
@@ -49,22 +49,20 @@ static bNodeSocketTemplate sh_node_invert_out[] = {
static void node_shader_exec_invert(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in,
bNodeStack **out)
{
- float col[3], facm;
+ float col[3], icol[3], fac;
- col[0] = 1.0f - in[1]->vec[0];
- col[1] = 1.0f - in[1]->vec[1];
- col[2] = 1.0f - in[1]->vec[2];
+ nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(col, SOCK_VECTOR, in[1]);
- /* if fac, blend result against original input */
- if (in[0]->vec[0] < 1.0f) {
- facm = 1.0f - in[0]->vec[0];
-
- col[0] = in[0]->vec[0] * col[0] + (facm * in[1]->vec[0]);
- col[1] = in[0]->vec[0] * col[1] + (facm * in[1]->vec[1]);
- col[2] = in[0]->vec[0] * col[2] + (facm * in[1]->vec[2]);
- }
+ icol[0] = 1.0f - col[0];
+ icol[1] = 1.0f - col[1];
+ icol[2] = 1.0f - col[2];
- copy_v3_v3(out[0]->vec, col);
+ /* if fac, blend result against original input */
+ if (fac < 1.0f)
+ interp_v3_v3v3(out[0]->vec, col, icol, fac);
+ else
+ copy_v3_v3(out[0]->vec, icol);
}
static int gpu_shader_invert(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index 49a7de47fc3..b6c755571c0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -47,64 +47,69 @@ static bNodeSocketTemplate sh_node_math_out[] = {
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 0: /* Add */
- out[0]->vec[0] = in[0]->vec[0] + in[1]->vec[0];
+ r = a + b;
break;
case 1: /* Subtract */
- out[0]->vec[0] = in[0]->vec[0] - in[1]->vec[0];
+ r = a - b;
break;
case 2: /* Multiply */
- out[0]->vec[0] = in[0]->vec[0] * in[1]->vec[0];
+ r = a * b;
break;
case 3: /* Divide */
{
- if (in[1]->vec[0] == 0) /* We don't want to divide by zero. */
- out[0]->vec[0] = 0.0;
+ if (b == 0) /* We don't want to divide by zero. */
+ r = 0.0;
else
- out[0]->vec[0] = in[0]->vec[0] / in[1]->vec[0];
+ r = a / b;
break;
}
case 4: /* Sine */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = sin(in[0]->vec[0]);
+ r = sin(a);
else
- out[0]->vec[0] = sin(in[1]->vec[0]);
+ r = sin(b);
break;
}
case 5: /* Cosine */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = cos(in[0]->vec[0]);
+ r = cos(a);
else
- out[0]->vec[0] = cos(in[1]->vec[0]);
+ r = cos(b);
break;
}
case 6: /* Tangent */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = tan(in[0]->vec[0]);
+ r = tan(a);
else
- out[0]->vec[0] = tan(in[1]->vec[0]);
+ r = tan(b);
break;
}
case 7: /* Arc-Sine */
{
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
/* Can't do the impossible... */
- if (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1)
- out[0]->vec[0] = asin(in[0]->vec[0]);
+ if (a <= 1 && a >= -1)
+ r = asin(a);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
else {
/* Can't do the impossible... */
- if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1)
- out[0]->vec[0] = asin(in[1]->vec[0]);
+ if (b <= 1 && b >= -1)
+ r = asin(b);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
break;
}
@@ -112,43 +117,43 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
{
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
/* Can't do the impossible... */
- if (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1)
- out[0]->vec[0] = acos(in[0]->vec[0]);
+ if (a <= 1 && a >= -1)
+ r = acos(a);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
else {
/* Can't do the impossible... */
- if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1)
- out[0]->vec[0] = acos(in[1]->vec[0]);
+ if (b <= 1 && b >= -1)
+ r = acos(b);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
break;
}
case 9: /* Arc-Tangent */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = atan(in[0]->vec[0]);
+ r = atan(a);
else
- out[0]->vec[0] = atan(in[1]->vec[0]);
+ r = atan(b);
break;
}
case 10: /* Power */
{
/* Only raise negative numbers by full integers */
- if (in[0]->vec[0] >= 0) {
- out[0]->vec[0] = pow(in[0]->vec[0], in[1]->vec[0]);
+ if (a >= 0) {
+ r = pow(a, b);
}
else {
- float y_mod_1 = fabsf(fmodf(in[1]->vec[0], 1.0f));
+ 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) {
- out[0]->vec[0] = powf(in[0]->vec[0], floorf(in[1]->vec[0] + 0.5f));
+ r = powf(a, floorf(b + 0.5f));
}
else {
- out[0]->vec[0] = 0.0f;
+ r = 0.0f;
}
}
@@ -157,61 +162,63 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
case 11: /* Logarithm */
{
/* Don't want any imaginary numbers... */
- if (in[0]->vec[0] > 0 && in[1]->vec[0] > 0)
- out[0]->vec[0] = log(in[0]->vec[0]) / log(in[1]->vec[0]);
+ if (a > 0 && b > 0)
+ r = log(a) / log(b);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
break;
}
case 12: /* Minimum */
{
- if (in[0]->vec[0] < in[1]->vec[0])
- out[0]->vec[0] = in[0]->vec[0];
+ if (a < b)
+ r = a;
else
- out[0]->vec[0] = in[1]->vec[0];
+ r = b;
break;
}
case 13: /* Maximum */
{
- if (in[0]->vec[0] > in[1]->vec[0])
- out[0]->vec[0] = in[0]->vec[0];
+ if (a > b)
+ r = a;
else
- out[0]->vec[0] = in[1]->vec[0];
+ r = b;
break;
}
case 14: /* Round */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = (in[0]->vec[0] < 0) ? (int)(in[0]->vec[0] - 0.5f) : (int)(in[0]->vec[0] + 0.5f);
+ r = (a < 0) ? (int)(a - 0.5f) : (int)(a + 0.5f);
else
- out[0]->vec[0] = (in[1]->vec[0] < 0) ? (int)(in[1]->vec[0] - 0.5f) : (int)(in[1]->vec[0] + 0.5f);
+ r = (b < 0) ? (int)(b - 0.5f) : (int)(b + 0.5f);
break;
}
case 15: /* Less Than */
{
- if (in[0]->vec[0] < in[1]->vec[0])
- out[0]->vec[0] = 1.0f;
+ if (a < b)
+ r = 1.0f;
else
- out[0]->vec[0] = 0.0f;
+ r = 0.0f;
break;
}
case 16: /* Greater Than */
{
- if (in[0]->vec[0] > in[1]->vec[0])
- out[0]->vec[0] = 1.0f;
+ if (a > b)
+ r = 1.0f;
else
- out[0]->vec[0] = 0.0f;
+ r = 0.0f;
break;
}
case 17: /* Modulo */
{
- if (in[1]->vec[0] == 0.0f)
- out[0]->vec[0] = 0.0f;
+ if (b == 0.0f)
+ r = 0.0f;
else
- out[0]->vec[0] = fmod(in[0]->vec[0], in[1]->vec[0]);
+ r = fmod(a, b);
break;
}
}
+
+ out[0]->vec[0] = r;
}
static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
index 2c515d587c0..b5b15397595 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
@@ -46,8 +46,11 @@ static bNodeSocketTemplate sh_node_sephsv_out[] = {
static void node_shader_exec_sephsv(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- rgb_to_hsv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2],
- &out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]);
+ float col[3];
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
+
+ rgb_to_hsv(col[0], col[1], col[2],
+ &out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]);
}
static int gpu_shader_sephsv(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -83,8 +86,12 @@ static bNodeSocketTemplate sh_node_combhsv_out[] = {
static void node_shader_exec_combhsv(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- hsv_to_rgb(in[0]->vec[0], in[1]->vec[0], in[2]->vec[0],
- &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
+ float h, s, v;
+ nodestack_get_vec(&h, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(&s, SOCK_FLOAT, in[1]);
+ nodestack_get_vec(&v, SOCK_FLOAT, in[2]);
+
+ hsv_to_rgb(h, s, v, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
}
static int gpu_shader_combhsv(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
index a3cbd14a90f..006ba34c3f3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
@@ -46,9 +46,12 @@ static bNodeSocketTemplate sh_node_seprgb_out[] = {
static void node_shader_exec_seprgb(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- out[0]->vec[0] = in[0]->vec[0];
- out[1]->vec[0] = in[0]->vec[1];
- out[2]->vec[0] = in[0]->vec[2];
+ float col[3];
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
+
+ out[0]->vec[0] = col[0];
+ out[1]->vec[0] = col[1];
+ out[2]->vec[0] = col[2];
}
static int gpu_shader_seprgb(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -85,9 +88,14 @@ static bNodeSocketTemplate sh_node_combrgb_out[] = {
static void node_shader_exec_combrgb(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- out[0]->vec[0] = in[0]->vec[0];
- out[0]->vec[1] = in[1]->vec[0];
- out[0]->vec[2] = in[2]->vec[0];
+ float r, g, b;
+ nodestack_get_vec(&r, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(&g, SOCK_FLOAT, in[1]);
+ nodestack_get_vec(&b, SOCK_FLOAT, in[2]);
+
+ out[0]->vec[0] = r;
+ out[0]->vec[1] = g;
+ out[0]->vec[2] = b;
}
static int gpu_shader_combrgb(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
index 1e402b3728b..fa5d9b43ee7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
@@ -103,8 +103,10 @@ static void node_shader_exec_rgbtobw(void *UNUSED(data), int UNUSED(thread), bNo
{
/* stack order out: bw */
/* stack order in: col */
+ float col[3];
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
- out[0]->vec[0] = rgb_to_bw(in[0]->vec);
+ out[0]->vec[0] = rgb_to_bw(col);
}
static int gpu_shader_rgbtobw(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)