[Bf-blender-cvs] [30aa0c2] master: Code refactor: better distinguish scatter and absorption for volume integration.

Brecht Van Lommel noreply at git.blender.org
Mon Dec 30 00:05:44 CET 2013


Commit: 30aa0c2482367fd5a99f2b791206b9e72d9ca7e3
Author: Brecht Van Lommel
Date:   Sun Dec 29 15:49:16 2013 +0100
https://developer.blender.org/rB30aa0c2482367fd5a99f2b791206b9e72d9ca7e3

Code refactor: better distinguish scatter and absorption for volume integration.

===================================================================

M	intern/cycles/kernel/closure/volume.h
M	intern/cycles/kernel/kernel_path.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/kernel_volume.h

===================================================================

diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 4cf918f..951a03b 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -39,7 +39,7 @@ ccl_device int volume_henyey_greenstein_setup(ShaderClosure *sc)
 	/* clamp anisotropy to avoid delta function */
 	sc->data0 = signf(sc->data0) * min(fabsf(sc->data0), 1.0f - 1e-3f);
 
-	return SD_BSDF|SD_BSDF_HAS_EVAL|SD_VOLUME;
+	return SD_BSDF|SD_BSDF_HAS_EVAL|SD_SCATTER;
 }
 
 ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
@@ -98,7 +98,7 @@ ccl_device int volume_absorption_setup(ShaderClosure *sc)
 {
 	sc->type = CLOSURE_VOLUME_ABSORPTION_ID;
 
-	return SD_VOLUME;
+	return SD_ABSORPTION;
 }
 
 /* VOLUME CLOSURE */
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 7aea673..204f782 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -92,11 +92,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ra
 #endif
 
 #ifdef __VOLUME__
-		/* volume attenuation */
+		/* volume attenuation, emission, scatter */
 		if(state.volume_stack[0].shader != SHADER_NO_ID) {
-			Ray segment_ray = ray;
-			segment_ray.t = (hit)? isect.t: FLT_MAX;
-			kernel_volume_integrate(kg, &state, &segment_ray, L, &throughput);
+			ray.t = (hit)? isect.t: FLT_MAX;
+			kernel_volume_integrate(kg, &state, &ray, L, &throughput);
 		}
 #endif
 
@@ -514,11 +513,10 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 #endif
 
 #ifdef __VOLUME__
-		/* volume attenuation */
+		/* volume attenuation, emission, scatter */
 		if(state.volume_stack[0].shader != SHADER_NO_ID) {
-			Ray segment_ray = ray;
-			segment_ray.t = (hit)? isect.t: FLT_MAX;
-			kernel_volume_integrate(kg, &state, &segment_ray, &L, &throughput);
+			ray.t = (hit)? isect.t: FLT_MAX;
+			kernel_volume_integrate(kg, &state, &ray, &L, &throughput);
 		}
 #endif
 
@@ -1018,11 +1016,10 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
 #endif
 
 #ifdef __VOLUME__
-		/* volume attenuation */
+		/* volume attenuation, emission, scatter */
 		if(state.volume_stack[0].shader != SHADER_NO_ID) {
-			Ray segment_ray = ray;
-			segment_ray.t = (hit)? isect.t: FLT_MAX;
-			kernel_volume_integrate(kg, &state, &segment_ray, &L, &throughput);
+			ray.t = (hit)? isect.t: FLT_MAX;
+			kernel_volume_integrate(kg, &state, &ray, &L, &throughput);
 		}
 #endif
 
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 3091def..63cd2b2 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -500,25 +500,26 @@ enum ShaderDataFlag {
 	SD_BSDF_GLOSSY = 16,	/* have glossy bsdf */
 	SD_BSSRDF = 32,			/* have bssrdf */
 	SD_HOLDOUT = 64,		/* have holdout closure? */
-	SD_VOLUME = 128,		/* have volume closure? */
-	SD_AO = 256,			/* have ao closure? */
+	SD_ABSORPTION = 128,	/* have volume absorption closure? */
+	SD_SCATTER = 256,		/* have volume scattering closure? */
+	SD_AO = 512,			/* have ao closure? */
 
-	SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY|SD_BSSRDF|SD_HOLDOUT|SD_VOLUME|SD_AO),
+	SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY|SD_BSSRDF|SD_HOLDOUT|SD_ABSORPTION|SD_SCATTER|SD_AO),
 
 	/* shader flags */
