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:
Diffstat (limited to 'source/blender/nodes/intern/SHD_nodes/SHD_material.c')
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_material.c82
1 files changed, 57 insertions, 25 deletions
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
index 40dfbc0edea..f78dd9ec727 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
@@ -85,6 +85,17 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
ShadeInput *shi;
ShaderCallData *shcd= data;
float col[4];
+ bNodeSocket *sock;
+ char hasinput[NUM_MAT_IN]= {'\0'};
+ int i;
+
+ /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily
+ * the constant input stack values (e.g. in case material node is inside a group).
+ * we just want to know if a node input uses external data or the material setting.
+ * this is an ugly hack, but so is this node as a whole.
+ */
+ for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i)
+ hasinput[i] = (sock->link != NULL);
shi= shcd->shi;
shi->mat= (Material *)node->id;
@@ -94,17 +105,17 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
shi->har= shi->mat->har;
/* write values */
- if(in[MAT_IN_COLOR]->hasinput)
+ if(hasinput[MAT_IN_COLOR])
nodestack_get_vec(&shi->r, SOCK_VECTOR, in[MAT_IN_COLOR]);
- if(in[MAT_IN_SPEC]->hasinput)
+ if(hasinput[MAT_IN_SPEC])
nodestack_get_vec(&shi->specr, SOCK_VECTOR, in[MAT_IN_SPEC]);
- if(in[MAT_IN_REFL]->hasinput)
+ if(hasinput[MAT_IN_REFL])
nodestack_get_vec(&shi->refl, SOCK_VALUE, in[MAT_IN_REFL]);
/* retrieve normal */
- if(in[MAT_IN_NORMAL]->hasinput) {
+ if(hasinput[MAT_IN_NORMAL]) {
nodestack_get_vec(shi->vn, SOCK_VECTOR, in[MAT_IN_NORMAL]);
normalize_v3(shi->vn);
}
@@ -119,19 +130,19 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
}
if (node->type == SH_NODE_MATERIAL_EXT) {
- if(in[MAT_IN_MIR]->hasinput)
+ if(hasinput[MAT_IN_MIR])
nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]);
- if(in[MAT_IN_AMB]->hasinput)
+ if(hasinput[MAT_IN_AMB])
nodestack_get_vec(&shi->amb, SOCK_VALUE, in[MAT_IN_AMB]);
- if(in[MAT_IN_EMIT]->hasinput)
+ if(hasinput[MAT_IN_EMIT])
nodestack_get_vec(&shi->emit, SOCK_VALUE, in[MAT_IN_EMIT]);
- if(in[MAT_IN_SPECTRA]->hasinput)
+ if(hasinput[MAT_IN_SPECTRA])
nodestack_get_vec(&shi->spectra, SOCK_VALUE, in[MAT_IN_SPECTRA]);
- if(in[MAT_IN_RAY_MIRROR]->hasinput)
+ if(hasinput[MAT_IN_RAY_MIRROR])
nodestack_get_vec(&shi->ray_mirror, SOCK_VALUE, in[MAT_IN_RAY_MIRROR]);
- if(in[MAT_IN_ALPHA]->hasinput)
+ if(hasinput[MAT_IN_ALPHA])
nodestack_get_vec(&shi->alpha, SOCK_VALUE, in[MAT_IN_ALPHA]);
- if(in[MAT_IN_TRANSLUCENCY]->hasinput)
+ if(hasinput[MAT_IN_TRANSLUCENCY])
nodestack_get_vec(&shi->translucency, SOCK_VALUE, in[MAT_IN_TRANSLUCENCY]);
}
@@ -198,28 +209,49 @@ static void node_shader_init_material(bNode* node)
node->custom1= SH_NODE_MAT_DIFF|SH_NODE_MAT_SPEC;
}
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
+{
+ if (in->link)
+ return in->link;
+ else
+ return GPU_uniform(in->vec);
+}
+
static int gpu_shader_material(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out)
{
if(node->id) {
GPUShadeInput shi;
GPUShadeResult shr;
+ bNodeSocket *sock;
+ char hasinput[NUM_MAT_IN]= {'\0'};
+ int i;
+
+ /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily
+ * the constant input stack values (e.g. in case material node is inside a group).
+ * we just want to know if a node input uses external data or the material setting.
+ */
+ for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i)
+ hasinput[i] = (sock->link != NULL);
GPU_shadeinput_set(mat, (Material*)node->id, &shi);
/* write values */
- if(in[MAT_IN_COLOR].hasinput)
- shi.rgb = in[MAT_IN_COLOR].link;
+ if(hasinput[MAT_IN_COLOR])
+ shi.rgb = gpu_get_input_link(&in[MAT_IN_COLOR]);
- if(in[MAT_IN_SPEC].hasinput)
- shi.specrgb = in[MAT_IN_SPEC].link;
+ if(hasinput[MAT_IN_SPEC])
+ shi.specrgb = gpu_get_input_link(&in[MAT_IN_SPEC]);
- if(in[MAT_IN_REFL].hasinput)
- shi.refl = in[MAT_IN_REFL].link;
+ if(hasinput[MAT_IN_REFL])
+ shi.refl = gpu_get_input_link(&in[MAT_IN_REFL]);
/* retrieve normal */
- if(in[MAT_IN_NORMAL].hasinput) {
+ if(hasinput[MAT_IN_NORMAL]) {
GPUNodeLink *tmp;
- shi.vn = in[MAT_IN_NORMAL].link;
+ shi.vn = gpu_get_input_link(&in[MAT_IN_NORMAL]);
GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp);
}
@@ -228,12 +260,12 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, GPUNodeStack *in,
GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
if (node->type == SH_NODE_MATERIAL_EXT) {
- if(in[MAT_IN_AMB].hasinput)
- shi.amb= in[MAT_IN_AMB].link;
- if(in[MAT_IN_EMIT].hasinput)
- shi.emit= in[MAT_IN_EMIT].link;
- if(in[MAT_IN_ALPHA].hasinput)
- shi.alpha= in[MAT_IN_ALPHA].link;
+ if(hasinput[MAT_IN_AMB])
+ shi.amb= gpu_get_input_link(&in[MAT_IN_AMB]);
+ if(hasinput[MAT_IN_EMIT])
+ shi.emit= gpu_get_input_link(&in[MAT_IN_EMIT]);
+ if(hasinput[MAT_IN_ALPHA])
+ shi.alpha= gpu_get_input_link(&in[MAT_IN_ALPHA]);
}
GPU_shaderesult_set(&shi, &shr); /* clears shr */