Cycles: add Transparent Depth output to Light Path node.
This can for example be useful if you want to manually terminate the path at some point and use a color other than black. Reviewed By: brecht Differential Revision: https://developer.blender.org/D454
This commit is contained in:
		@@ -55,7 +55,7 @@ ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *inpu
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* setup shader data */
 | 
			
		||||
		shader_setup_from_background(kg, &sd, &ray, 0);
 | 
			
		||||
		shader_setup_from_background(kg, &sd, &ray, 0, 0);
 | 
			
		||||
 | 
			
		||||
		/* evaluate */
 | 
			
		||||
		int flag = 0; /* we can't know which type of BSDF this is for */
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN
 | 
			
		||||
/* Direction Emission */
 | 
			
		||||
 | 
			
		||||
ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
 | 
			
		||||
	LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce)
 | 
			
		||||
	LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
	/* setup shading at emitter */
 | 
			
		||||
	ShaderData sd;
 | 
			
		||||
@@ -37,13 +37,13 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
 | 
			
		||||
		ray.dP = differential3_zero();
 | 
			
		||||
		ray.dD = dI;
 | 
			
		||||
 | 
			
		||||
		shader_setup_from_background(kg, &sd, &ray, bounce+1);
 | 
			
		||||
		shader_setup_from_background(kg, &sd, &ray, bounce+1, transparent_bounce);
 | 
			
		||||
		eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1);
 | 
			
		||||
		shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, transparent_bounce);
 | 
			
		||||
 | 
			
		||||
		ls->Ng = sd.Ng;
 | 
			
		||||
 | 
			
		||||
@@ -65,7 +65,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
 | 
			
		||||
 | 
			
		||||
ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
 | 
			
		||||
	float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
 | 
			
		||||
	bool *is_lamp, int bounce)
 | 
			
		||||
	bool *is_lamp, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
	LightSample ls;
 | 
			
		||||
 | 
			
		||||
@@ -88,7 +88,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int
 | 
			
		||||
	differential3 dD = differential3_zero();
 | 
			
		||||
 | 
			
		||||
	/* evaluate closure */
 | 
			
		||||
	float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce);
 | 
			
		||||
	float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce, transparent_bounce);
 | 
			
		||||
 | 
			
		||||
	if(is_zero(light_eval))
 | 
			
		||||
		return false;
 | 
			
		||||
@@ -183,7 +183,7 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader
 | 
			
		||||
 | 
			
		||||
/* Indirect Lamp Emission */
 | 
			
		||||
 | 
			
		||||
ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission, int bounce)
 | 
			
		||||
ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
	LightSample ls;
 | 
			
		||||
	int lamp = lamp_light_eval_sample(kg, randt);
 | 
			
		||||
@@ -204,7 +204,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce);
 | 
			
		||||
	float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce, transparent_bounce);
 | 
			
		||||
 | 
			
		||||
	if(!(path_flag & PATH_RAY_MIS_SKIP)) {
 | 
			
		||||
		/* multiple importance sampling, get regular light pdf,
 | 
			
		||||
@@ -219,7 +219,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int
 | 
			
		||||
 | 
			
		||||
/* Indirect Background */
 | 
			
		||||
 | 
			
		||||
ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce)
 | 
			
		||||
ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
#ifdef __BACKGROUND__
 | 
			
		||||
	int shader = kernel_data.background.surface_shader;
 | 
			
		||||
@@ -235,7 +235,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int
 | 
			
		||||
 | 
			
		||||
	/* evaluate background closure */
 | 
			
		||||
	ShaderData sd;
 | 
			
		||||
	shader_setup_from_background(kg, &sd, ray, bounce+1);
 | 
			
		||||
	shader_setup_from_background(kg, &sd, ray, bounce+1, transparent_bounce);
 | 
			
		||||
 | 
			
		||||
	float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -72,7 +72,7 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
 | 
			
		||||
			light_ray.time = sd->time;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
 | 
			
		||||
			if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
 | 
			
		||||
				/* trace shadow ray */
 | 
			
		||||
				float3 shadow;
 | 
			
		||||
 | 
			
		||||
@@ -157,7 +157,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
 | 
			
		||||
					float light_u, light_v;
 | 
			
		||||
					path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
 | 
			
		||||
 | 
			
		||||
					if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
 | 
			
		||||
					if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
 | 
			
		||||
						/* trace shadow ray */
 | 
			
		||||
						float3 shadow;
 | 
			
		||||
 | 
			
		||||
