Exemple #1
0
static void node_shader_exec_output(void *data, bNode *node, 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) {
			nodeAddToPreview(node, 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);
		}
	}	
}
void tex_do_preview(bNode *node, const float coord[2], const float col[4])
{
	bNodePreview *preview = node->preview;

	if (preview) {
		int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize;
		int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize;

		nodeAddToPreview(node, col, xs, ys, 0); /* 0 = no color management */
	}
}
Exemple #3
0
static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	if(data && node->id) {
		ShadeInput *shi= ((ShaderCallData *)data)->shi;
		TexResult texres;
		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;
		
		if(in[0]->hasinput) {
			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);
			}
			else if(in[0]->datatype==NS_OSA_VALUES) {
				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);
			}
			else
				retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL);
		}
		else {
			VECCOPY(vec, shi->lo);
			retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, 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) {
			out[1]->vec[0]= out[0]->vec[0];
			out[1]->vec[1]= out[0]->vec[0];
			out[1]->vec[2]= out[0]->vec[0];
			out[1]->vec[3]= 1.0f;
		}
		else {
			out[1]->vec[0]= texres.tr;
			out[1]->vec[1]= texres.tg;
			out[1]->vec[2]= texres.tb;
			out[1]->vec[3]= 1.0f;
		}
		
		VECCOPY(out[2]->vec, nor);
		
		if(shi->do_preview)
			nodeAddToPreview(node, out[1]->vec, shi->xs, shi->ys, shi->do_manage);
		
	}
}
static void node_shader_exec_material(void *data, bNode *node, 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)
			nodeAddToPreview(node, 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.diff);
			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;
		}
	}
}
Exemple #5
0
static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	if(data && node->id) {
		ShadeResult shrnode;
		ShadeInput *shi;
		ShaderCallData *shcd= data;
		float col[4];
		
		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(in[MAT_IN_COLOR]->hasinput)
			nodestack_get_vec(&shi->r, SOCK_VECTOR, in[MAT_IN_COLOR]);
		
		if(in[MAT_IN_SPEC]->hasinput)
			nodestack_get_vec(&shi->specr, SOCK_VECTOR, in[MAT_IN_SPEC]);
		
		if(in[MAT_IN_REFL]->hasinput)
			nodestack_get_vec(&shi->refl, SOCK_VALUE, in[MAT_IN_REFL]);
		
		/* retrieve normal */
		if(in[MAT_IN_NORMAL]->hasinput) {
			nodestack_get_vec(shi->vn, SOCK_VECTOR, in[MAT_IN_NORMAL]);
			normalize_v3(shi->vn);
		}
		else
			VECCOPY(shi->vn, shi->vno);
		
		/* custom option to flip normal */
		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];
		}
		
		if (node->type == SH_NODE_MATERIAL_EXT) {
			if(in[MAT_IN_MIR]->hasinput)
				nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]);
			if(in[MAT_IN_AMB]->hasinput)
				nodestack_get_vec(&shi->amb, SOCK_VALUE, in[MAT_IN_AMB]);
			if(in[MAT_IN_EMIT]->hasinput)
				nodestack_get_vec(&shi->emit, SOCK_VALUE, in[MAT_IN_EMIT]);
			if(in[MAT_IN_SPECTRA]->hasinput)
				nodestack_get_vec(&shi->spectra, SOCK_VALUE, in[MAT_IN_SPECTRA]);
			if(in[MAT_IN_RAY_MIRROR]->hasinput)
				nodestack_get_vec(&shi->ray_mirror, SOCK_VALUE, in[MAT_IN_RAY_MIRROR]);
			if(in[MAT_IN_ALPHA]->hasinput)
				nodestack_get_vec(&shi->alpha, SOCK_VALUE, in[MAT_IN_ALPHA]);
			if(in[MAT_IN_TRANSLUCENCY]->hasinput)
				nodestack_get_vec(&shi->translucency, SOCK_VALUE, in[MAT_IN_TRANSLUCENCY]);			
		}
		
		shi->nodes= 1; /* temp hack to prevent trashadow recursion */
		node_shader_lamp_loop(shi, &shrnode);	/* clears shrnode */
		shi->nodes= 0;
		
		/* write to outputs */
		if(node->custom1 & SH_NODE_MAT_DIFF) {
			VECCOPY(col, shrnode.combined);
			if(!(node->custom1 & SH_NODE_MAT_SPEC)) {
				sub_v3_v3(col, shrnode.spec);
			}
		}
		else if(node->custom1 & SH_NODE_MAT_SPEC) {
			VECCOPY(col, shrnode.spec);
		}
		else
			col[0]= col[1]= col[2]= 0.0f;
		
		col[3]= shrnode.alpha;
		
		if(shi->do_preview)
			nodeAddToPreview(node, col, shi->xs, shi->ys);
		
		VECCOPY(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];
		}
		
		VECCOPY(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 :( */
			VECCOPY(out[MAT_OUT_DIFFUSE]->vec, shrnode.diff);
			VECCOPY(out[MAT_OUT_SPEC]->vec, shrnode.spec);
			VECCOPY(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;
		}
	}
}