-	SD_USE_MIS = 512,					/* direct light sample */
-	SD_HAS_TRANSPARENT_SHADOW = 1024,	/* has transparent shadow */
-	SD_HAS_VOLUME = 2048,				/* has volume shader */
-	SD_HAS_ONLY_VOLUME = 4096,			/* has only volume shader, no surface */
-	SD_HOMOGENEOUS_VOLUME = 8192,		/* has homogeneous volume */
-	SD_HAS_BSSRDF_BUMP = 16384,			/* bssrdf normal uses bump */
+	SD_USE_MIS = 1024,					/* direct light sample */
+	SD_HAS_TRANSPARENT_SHADOW = 2048,	/* has transparent shadow */
+	SD_HAS_VOLUME = 4096,				/* has volume shader */
+	SD_HAS_ONLY_VOLUME = 8192,			/* has only volume shader, no surface */
+	SD_HOMOGENEOUS_VOLUME = 16384,		/* has homogeneous volume */
+	SD_HAS_BSSRDF_BUMP = 32768,			/* bssrdf normal uses bump */
 
 	SD_SHADER_FLAGS = (SD_USE_MIS|SD_HAS_TRANSPARENT_SHADOW|SD_HAS_VOLUME|SD_HAS_ONLY_VOLUME|SD_HOMOGENEOUS_VOLUME|SD_HAS_BSSRDF_BUMP),
 
 	/* object flags */
-	SD_HOLDOUT_MASK = 32768,			/* holdout for camera rays */
-	SD_OBJECT_MOTION = 65536,			/* has object motion blur */
-	SD_TRANSFORM_APPLIED = 131072, 		/* vertices have transform applied */
+	SD_HOLDOUT_MASK = 65536,			/* holdout for camera rays */
+	SD_OBJECT_MOTION = 131072,			/* has object motion blur */
+	SD_TRANSFORM_APPLIED = 262144, 		/* vertices have transform applied */
 
 	SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED)
 };
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 6b198ed..ee9e289 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -16,16 +16,23 @@
 
 CCL_NAMESPACE_BEGIN
 
+typedef enum VolumeIntegrateResult {
+	VOLUME_PATH_TERMINATED = 0,
+	VOLUME_PATH_SCATTERED = 1,
+	VOLUME_PATH_ATTENUATED = 2,
+	VOLUME_PATH_MISSED = 3
+} VolumeIntegrateResult;
+
 /* Volume shader properties
  *
  * extinction coefficient = absorption coefficient + scattering coefficient
  * sigma_t = sigma_a + sigma_s */
 
-typedef struct VolumeShaderSample {
+typedef struct VolumeShaderCoefficients {
 	float3 sigma_a;
 	float3 sigma_s;
 	float3 emission;
-} VolumeShaderSample;
+} VolumeShaderCoefficients;
 
 /* evaluate shader to get extinction coefficient at P */
 ccl_device bool volume_shader_extinction_sample(KernelGlobals *kg, ShaderData *sd, VolumeStack *stack, int path_flag, ShaderContext ctx, float3 P, float3 *extinction)