@@ -186,7 +186,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
 | 
			
		||||
					if(kernel_data.integrator.num_all_lights)
 | 
			
		||||
						light_t = 0.5f*light_t;
 | 
			
		||||
 | 
			
		||||
					if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
 | 
			
		||||
					if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
 | 
			
		||||
						/* trace shadow ray */
 | 
			
		||||
						float3 shadow;
 | 
			
		||||
 | 
			
		||||
@@ -204,7 +204,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
 | 
			
		||||
			path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
 | 
			
		||||
 | 
			
		||||
			/* sample random light */
 | 
			
		||||
			if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
 | 
			
		||||
			if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
 | 
			
		||||
				/* trace shadow ray */
 | 
			
		||||
				float3 shadow;
 | 
			
		||||
 | 
			
		||||
@@ -248,7 +248,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
 | 
			
		||||
			float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
 | 
			
		||||
			float3 emission;
 | 
			
		||||
 | 
			
		||||
			if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce))
 | 
			
		||||
			if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce, state.transparent_bounce))
 | 
			
		||||
				path_radiance_accum_emission(L, throughput, emission, state.bounce);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -275,7 +275,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
 | 
			
		||||
		if(!hit) {
 | 
			
		||||
#ifdef __BACKGROUND__
 | 
			
		||||
			/* sample background shader */
 | 
			
		||||
			float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
 | 
			
		||||
			float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce, state.transparent_bounce);
 | 
			
		||||
			path_radiance_accum_background(L, throughput, L_background, state.bounce);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -284,7 +284,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
 | 
			
		||||
 | 
			
		||||
		/* setup shading */
 | 
			
		||||
		ShaderData sd;
 | 
			
		||||
		shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
 | 
			
		||||
		shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
 | 
			
		||||
		float rbsdf = path_state_rng_1D(kg, rng, &state, PRNG_BSDF);
 | 
			
		||||
		shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
 | 
			
		||||
#ifdef __BRANCHED_PATH__
 | 
			
		||||
@@ -490,7 +490,7 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
 | 
			
		||||
			light_ray.time = sd->time;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
 | 
			
		||||
			if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
 | 
			
		||||
				/* trace shadow ray */
 | 
			
		||||
				float3 shadow;
 | 
			
		||||
 | 
			
		||||
@@ -637,7 +637,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 | 
			
		||||
			float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
 | 
			
		||||
			float3 emission;
 | 
			
		||||
 | 
			
		||||
			if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce))
 | 
			
		||||
			if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce, state.transparent_bounce))
 | 
			
		||||
				path_radiance_accum_emission(&L, throughput, emission, state.bounce);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -674,7 +674,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 | 
			
		||||
 | 
			
		||||
#ifdef __BACKGROUND__
 | 
			
		||||
			/* sample background shader */
 | 
			
		||||
			float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
 | 
			
		||||
			float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce, state.transparent_bounce);
 | 
			
		||||
			path_radiance_accum_background(&L, throughput, L_background, state.bounce);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -683,7 +683,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 | 
			
		||||
 | 
			
		||||
		/* setup shading */
 | 
			
		||||
		ShaderData sd;
 | 
			
		||||
		shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
 | 
			
		||||
		shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
 | 
			
		||||
		float rbsdf = path_state_rng_1D(kg, rng, &state, PRNG_BSDF);
 | 
			
		||||
		shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
 | 
			
		||||
 | 
			
		||||
