static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), 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 (hasinput[MAT_IN_COLOR]) shi.rgb = gpu_get_input_link(&in[MAT_IN_COLOR]); if (hasinput[MAT_IN_SPEC]) shi.specrgb = gpu_get_input_link(&in[MAT_IN_SPEC]); if (hasinput[MAT_IN_REFL]) shi.refl = gpu_get_input_link(&in[MAT_IN_REFL]); /* retrieve normal */ if (hasinput[MAT_IN_NORMAL]) { GPUNodeLink *tmp; shi.vn = gpu_get_input_link(&in[MAT_IN_NORMAL]); GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp); } /* custom option to flip normal */ if (node->custom1 & SH_NODE_MAT_NEG) GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); if (node->type == SH_NODE_MATERIAL_EXT) { if (hasinput[MAT_IN_MIR]) shi.mir = gpu_get_input_link(&in[MAT_IN_MIR]); 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_SPECTRA]) shi.spectra = gpu_get_input_link(&in[MAT_IN_SPECTRA]); if (hasinput[MAT_IN_ALPHA]) shi.alpha = gpu_get_input_link(&in[MAT_IN_ALPHA]); } GPU_shaderesult_set(&shi, &shr); /* clears shr */ /* write to outputs */ if (node->custom1 & SH_NODE_MAT_DIFF) { out[MAT_OUT_COLOR].link = shr.combined; if (!(node->custom1 & SH_NODE_MAT_SPEC)) { GPUNodeLink *link; GPU_link(mat, "vec_math_sub", shr.combined, shr.spec, &out[MAT_OUT_COLOR].link, &link); } } else if (node->custom1 & SH_NODE_MAT_SPEC) { out[MAT_OUT_COLOR].link = shr.spec; } else GPU_link(mat, "set_rgb_zero", &out[MAT_OUT_COLOR].link); GPU_link(mat, "mtex_alpha_to_col", out[MAT_OUT_COLOR].link, shr.alpha, &out[MAT_OUT_COLOR].link); out[MAT_OUT_ALPHA].link = shr.alpha; // if (node->custom1 & SH_NODE_MAT_NEG) GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); out[MAT_OUT_NORMAL].link = shi.vn; if (node->type == SH_NODE_MATERIAL_EXT) { out[MAT_OUT_DIFFUSE].link = shr.diff; out[MAT_OUT_SPEC].link = shr.spec; GPU_link(mat, "set_rgb_one", &out[MAT_OUT_AO].link); } return 1; } return 0; }
static int gpu_shader_material(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { if(node->id) { GPUShadeInput shi; GPUShadeResult shr; GPU_shadeinput_set(mat, (Material*)node->id, &shi); /* write values */ if(in[MAT_IN_COLOR].hasinput) shi.rgb = in[MAT_IN_COLOR].link; if(in[MAT_IN_SPEC].hasinput) shi.specrgb = in[MAT_IN_SPEC].link; if(in[MAT_IN_REFL].hasinput) shi.refl = in[MAT_IN_REFL].link; /* retrieve normal */ if(in[MAT_IN_NORMAL].hasinput) { GPUNodeLink *tmp; shi.vn = in[MAT_IN_NORMAL].link; GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp); } /* custom option to flip normal */ if(node->custom1 & SH_NODE_MAT_NEG) 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; } GPU_shaderesult_set(&shi, &shr); /* clears shr */ /* write to outputs */ if(node->custom1 & SH_NODE_MAT_DIFF) { out[MAT_OUT_COLOR].link= shr.combined; if(!(node->custom1 & SH_NODE_MAT_SPEC)) { GPUNodeLink *link; GPU_link(mat, "vec_math_sub", shr.combined, shr.spec, &out[MAT_OUT_COLOR].link, &link); } } else if(node->custom1 & SH_NODE_MAT_SPEC) { out[MAT_OUT_COLOR].link= shr.spec; } else GPU_link(mat, "set_rgb_zero", &out[MAT_OUT_COLOR].link); GPU_link(mat, "mtex_alpha_to_col", out[MAT_OUT_COLOR].link, shr.alpha, &out[MAT_OUT_COLOR].link); out[MAT_OUT_ALPHA].link = shr.alpha; // if(node->custom1 & SH_NODE_MAT_NEG) GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); out[MAT_OUT_NORMAL].link = shi.vn; if (node->type == SH_NODE_MATERIAL_EXT) { out[MAT_OUT_DIFFUSE].link = shr.diff; out[MAT_OUT_SPEC].link = shr.spec; } return 1; } return 0; }