@@ -33,7 +40,7 @@ ccl_device bool volume_shader_extinction_sample(KernelGlobals *kg, ShaderData *s
 	sd->P = P;
 	shader_eval_volume(kg, sd, stack, 0.0f, path_flag, ctx);
 
-	if(!(sd->flag & SD_VOLUME))
+	if(!(sd->flag & (SD_ABSORPTION|SD_SCATTER)))
 		return false;
 
 	float3 sigma_t = make_float3(0.0f, 0.0f, 0.0f);
@@ -50,12 +57,12 @@ ccl_device bool volume_shader_extinction_sample(KernelGlobals *kg, ShaderData *s
 }
 
 /* evaluate shader to get absorption, scattering and emission at P */
-ccl_device bool volume_shader_sample(KernelGlobals *kg, ShaderData *sd, VolumeStack *stack, int path_flag, ShaderContext ctx, float3 P, VolumeShaderSample *sample)
+ccl_device bool volume_shader_sample(KernelGlobals *kg, ShaderData *sd, VolumeStack *stack, int path_flag, ShaderContext ctx, float3 P, VolumeShaderCoefficients *sample)
 {
 	sd->P = P;
 	shader_eval_volume(kg, sd, stack, 0.0f, path_flag, ctx);
 
-	if(!(sd->flag & (SD_VOLUME|SD_EMISSION)))
+	if(!(sd->flag & (SD_ABSORPTION|SD_SCATTER|SD_EMISSION)))
 		return false;
 
 	sample->sigma_a = make_float3(0.0f, 0.0f, 0.0f);
@@ -83,12 +90,12 @@ ccl_device float3 volume_color_attenuation(float3 sigma, float t)
 
 /* Volumetric Shadows */
 
-/* get the volume attenuation over line segment defined by segment_ray, with the
+/* get the volume attenuation over line segment defined by ray, with the
  * assumption that there are no surfaces blocking light between the endpoints */
-ccl_device void kernel_volume_get_shadow_attenuation(KernelGlobals *kg, PathState *state, Ray *segment_ray, float3 *throughput)
+ccl_device void kernel_volume_get_shadow_attenuation(KernelGlobals *kg, PathState *state, Ray *ray, float3 *throughput)
 {
 	ShaderData sd;
-	shader_setup_from_volume(kg, &sd, segment_ray, state->bounce);
+	shader_setup_from_volume(kg, &sd, ray, state->bounce);
 
 	ShaderContext ctx = SHADER_CONTEXT_SHADOW;
 	int path_flag = PATH_RAY_SHADOW;
@@ -96,54 +103,58 @@ ccl_device void kernel_volume_get_shadow_attenuation(KernelGlobals *kg, PathStat
 
 	/* homogenous volume: assume shader evaluation at the starts gives
 	 * the extinction coefficient for the entire line segment */
-	if(!volume_shader_extinction_sample(kg, &sd, state->volume_stack, path_flag, ctx, segment_ray->P, &sigma_t))
+	if(!volume_shader_extinction_sample(kg, &sd, state->volume_stack, path_flag, ctx, ray->P, &sigma_t))
 		return;
 
-	*throughput *= volume_color_attenuation(sigma_t, segment_ray->t);
+	*throughput *= volume_color_attenuation(sigma_t, ray->t);
 }
 
 /* Volumetric Path */
 
 /* get the volume attenuation and emission over line segment defined by
- * segment_ray, with the assumption that there are no surfaces blocking light
+ * ray, with the assumption that there are no surfaces blocking light
  * between the endpoints */
-ccl_device void kernel_volume_integrate(KernelGlobals *kg, PathState *state, Ray *segment_ray, PathRadiance *L, float3 *throughput)
+ccl_device VolumeIntegrateResult kernel_volume_integrate(KernelGlobals *kg, PathState *state, Ray *ray, PathRadiance *L, float3 *throughput)
 {
 	ShaderData sd;
-	shader_setup_from_volume(kg, &sd, segment_ray, state->bounce);
+	shader_setup_from_volume(kg, &sd, ray, state->bounce);
 
 	ShaderContext ctx = SHADER_CONTEXT_VOLUME;
 	int path_flag = PATH_RAY_SHADOW;
-	VolumeShaderSample sample;
+	VolumeShaderCoefficients coeff;
 
 	/* homogenous volume: assume shader evaluation at the starts gives
 	 * the extinction coefficient for the entire line segment */
-	if(!volume_shader_sample(kg, &sd, state->volume_stack, path_flag, ctx, segment_ray->P, &sample))
-		return;
+	if(!volume_shader_sample(kg, &sd, state->volume_stack, path_flag, ctx, ray->P, &coeff))
+		return VOLUME_PATH_MISSED;
+
+	/* todo: in principle the SD_EMISSION, SD_ABSORPTION and SD_SCATTER flags
+	 * should ensure that one of the components is > 0 and so no division by
+	 * zero occurs, however this needs to be double-checked and tested */
 	
 	int closure_flag = sd.flag;
-	float t = segment_ray->t;
+	float t = ray->t;
 
 	/* compute attenuation from absorption (+ scattering for now) */
-	float3 sigma_t, attenuation;
+	float3 attenuation;
 
-	if(closure_flag & SD_VOLUME) {
-		sigma_t = sample.sigma_a + sample.sigma_s;
-		attenuation = volume_color_attenuation(sigma_t, t);
-	}
+	if(closure_flag & SD_ABSORPTION)
+		attenuation = volume_color_attenuation(coeff.sigma_a, t);
 
 	/* integrate emission attenuated by absorpti

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list