@@ -851,7 +851,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 | 
			
		||||
				light_ray.time = sd.time;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				if(direct_emission(kg, &sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) {
 | 
			
		||||
				if(direct_emission(kg, &sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce, state.transparent_bounce)) {
 | 
			
		||||
					/* trace shadow ray */
 | 
			
		||||
					float3 shadow;
 | 
			
		||||
 | 
			
		||||
@@ -1100,7 +1100,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
 | 
			
		||||
			VolumeSegment volume_segment;
 | 
			
		||||
			ShaderData volume_sd;
 | 
			
		||||
 | 
			
		||||
			shader_setup_from_volume(kg, &volume_sd, &volume_ray, state.bounce);
 | 
			
		||||
			shader_setup_from_volume(kg, &volume_sd, &volume_ray, state.bounce, state.transparent_bounce);
 | 
			
		||||
			kernel_volume_decoupled_record(kg, &state,
 | 
			
		||||
				&volume_ray, &volume_sd, &volume_segment, heterogeneous);
 | 
			
		||||
 | 
			
		||||
@@ -1196,7 +1196,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
 | 
			
		||||
 | 
			
		||||
#ifdef __BACKGROUND__
 | 
			
		||||
			/* sample background shader */
 | 
			
		||||
			float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
 | 
			
		||||
			float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce, state.transparent_bounce);
 | 
			
		||||
			path_radiance_accum_background(&L, throughput, L_background, state.bounce);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1205,7 +1205,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
 | 
			
		||||
 | 
			
		||||
		/* setup shading */
 | 
			
		||||
		ShaderData sd;
 | 
			
		||||
		shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
 | 
			
		||||
		shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
 | 
			
		||||
		shader_eval_surface(kg, &sd, 0.0f, state.flag, SHADER_CONTEXT_MAIN);
 | 
			
		||||
		shader_merge_closures(&sd);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ ccl_device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
 | 
			
		||||
	const Intersection *isect, const Ray *ray, int bounce)
 | 
			
		||||
	const Intersection *isect, const Ray *ray, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
#ifdef __INSTANCING__
 | 
			
		||||
	sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
 | 
			
		||||
@@ -67,6 +67,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
 | 
			
		||||
	sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
 | 
			
		||||
	sd->ray_length = isect->t;
 | 
			
		||||
	sd->ray_depth = bounce;
 | 
			
		||||
	sd->transparent_depth = transparent_bounce;
 | 
			
		||||
 | 
			
		||||
#ifdef __UV__
 | 
			
		||||
	sd->u = isect->u;
 | 
			
		||||
@@ -228,7 +229,7 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
 | 
			
		||||
 | 
			
		||||
ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
 | 
			
		||||
	const float3 P, const float3 Ng, const float3 I,
 | 
			
		||||
	int shader, int object, int prim, float u, float v, float t, float time, int bounce)
 | 
			
		||||
	int shader, int object, int prim, float u, float v, float t, float time, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
	/* vectors */
 | 
			
		||||
	sd->P = P;
 | 
			
		||||
@@ -250,6 +251,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
 | 
			
		||||
#endif
 | 
			
		||||
	sd->ray_length = t;
 | 
			
		||||
	sd->ray_depth = bounce;
 | 
			
		||||
	sd->transparent_depth = transparent_bounce;
 | 
			
		||||
 | 
			
		||||
	/* detect instancing, for non-instanced the object index is -object-1 */
 | 
			
		||||
#ifdef __INSTANCING__
 | 
			
		||||
@@ -347,12 +349,12 @@ ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
 | 
			
		||||
 | 
			
		||||
	/* watch out: no instance transform currently */
 | 
			
		||||
 | 
			
		||||
	shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0);
 | 
			
		||||
	shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ShaderData setup from ray into background */
 | 
			
		||||
 | 
			
		||||
ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce)
 | 
			
		||||
ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
	/* vectors */
 | 
			
		||||
	sd->P = ray->D;
 | 
			
		||||
@@ -366,6 +368,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
 | 
			
		||||
#endif
 | 
			
		||||
	sd->ray_length = 0.0f;
 | 
			
		||||
	sd->ray_depth = bounce;
 | 
			
		||||
	sd->transparent_depth = transparent_bounce;
 | 
			
		||||
 | 
			
		||||
#ifdef __INSTANCING__
 | 
			
		||||
	sd->object = PRIM_NONE;
 | 
			
		||||
@@ -395,7 +398,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
 | 
			
		||||
 | 
			
		||||
