示例#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);
		}
	}	
}
static void node_shader_exec_squeeze(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
	float vec[3];
	
	nodestack_get_vec(vec, SOCK_FLOAT, in[0]);
	nodestack_get_vec(vec + 1, SOCK_FLOAT, in[1]);
	nodestack_get_vec(vec + 2, SOCK_FLOAT, in[2]);

	out[0]->vec[0] = 1.0f / (1.0f + powf(M_E, -((vec[0] - vec[2]) * vec[1])));
}
示例#3
0
static void node_shader_exec_vect_math(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 
{ 
	float vec1[3], vec2[3];
	
	nodestack_get_vec(vec1, SOCK_VECTOR, in[0]);
	nodestack_get_vec(vec2, SOCK_VECTOR, in[1]);
	
	if(node->custom1 == 0) {	/* Add */
		out[0]->vec[0]= vec1[0] + vec2[0];
		out[0]->vec[1]= vec1[1] + vec2[1];
		out[0]->vec[2]= vec1[2] + vec2[2];
		
		out[1]->vec[0]= (fabs(out[0]->vec[0]) + fabs(out[0]->vec[0]) + fabs(out[0]->vec[0])) / 3;
	}
	else if(node->custom1 == 1) {	/* Subtract */
		out[0]->vec[0]= vec1[0] - vec2[0];
		out[0]->vec[1]= vec1[1] - vec2[1];
		out[0]->vec[2]= vec1[2] - vec2[2];
		
		out[1]->vec[0]= (fabs(out[0]->vec[0]) + fabs(out[0]->vec[0]) + fabs(out[0]->vec[0])) / 3;
	}
	else if(node->custom1 == 2) {	/* Average */
		out[0]->vec[0]= vec1[0] + vec2[0];
		out[0]->vec[1]= vec1[1] + vec2[1];
		out[0]->vec[2]= vec1[2] + vec2[2];
		
		out[1]->vec[0] = normalize_v3( out[0]->vec );
	}
	else if(node->custom1 == 3) {	/* Dot product */
		out[1]->vec[0]= (vec1[0] * vec2[0]) + (vec1[1] * vec2[1]) + (vec1[2] * vec2[2]);
	}
	else if(node->custom1 == 4) {	/* Cross product */
		out[0]->vec[0]= (vec1[1] * vec2[2]) - (vec1[2] * vec2[1]);
		out[0]->vec[1]= (vec1[2] * vec2[0]) - (vec1[0] * vec2[2]);
		out[0]->vec[2]= (vec1[0] * vec2[1]) - (vec1[1] * vec2[0]);
		
		out[1]->vec[0] = normalize_v3( out[0]->vec );
	}
	else if(node->custom1 == 5) {	/* Normalize */
		if(in[0]->hasinput || !in[1]->hasinput) {	/* This one only takes one input, so we've got to choose. */
			out[0]->vec[0]= vec1[0];
			out[0]->vec[1]= vec1[1];
			out[0]->vec[2]= vec1[2];
		}
		else {
			out[0]->vec[0]= vec2[0];
			out[0]->vec[1]= vec2[1];
			out[0]->vec[2]= vec2[2];
		}
		
		out[1]->vec[0] = normalize_v3( out[0]->vec );
	}
	
}
示例#4
0
static void node_shader_exec_gamma(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
	float col[3];
	float gamma;
	nodestack_get_vec(col, SOCK_VECTOR, in[0]);
	nodestack_get_vec(&gamma, SOCK_FLOAT, in[1]);

	out[0]->vec[0] = col[0] > 0.0f ? powf(col[0], gamma) : col[0];
	out[0]->vec[1] = col[1] > 0.0f ? powf(col[1], gamma) : col[1];
	out[0]->vec[2] = col[2] > 0.0f ? powf(col[2], gamma) : col[2];
}
示例#5
0
static void node_shader_exec_combrgb(void *UNUSED(data),
                                     int UNUSED(thread),
                                     bNode *UNUSED(node),
                                     bNodeExecData *UNUSED(execdata),
                                     bNodeStack **in,
                                     bNodeStack **out)
{
  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;
}
void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
{
	memset(gs, 0, sizeof(*gs));
	
	nodestack_get_vec(gs->vec, type, ns);
	gs->link = ns->data;
	
	if (type == SOCK_FLOAT)
		gs->type = GPU_FLOAT;
	else if (type == SOCK_VECTOR)
		gs->type = GPU_VEC3;
	else if (type == SOCK_RGBA)
		gs->type = GPU_VEC4;
	else if (type == SOCK_SHADER)
		gs->type = GPU_VEC4;
	else
		gs->type = GPU_NONE;
	
	gs->name = "";
	gs->hasinput = ns->hasinput && ns->data;
	/* XXX Commented out the ns->data check here, as it seems it's not always set,
	 *     even though there *is* a valid connection/output... But that might need
	 *     further investigation.
	 */
	gs->hasoutput = ns->hasoutput /*&& ns->data*/;
	gs->sockettype = ns->sockettype;
}
示例#7
0
static void node_shader_exec_mix_rgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: fac, col1, col2 */
	/* stack order out: col */
	float col[3];
	float fac;
	float vec[3];

	nodestack_get_vec(&fac, SOCK_VALUE, in[0]);
	CLAMP(fac, 0.0f, 1.0f);
	
	nodestack_get_vec(col, SOCK_VECTOR, in[1]);
	nodestack_get_vec(vec, SOCK_VECTOR, in[2]);

	ramp_blend(node->custom1, col, col+1, col+2, fac, vec);
	VECCOPY(out[0]->vec, col);
}
static void node_shader_exec_rgbtobw(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
	/* stack order out: bw */
	/* stack order in: col */
	float col[3];
	nodestack_get_vec(col, SOCK_VECTOR, in[0]);

	out[0]->vec[0] = IMB_colormanagement_get_luminance(col);
}
示例#9
0
static void node_shader_exec_curve_vec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	float vec[3];
	
	/* stack order input:  vec */
	/* stack order output: vec */
	nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
	curvemapping_evaluate3F(node->storage, out[0]->vec, vec);
}
示例#10
0
static void node_shader_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	float vec[3];
	
	/* stack order input:  vec */
	/* stack order output: vec */
	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);
	}
}
示例#11
0
/* generates normal, does dot product */
static void node_shader_exec_normal(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
	float vec[3];
	
	/* stack order input:  normal */
	/* stack order output: normal, value */
	
	nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
	
	/* render normals point inside... the widget points outside */
	out[1]->vec[0] = -dot_v3v3(vec, out[0]->vec);
}
示例#12
0
static void node_shader_exec_valtorgb(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
	/* stack order in: fac */
	/* stack order out: col, alpha */

	if (node->storage) {
		float fac;
		nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);

		BKE_colorband_evaluate(node->storage, fac, out[0]->vec);
		out[1]->vec[0] = out[0]->vec[3];
	}
}
示例#13
0
static void node_shader_exec_valtorgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: fac */
	/* stack order out: col, alpha */
	
	if(node->storage) {
		float fac;
		nodestack_get_vec(&fac, SOCK_VALUE, in[0]);

		do_colorband(node->storage, fac, out[0]->vec);
		out[1]->vec[0]= out[0]->vec[3];
	}
}
示例#14
0
/* generates normal, does dot product */
static void node_shader_exec_normal(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	bNodeSocket *sock= node->outputs.first;
	float vec[3];
	
	/* stack order input:  normal */
	/* stack order output: normal, value */
	
	nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
	
	copy_v3_v3(out[0]->vec, ((bNodeSocketValueVector*)sock->default_value)->value);
	/* render normals point inside... the widget points outside */
	out[1]->vec[0]= -INPR(out[0]->vec, vec);
}
示例#15
0
文件: SHD_normal.c 项目: jinjoh/NOOR
/* generates normal, does dot product */
static void node_shader_exec_normal(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	bNodeSocket *sock= node->outputs.first;
	float vec[3];
	
	/* stack order input:  normal */
	/* stack order output: normal, value */
	
	nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
	
	VECCOPY(out[0]->vec, sock->ns.vec);
	/* render normals point inside... the widget points outside */
	out[1]->vec[0]= -INPR(out[0]->vec, vec);
}
示例#16
0
static void node_shader_exec_seprgb(void *UNUSED(data),
                                    int UNUSED(thread),
                                    bNode *UNUSED(node),
                                    bNodeExecData *UNUSED(execdata),
                                    bNodeStack **in,
                                    bNodeStack **out)
{
  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];
}
示例#17
0
/* do the regular mapping options for blender textures */
static void node_shader_exec_mapping(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	TexMapping *texmap= node->storage;
	float *vec= out[0]->vec;
	
	/* stack order input:  vector */
	/* stack order output: vector */
	nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
	mul_m4_v3(texmap->mat, vec);
	
	if (texmap->flag & TEXMAP_CLIP_MIN) {
		if (vec[0]<texmap->min[0]) vec[0]= texmap->min[0];
		if (vec[1]<texmap->min[1]) vec[1]= texmap->min[1];
		if (vec[2]<texmap->min[2]) vec[2]= texmap->min[2];
	}
	if (texmap->flag & TEXMAP_CLIP_MAX) {
		if (vec[0]>texmap->max[0]) vec[0]= texmap->max[0];
		if (vec[1]>texmap->max[1]) vec[1]= texmap->max[1];
		if (vec[2]>texmap->max[2]) vec[2]= texmap->max[2];
	}
}
示例#18
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;
		}
	}
}
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);
		}
		
	}
}
示例#20
0
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_normal_map(
        void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata),
        bNodeStack **in, bNodeStack **out)
{
	if (data) {
		ShadeInput *shi = ((ShaderCallData *)data)->shi;

		NodeShaderNormalMap *nm = node->storage;

		float strength, vecIn[3];
		nodestack_get_vec(&strength, SOCK_FLOAT, in[0]);
		nodestack_get_vec(vecIn, SOCK_VECTOR, in[1]);

		vecIn[0] = -2 * (vecIn[0] - 0.5f);
		vecIn[1] =  2 * (vecIn[1] - 0.5f);
		vecIn[2] =  2 * (vecIn[2] - 0.5f);

		CLAMP_MIN(strength, 0.0f);

		float *N = shi->nmapnorm;
		int uv_index = 0;
		switch (nm->space) {
			case SHD_SPACE_TANGENT:
				if (nm->uv_map[0]) {
					/* find uv map by name */
					for (int i = 0; i < shi->totuv; i++) {
						if (STREQ(shi->uv[i].name, nm->uv_map)) {
							uv_index = i;
							break;
						}
					}
				}
				else {
					uv_index = shi->actuv;
				}

				float *T = shi->tangents[uv_index];

				float B[3];
				cross_v3_v3v3(B, N, T);
				mul_v3_fl(B, T[3]);

				for (int j = 0; j < 3; j++)
					out[0]->vec[j] = vecIn[0] * T[j] + vecIn[1] * B[j] + vecIn[2] * N[j];
				interp_v3_v3v3(out[0]->vec, N, out[0]->vec, strength);
				if (shi->use_world_space_shading) {
					mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[0]->vec);
				}
				break;

			case SHD_SPACE_OBJECT:
			case SHD_SPACE_BLENDER_OBJECT:
				if (shi->use_world_space_shading) {
					mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB), vecIn);
					mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N);
				}
				else
					mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW), vecIn);
				interp_v3_v3v3(out[0]->vec, N, vecIn, strength);
				break;

			case SHD_SPACE_WORLD:
			case SHD_SPACE_BLENDER_WORLD:
				if (shi->use_world_space_shading)
					mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N);
				else
					mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), vecIn);
				interp_v3_v3v3(out[0]->vec, N, vecIn, strength);
				break;
		}
		if (shi->use_world_space_shading) {
			negate_v3(out[0]->vec);
		}
		normalize_v3(out[0]->vec);
	}
}
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 */
			r = a + b;
			break;
		case 1: /* Subtract */
			r = a - b;
			break;
		case 2: /* Multiply */
			r = a * b;
			break;
		case 3: /* Divide */
		{
			if (b == 0) /* We don't want to divide by zero. */
				r = 0.0;
			else
				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. */
				r = sinf(a);
			else
				r = sinf(b);
			break;
		}
		case 5: /* Cosine */
		{
			if (in[0]->hasinput || !in[1]->hasinput)  /* This one only takes one input, so we've got to choose. */
				r = cosf(a);
			else
				r = cosf(b);
			break;
		}
		case 6: /* Tangent */
		{
			if (in[0]->hasinput || !in[1]->hasinput)  /* This one only takes one input, so we've got to choose. */
				r = tanf(a);
			else
				r = tanf(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 (a <= 1 && a >= -1)
					r = asinf(a);
				else
					r = 0.0;
			}
			else {
				/* Can't do the impossible... */
				if (b <= 1 && b >= -1)
					r = asinf(b);
				else
					r = 0.0;
			}
			break;
		}
		case 8: /* Arc-Cosine */
		{
			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 (a <= 1 && a >= -1)
					r = acosf(a);
				else
					r = 0.0;
			}
			else {
				/* Can't do the impossible... */
				if (b <= 1 && b >= -1)
					r = acosf(b);
				else
					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. */
				r = atan(a);
			else
				r = atan(b);
			break;
		}
		case 10: /* Power */
		{
			/* Only raise negative numbers by full integers */
			if (a >= 0) {
				r = pow(a, b);
			}
			else {
				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) {
					r = powf(a, floorf(b + 0.5f));
				}
				else {
					r = 0.0f;
				}
			}

			break;
		}
		case 11: /* Logarithm */
		{
			/* Don't want any imaginary numbers... */
			if (a > 0  && b > 0)
				r = log(a) / log(b);
			else
				r = 0.0;
			break;
		}
		case 12: /* Minimum */
		{
			if (a < b)
				r = a;
			else
				r = b;
			break;
		}
		case 13: /* Maximum */
		{
			if (a > b)
				r = a;
			else
				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. */
				r = (a < 0) ? (int)(a - 0.5f) : (int)(a + 0.5f);
			else
				r = (b < 0) ? (int)(b - 0.5f) : (int)(b + 0.5f);
			break;
		}
		case 15: /* Less Than */
		{
			if (a < b)
				r = 1.0f;
			else
				r = 0.0f;
			break;
		}
		case 16: /* Greater Than */
		{
			if (a > b)
				r = 1.0f;
			else
				r = 0.0f;
			break;
		}
		case 17: /* Modulo */
		{
			if (b == 0.0f)
				r = 0.0f;
			else
				r = fmod(a, b);
			break;
		}
		case 18: /* Absolute */
		{
			r = fabsf(a);
			break;
		}
	}
	
	out[0]->vec[0] = r;
}
示例#23
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);
		
	}
}