Exemple #1
0
static void node_shader_exec_output(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out))
{
	if (data) {
		ShadeInput *shi= ((ShaderCallData *)data)->shi;
		float col[4];
		
		/* stack order input sockets: col, alpha, normal */
		nodestack_get_vec(col, SOCK_VECTOR, in[0]);
		nodestack_get_vec(col+3, SOCK_FLOAT, in[1]);
		
		if (shi->do_preview) {
			BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage);
			node->lasty= shi->ys;
		}
		
		if (node->flag & NODE_DO_OUTPUT) {
			ShadeResult *shr= ((ShaderCallData *)data)->shr;
			
			copy_v4_v4(shr->combined, col);
			shr->alpha= col[3];
			
			//	copy_v3_v3(shr->nor, in[3]->vec);
		}
	}
}
Exemple #2
0
void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4])
{
	if (preview) {
		int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize;
		int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize;
		
		BKE_node_preview_set_pixel(preview, col, xs, ys, 0); /* 0 = no color management */
	}
}
static void node_shader_exec_material(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
	if (data && node->id) {
		ShadeResult shrnode;
		ShadeInput *shi;
		ShaderCallData *shcd = data;
		float col[4];
		bNodeSocket *sock;
		char hasinput[NUM_MAT_IN] = {'\0'};
		int i, mode;
		
		/* 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;
		
		/* copy all relevant material vars, note, keep this synced with render_types.h */
		memcpy(&shi->r, &shi->mat->r, 23 * sizeof(float));
		shi->har = shi->mat->har;
		
		/* write values */
		if (hasinput[MAT_IN_COLOR])
			nodestack_get_vec(&shi->r, SOCK_VECTOR, in[MAT_IN_COLOR]);
		
		if (hasinput[MAT_IN_SPEC])
			nodestack_get_vec(&shi->specr, SOCK_VECTOR, in[MAT_IN_SPEC]);
		
		if (hasinput[MAT_IN_REFL])
			nodestack_get_vec(&shi->refl, SOCK_FLOAT, in[MAT_IN_REFL]);
		
		/* retrieve normal */
		if (hasinput[MAT_IN_NORMAL]) {
			nodestack_get_vec(shi->vn, SOCK_VECTOR, in[MAT_IN_NORMAL]);
			normalize_v3(shi->vn);
		}
		else
			copy_v3_v3(shi->vn, shi->vno);
		
		/* custom option to flip normal */
		if (node->custom1 & SH_NODE_MAT_NEG) {
			negate_v3(shi->vn);
		}
		
		if (node->type == SH_NODE_MATERIAL_EXT) {
			if (hasinput[MAT_IN_MIR])
				nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]);
			if (hasinput[MAT_IN_AMB])
				nodestack_get_vec(&shi->amb, SOCK_FLOAT, in[MAT_IN_AMB]);
			if (hasinput[MAT_IN_EMIT])
				nodestack_get_vec(&shi->emit, SOCK_FLOAT, in[MAT_IN_EMIT]);
			if (hasinput[MAT_IN_SPECTRA])
				nodestack_get_vec(&shi->spectra, SOCK_FLOAT, in[MAT_IN_SPECTRA]);
			if (hasinput[MAT_IN_RAY_MIRROR])
				nodestack_get_vec(&shi->ray_mirror, SOCK_FLOAT, in[MAT_IN_RAY_MIRROR]);
			if (hasinput[MAT_IN_ALPHA])
				nodestack_get_vec(&shi->alpha, SOCK_FLOAT, in[MAT_IN_ALPHA]);
			if (hasinput[MAT_IN_TRANSLUCENCY])
				nodestack_get_vec(&shi->translucency, SOCK_FLOAT, in[MAT_IN_TRANSLUCENCY]);
		}
		
		/* make alpha output give results even if transparency is only enabled on
		 * the material linked in this not and not on the parent material */
		mode = shi->mode;
		if (shi->mat->mode & MA_TRANSP)
			shi->mode |= MA_TRANSP;

		shi->nodes = 1; /* temp hack to prevent trashadow recursion */
		node_shader_lamp_loop(shi, &shrnode);   /* clears shrnode */
		shi->nodes = 0;
		
		shi->mode = mode;

		/* write to outputs */
		if (node->custom1 & SH_NODE_MAT_DIFF) {
			copy_v3_v3(col, shrnode.combined);
			if (!(node->custom1 & SH_NODE_MAT_SPEC)) {
				sub_v3_v3(col, shrnode.spec);
			}
		}
		else if (node->custom1 & SH_NODE_MAT_SPEC) {
			copy_v3_v3(col, shrnode.spec);
		}
		else
			col[0] = col[1] = col[2] = 0.0f;
		
		col[3] = shrnode.alpha;
		
		if (shi->do_preview)
			BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage);
		
		copy_v3_v3(out[MAT_OUT_COLOR]->vec, col);
		out[MAT_OUT_ALPHA]->vec[0] = shrnode.alpha;
		
		if (node->custom1 & SH_NODE_MAT_NEG) {
			shi->vn[0] = -shi->vn[0];
			shi->vn[1] = -shi->vn[1];
			shi->vn[2] = -shi->vn[2];
		}
		
		copy_v3_v3(out[MAT_OUT_NORMAL]->vec, shi->vn);
		
		/* Extended material options */
		if (node->type == SH_NODE_MATERIAL_EXT) {
			/* Shadow, Reflect, Refract, Radiosity, Speed seem to cause problems inside
			 * a node tree :( */
			copy_v3_v3(out[MAT_OUT_DIFFUSE]->vec, shrnode.diffshad);
			copy_v3_v3(out[MAT_OUT_SPEC]->vec, shrnode.spec);
			copy_v3_v3(out[MAT_OUT_AO]->vec, shrnode.ao);
		}
		
		/* copy passes, now just active node */
		if (node->flag & NODE_ACTIVE_ID) {
			float combined[4], alpha;

			copy_v4_v4(combined, shcd->shr->combined);
			alpha = shcd->shr->alpha;

			*(shcd->shr) = shrnode;

			copy_v4_v4(shcd->shr->combined, combined);
			shcd->shr->alpha = alpha;
		}
	}
}
static void node_shader_exec_texture(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
	if (data && node->id) {
		ShadeInput *shi = ((ShaderCallData *)data)->shi;
		TexResult texres;
		bNodeSocket *sock_vector = node->inputs.first;
		float vec[3], nor[3] = {0.0f, 0.0f, 0.0f};
		int retval;
		short which_output = node->custom1;
		
		short thread = shi->thread;
		
		/* out: value, color, normal */
		
		/* we should find out if a normal as output is needed, for now we do all */
		texres.nor = nor;
		texres.tr = texres.tg = texres.tb = 0.0f;
		
		/* don't use in[0]->hasinput, see material node for explanation */
		if (sock_vector->link) {
			nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
			
			if (in[0]->datatype == NS_OSA_VECTORS) {
				float *fp = in[0]->data;
				retval = multitex_nodes((Tex *)node->id, vec, fp, fp + 3, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
			}
			else if (in[0]->datatype == NS_OSA_VALUES) {
				const float *fp = in[0]->data;
				float dxt[3], dyt[3];
				
				dxt[0] = fp[0]; dxt[1] = dxt[2] = 0.0f;
				dyt[0] = fp[1]; dyt[1] = dyt[2] = 0.0f;
				retval = multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
			}
			else
				retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
		}
		else {
			copy_v3_v3(vec, shi->lo);
			retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
		}
		
		/* stupid exception */
		if ( ((Tex *)node->id)->type == TEX_STUCCI) {
			texres.tin = 0.5f + 0.7f * texres.nor[0];
			CLAMP(texres.tin, 0.0f, 1.0f);
		}
		
		/* intensity and color need some handling */
		if (texres.talpha)
			out[0]->vec[0] = texres.ta;
		else
			out[0]->vec[0] = texres.tin;
		
		if ((retval & TEX_RGB) == 0) {
			copy_v3_fl(out[1]->vec, out[0]->vec[0]);
			out[1]->vec[3] = 1.0f;
		}
		else {
			copy_v3_v3(out[1]->vec, &texres.tr);
			out[1]->vec[3] = 1.0f;
		}
		
		copy_v3_v3(out[2]->vec, nor);
		
		if (shi->do_preview) {
			BKE_node_preview_set_pixel(execdata->preview, out[1]->vec, shi->xs, shi->ys, shi->do_manage);
		}
		
	}
}