/* ShaderData setup from point inside volume */
 | 
			
		||||
 | 
			
		||||
ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce)
 | 
			
		||||
ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce, int transparent_bounce)
 | 
			
		||||
{
 | 
			
		||||
	/* vectors */
 | 
			
		||||
	sd->P = ray->P;
 | 
			
		||||
@@ -409,6 +412,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s
 | 
			
		||||
#endif
 | 
			
		||||
	sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
 | 
			
		||||
	sd->ray_depth = bounce;
 | 
			
		||||
	sd->transparent_depth = transparent_bounce;
 | 
			
		||||
 | 
			
		||||
#ifdef __INSTANCING__
 | 
			
		||||
	sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
 | 
			
		||||
 | 
			
		||||
				/* setup shader data at surface */
 | 
			
		||||
				ShaderData sd;
 | 
			
		||||
				shader_setup_from_ray(kg, &sd, &isect, ray, state->bounce+1);
 | 
			
		||||
				shader_setup_from_ray(kg, &sd, &isect, ray, ps.bounce+1, ps.transparent_bounce);
 | 
			
		||||
 | 
			
		||||
				/* attenuation from transparent surface */
 | 
			
		||||
				if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -609,6 +609,9 @@ typedef struct ShaderData {
 | 
			
		||||
	/* ray bounce depth */
 | 
			
		||||
	int ray_depth;
 | 
			
		||||
 | 
			
		||||
	/* ray transparent depth */
 | 
			
		||||
	int transparent_depth;
 | 
			
		||||
 | 
			
		||||
#ifdef __RAY_DIFFERENTIALS__
 | 
			
		||||
	/* differential of P. these are orthogonal to Ng, not N */
 | 
			
		||||
	differential3 dP;
 | 
			
		||||
 
 | 
			
		||||
@@ -184,7 +184,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState
 | 
			
		||||
ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg, PathState *state, Ray *ray, float3 *throughput)
 | 
			
		||||
{
 | 
			
		||||
	ShaderData sd;
 | 
			
		||||
	shader_setup_from_volume(kg, &sd, ray, state->bounce);
 | 
			
		||||
	shader_setup_from_volume(kg, &sd, ray, state->bounce, state->transparent_bounce);
 | 
			
		||||
 | 
			
		||||
	if(volume_stack_is_heterogeneous(kg, state->volume_stack))
 | 
			
		||||
		kernel_volume_shadow_heterogeneous(kg, state, ray, &sd, throughput);
 | 
			
		||||
@@ -828,7 +828,7 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
 | 
			
		||||
	/* debugging code to compare decoupled ray marching */
 | 
			
		||||
	VolumeSegment segment;
 | 
			
		||||
 | 
			
		||||
	shader_setup_from_volume(kg, sd, ray, state->bounce);
 | 
			
		||||
	shader_setup_from_volume(kg, sd, ray, state->bounce, state->transparent_bounce);
 | 
			
		||||
	kernel_volume_decoupled_record(kg, state, ray, sd, &segment, heterogeneous);
 | 
			
		||||
 | 
			
		||||
	VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, state, ray, sd, throughput, &tmp_rng, &segment);
 | 
			
		||||
@@ -837,7 +837,7 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
#else
 | 
			
		||||
	shader_setup_from_volume(kg, sd, ray, state->bounce);
 | 
			
		||||
	shader_setup_from_volume(kg, sd, ray, state->bounce, state->transparent_bounce);
 | 
			
		||||
 | 
			
		||||
	if(heterogeneous)
 | 
			
		||||
		return kernel_volume_integrate_heterogeneous(kg, state, ray, sd, L, throughput, &tmp_rng);
 | 
			
		||||
 
 | 
			
		||||
@@ -85,6 +85,7 @@ ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
 | 
			
		||||
#endif
 | 
			
		||||
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
 | 
			
		||||
ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
 | 
			
		||||
ustring OSLRenderServices::u_path_transparent_depth("path:transparent_depth");
 | 
			
		||||
ustring OSLRenderServices::u_trace("trace");
 | 
			
		||||
ustring OSLRenderServices::u_hit("hit");
 | 
			
		||||
ustring OSLRenderServices::u_hitdist("hitdist");
 | 
			
		||||
@@ -701,6 +702,11 @@ bool OSLRenderServices::get_background_attribute(KernelGlobals *kg, ShaderData *
 | 
			
		||||
		int f = sd->ray_depth;
 | 
			
		||||
		return set_attribute_int(f, type, derivatives, val);
 | 
			
		||||
	}
 | 
			
		||||
	else if (name == u_path_transparent_depth) {
 | 
			
		||||
		/* Ray Depth */
 | 
			
		||||
		int f = sd->transparent_depth;
 | 
			
		||||
		return set_attribute_int(f, type, derivatives, val);
 | 
			
		||||
	}
 | 
			
		||||
	else if (name == u_ndc) {
 | 
			
		||||
		/* NDC coordinates with special exception for otho */
 | 
			
		||||
		OSLThreadData *tdata = kg->osl_tdata;
 | 
			
		||||
@@ -1031,8 +1037,9 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustri
 | 
			
		||||
					/* lazy shader data setup */
 | 
			
		||||
					ShaderData *original_sd = (ShaderData *)(sg->renderstate);
 | 
			
		||||
					int bounce = original_sd->ray_depth + 1;
 | 
			
		||||
					int transparent_bounce = original_sd->transparent_depth;
 | 
			
		||||
 | 
			
		||||
					shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray, bounce);
 | 
			
		||||
					shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray, bounce, transparent_bounce);
 | 
			
		||||
					tracedata->setup = true;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,7 @@ public:
 | 
			
		||||
	static ustring u_curve_tangent_normal;
 | 
			
		||||
	static ustring u_path_ray_length;
 | 
			
		||||
	static ustring u_path_ray_depth;
 | 
			
		||||
	static ustring u_path_transparent_depth;
 | 
			
		||||
	static ustring u_trace;
 | 
			
		||||
	static ustring u_hit;
 | 
			
		||||
	static ustring u_hitdist;
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,8 @@ shader node_light_path(
 | 
			
		||||
	output float IsTransmissionRay = 0.0,
 | 
			
		||||
	output float IsVolumeScatterRay = 0.0,
 | 
			
		||||
	output float RayLength = 0.0,
 | 
			
		||||
	output float RayDepth = 0.0)
 | 
			
		||||
	output float RayDepth = 0.0,
 | 
			
		||||
	output float TransparentDepth = 0.0)
 | 
			
		||||
{
 | 
			
		||||
	IsCameraRay = raytype("camera");
 | 
			
		||||
	IsShadowRay = raytype("shadow");
 | 
			
		||||
@@ -42,5 +43,9 @@ shader node_light_path(
 | 
			
		||||
	int ray_depth;
 | 
			
		||||
	getattribute("path:ray_depth", ray_depth);
 | 
			
		||||
	RayDepth = (float)ray_depth;
 | 
			
		||||
 | 
			
		||||
	int transparent_depth;
 | 
			
		||||
	getattribute("path:transparent_depth", transparent_depth);
 | 
			
		||||
	TransparentDepth = (float)transparent_depth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ ccl_device void svm_node_light_path(ShaderData *sd, float *stack, uint type, uin
 | 
			
		||||
		case NODE_LP_backfacing: info = (sd->flag & SD_BACKFACING)? 1.0f: 0.0f; break;
 | 
			
		||||
		case NODE_LP_ray_length: info = sd->ray_length; break;
 | 
			
		||||
		case NODE_LP_ray_depth: info = (float)sd->ray_depth; break;
 | 
			
		||||
		case NODE_LP_ray_transparent: info = sd->transparent_depth; break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stack_store_float(stack, out_offset, info);
 | 
			
		||||
 
 | 
			
		||||
@@ -160,7 +160,8 @@ typedef enum NodeLightPath {
 | 
			
		||||
	NODE_LP_volume_scatter,
 | 
			
		||||
	NODE_LP_backfacing,
 | 
			
		||||
	NODE_LP_ray_length,
 | 
			
		||||
	NODE_LP_ray_depth
 | 
			
		||||
	NODE_LP_ray_depth,
 | 
			
		||||
	NODE_LP_ray_transparent
 | 
			
		||||
} NodeLightPath;
 | 
			
		||||
 | 
			
		||||
typedef enum NodeLightFalloff {
 | 
			
		||||
 
 | 
			
		||||
@@ -2419,6 +2419,7 @@ LightPathNode::LightPathNode()
 | 
			
		||||
	add_output("Is Volume Scatter Ray", SHADER_SOCKET_FLOAT);
 | 
			
		||||
	add_output("Ray Length", SHADER_SOCKET_FLOAT);
 | 
			
		||||
	add_output("Ray Depth", SHADER_SOCKET_FLOAT);
 | 
			
		||||
	add_output("Transparent Depth", SHADER_SOCKET_FLOAT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LightPathNode::compile(SVMCompiler& compiler)
 | 
			
		||||
@@ -2486,6 +2487,11 @@ void LightPathNode::compile(SVMCompiler& compiler)
 | 
			
		||||
		compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, out->stack_offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	out = output("Transparent Depth");
 | 
			
		||||
	if(!out->links.empty()) {
 | 
			
		||||
		compiler.stack_assign(out);
 | 
			
		||||
		compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, out->stack_offset);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LightPathNode::compile(OSLCompiler& compiler)
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@ static bNodeSocketTemplate sh_node_light_path_out[] = {
 | 
			
		||||
	{	SOCK_FLOAT, 0, N_("Is Transmission Ray"),	0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 | 
			
		||||
	{	SOCK_FLOAT, 0, N_("Ray Length"),			0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 | 
			
		||||
	{	SOCK_FLOAT, 0, N_("Ray Depth"),				0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 | 
			
		||||
	{	SOCK_FLOAT, 0, N_("Transparent Depth"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 | 
			
		||||
	{	-1, 0, ""	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user