Ejemplo n.º 1
0
static void flatten_volume_closure_tree(ShaderData *sd,
                                        const OSL::ClosureColor *closure,
                                        float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
	/* OSL gives us a closure tree, we flatten it into arrays per
	 * closure type, for evaluation, sampling, etc later on. */

	switch(closure->id) {
		case OSL::ClosureColor::MUL: {
			OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
			flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
			break;
		}
		case OSL::ClosureColor::ADD: {
			OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
			flatten_volume_closure_tree(sd, add->closureA, weight);
			flatten_volume_closure_tree(sd, add->closureB, weight);
			break;
		}
		default: {
			OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
			CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();

			if(prim) {
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
				weight = weight*TO_FLOAT3(comp->w);
#endif
				prim->setup(sd, 0, weight);
			}
		}
	}
}
Ejemplo n.º 2
0
static void flatten_volume_closure_tree(ShaderData *sd,
                                        const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
	/* OSL gives us a closure tree, we flatten it into arrays per
	 * closure type, for evaluation, sampling, etc later on. */

	if (closure->type == OSL::ClosureColor::COMPONENT) {
		OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
		CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();

		if (prim) {
			ShaderClosure sc;

#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
			weight = weight*TO_FLOAT3(comp->w);
#endif
			sc.weight = weight;

			prim->setup();

			switch (prim->category) {
				case CClosurePrimitive::Volume: {
					/* sample weight */
					float sample_weight = fabsf(average(weight));

					sc.sample_weight = sample_weight;
					sc.type = CLOSURE_VOLUME_ID;
					sc.data0 = 0.0f;
					sc.data1 = 0.0f;
					sc.prim = NULL;

					/* add */
					if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE)
						sd->closure[sd->num_closure++] = sc;
					break;
				}
				case CClosurePrimitive::Holdout:
					break; /* not implemented */
				case CClosurePrimitive::Background:
				case CClosurePrimitive::BSDF:
				case CClosurePrimitive::Emissive:
				case CClosurePrimitive::BSSRDF:
				case CClosurePrimitive::AmbientOcclusion:
					break; /* not relevant */
			}
		}
	}
	else if (closure->type == OSL::ClosureColor::MUL) {
		OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
		flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
	}
	else if (closure->type == OSL::ClosureColor::ADD) {
		OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
		flatten_volume_closure_tree(sd, add->closureA, weight);
		flatten_volume_closure_tree(sd, add->closureB, weight);
	}
}
Ejemplo n.º 3
0
static void flatten_volume_closure_tree(ShaderData *sd,
	const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
	/* OSL gives use a closure tree, we flatten it into arrays per
	 * closure type, for evaluation, sampling, etc later on. */

	if(closure->type == OSL::ClosureColor::COMPONENT) {
		OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure;
		OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data();

		if(prim) {
			ShaderClosure sc;
			sc.prim = prim;
			sc.weight = weight;

			switch(prim->category()) {
				case ClosurePrimitive::Volume: {
					if(sd->num_closure == MAX_CLOSURE)
						return;

					/* sample weight */
					float sample_weight = fabsf(average(weight));
					float sample_sum = sd->osl_closure.volume_sample_sum + sample_weight;

					sc.sample_weight = sample_weight;
					sc.type = CLOSURE_VOLUME_ID;
					sd->osl_closure.volume_sample_sum = sample_sum;

					/* add */
					sd->closure[sd->num_closure++] = sc;
					break;
				}
				case ClosurePrimitive::Holdout:
				case ClosurePrimitive::Debug:
					break; /* not implemented */
				case ClosurePrimitive::Background:
				case ClosurePrimitive::BSDF:
				case ClosurePrimitive::Emissive:
				case ClosurePrimitive::BSSRDF:
					break; /* not relevant */
			}
		}
	}
	else if(closure->type == OSL::ClosureColor::MUL) {
		OSL::ClosureMul *mul = (OSL::ClosureMul*)closure;
		flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
	}
	else if(closure->type == OSL::ClosureColor::ADD) {
		OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure;
		flatten_volume_closure_tree(sd, add->closureA, weight);
		flatten_volume_closure_tree(sd, add->closureB, weight);
	}
}
Ejemplo n.º 4
0
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
{
	/* gather pointers */
	OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss;
	OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
	OSL::ShaderGlobals *globals = &tdata->globals;
	OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info);

	/* setup shader globals from shader data */
	sd->osl_ctx = ctx;
	shaderdata_to_shaderglobals(kg, sd, path_flag, globals);

	/* execute shader */
	int shader = sd->shader & SHADER_MASK;

	if(kg->osl.volume_state[shader])
		ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.volume_state[shader]), *globals);

	/* retrieve resulting closures */
	sd->osl_closure.volume_sample_sum = 0.0f;
	sd->osl_closure.num_volume = 0;
	sd->osl_closure.randb = randb;

	if(globals->Ci)
		flatten_volume_closure_tree(sd, globals->Ci);
}
Ejemplo n.º 5
0
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
{
	/* setup shader globals from shader data */
	OSLThreadData *tdata = kg->osl_tdata;
	shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);

	/* execute shader */
	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
	OSL::ShaderGlobals *globals = &tdata->globals;
	OSL::ShadingContext *octx = tdata->context[(int)ctx];
	int shader = sd->shader & SHADER_MASK;

	if (kg->osl->volume_state[shader])
		ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);

	if (globals->Ci)
		flatten_volume_closure_tree(sd, globals->Ci);
}
Ejemplo n.º 6
0
static void flatten_volume_closure_tree(ShaderData *sd,
                                        const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f))
{
	/* OSL gives us a closure tree, we flatten it into arrays per
	 * closure type, for evaluation, sampling, etc later on. */

#if OSL_LIBRARY_VERSION_CODE < 10700
	switch(closure->type) {
#else
	switch(closure->id) {
#endif
		case OSL::ClosureColor::MUL: {
			OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
			flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
			break;
		}
		case OSL::ClosureColor::ADD: {
			OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
			flatten_volume_closure_tree(sd, add->closureA, weight);
			flatten_volume_closure_tree(sd, add->closureB, weight);
			break;
		}
		default: {
			OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
			CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();

			if(prim) {
				ShaderClosure sc;

#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
				weight = weight*TO_FLOAT3(comp->w);
#endif
				sc.weight = weight;

				prim->setup();

				switch(prim->category) {
					case CClosurePrimitive::Volume: {
						CVolumeClosure *volume = (CVolumeClosure *)prim;
						/* sample weight */
						float sample_weight = fabsf(average(weight));

						sc.sample_weight = sample_weight;
						sc.type = volume->sc.type;
						sc.data0 = volume->sc.data0;
						sc.data1 = volume->sc.data1;

						/* add */
						if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) &&
						   (sd->num_closure < MAX_CLOSURE))
						{
							sd->closure[sd->num_closure++] = sc;
							sd->flag |= volume->shaderdata_flag();
						}
						break;
					}
					case CClosurePrimitive::Emissive: {
						/* sample weight */
						float sample_weight = fabsf(average(weight));

						sc.sample_weight = sample_weight;
						sc.type = CLOSURE_EMISSION_ID;
						sc.data0 = 0.0f;
						sc.data1 = 0.0f;
						sc.prim = NULL;

						/* flag */
						if(sd->num_closure < MAX_CLOSURE) {
							sd->closure[sd->num_closure++] = sc;
							sd->flag |= SD_EMISSION;
						}
						break;
					}
					case CClosurePrimitive::Holdout:
						break; /* not implemented */
					case CClosurePrimitive::Background:
					case CClosurePrimitive::BSDF:
					case CClosurePrimitive::BSSRDF:
					case CClosurePrimitive::AmbientOcclusion:
						break; /* not relevant */
				}
			}
		}
	}
}

void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag, ShaderContext ctx)
{
	/* setup shader globals from shader data */
	OSLThreadData *tdata = kg->osl_tdata;
	shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);

	/* execute shader */
	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
	OSL::ShaderGlobals *globals = &tdata->globals;
	OSL::ShadingContext *octx = tdata->context[(int)ctx];
	int shader = sd->shader & SHADER_MASK;

	if(kg->osl->volume_state[shader]) {
#if OSL_LIBRARY_VERSION_CODE < 10600
		ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);
#else
		ss->execute(octx, *(kg->osl->volume_state[shader]), *globals);
#endif
	}
	
	/* flatten closure tree */
	if(globals->Ci)
		flatten_volume_closure_tree(sd, globals->Ci);
}