[Bf-blender-cvs] [095a01a73a3] master: Cycles: slightly improve BSDF sample stratification for path tracing.

Brecht Van Lommel noreply at git.blender.org
Wed Sep 20 20:00:41 CEST 2017


Commit: 095a01a73a35d3af57573fc724d381bcca019f54
Author: Brecht Van Lommel
Date:   Thu Sep 14 22:56:32 2017 +0200
Branches: master
https://developer.blender.org/rB095a01a73a35d3af57573fc724d381bcca019f54

Cycles: slightly improve BSDF sample stratification for path tracing.

Similar to what we did for area lights previously, this should help
preserve stratification when using multiple BSDFs in theory. Improvements
are not easily noticeable in practice though, because the number of BSDFs
is usually low. Still nice to eliminate one sampling dimension.

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

M	intern/cycles/kernel/kernel_bake.h
M	intern/cycles/kernel/kernel_emission.h
M	intern/cycles/kernel/kernel_path.h
M	intern/cycles/kernel/kernel_path_branched.h
M	intern/cycles/kernel/kernel_path_subsurface.h
M	intern/cycles/kernel/kernel_path_volume.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/kernel_shadow.h
M	intern/cycles/kernel/kernel_subsurface.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/kernel_volume.h
M	intern/cycles/kernel/split/kernel_shader_eval.h
M	intern/cycles/kernel/split/kernel_subsurface_scatter.h

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

diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index b05f6e9ed5e..f06005c5072 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -51,8 +51,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
 	path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
 
 	/* evaluate surface shader */
-	float rbsdf = path_state_rng_1D(kg, &state, PRNG_BSDF);
-	shader_eval_surface(kg, sd, &state, rbsdf, state.flag);
+	shader_eval_surface(kg, sd, &state, state.flag);
 
 	/* TODO, disable more closures we don't need besides transparent */
 	shader_bsdf_disable_transparency(kg, sd);
@@ -241,12 +240,12 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
 		}
 		else {
 			/* surface color of the pass only */
-			shader_eval_surface(kg, sd, state, 0.0f, 0);
+			shader_eval_surface(kg, sd, state, 0);
 			return kernel_bake_shader_bsdf(kg, sd, type);
 		}
 	}
 	else {
-		shader_eval_surface(kg, sd, state, 0.0f, 0);
+		shader_eval_surface(kg, sd, state, 0);
 		color = kernel_bake_shader_bsdf(kg, sd, type);
 	}
 
@@ -338,7 +337,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 		case SHADER_EVAL_NORMAL:
 		{
 			if((sd.flag & SD_HAS_BUMP)) {
-				shader_eval_surface(kg, &sd, &state, 0.f, 0);
+				shader_eval_surface(kg, &sd, &state, 0);
 			}
 
 			/* encoding: normal = (2 * color) - 1 */
@@ -352,7 +351,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 		}
 		case SHADER_EVAL_EMISSION:
 		{
-			shader_eval_surface(kg, &sd, &state, 0.f, 0);
+			shader_eval_surface(kg, &sd, &state, 0);
 			out = shader_emissive_eval(kg, &sd);
 			break;
 		}
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 13d4759a9ec..45b8c6311e1 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -70,7 +70,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
 		/* no path flag, we're evaluating this for all closures. that's weak but
 		 * we'd have to do multiple evaluations otherwise */
 		path_state_modify_bounce(state, true);
-		shader_eval_surface(kg, emission_sd, state, 0.0f, 0);
+		shader_eval_surface(kg, emission_sd, state, 0);
 		path_state_modify_bounce(state, false);
 
 		/* evaluate emissive closure */
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 86b2aa00776..2df21f1cda3 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -210,7 +210,7 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
 				/* indirect sample. if we use distance sampling and take just
 				 * one sample for direct and indirect light, we could share
 				 * this computation, but makes code a bit complex */
-				float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
+				float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
 				float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
 
 				result = kernel_volume_decoupled_scatter(kg,
@@ -434,8 +434,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
 		                      sd,
 		                      &isect,
 		                      ray);
-		float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
-		shader_eval_surface(kg, sd, state, rbsdf, state->flag);
+		shader_eval_surface(kg, sd, state, state->flag);
 #ifdef __BRANCHED_PATH__
 		shader_merge_closures(sd);
 #endif  /* __BRANCHED_PATH__ */
@@ -483,17 +482,18 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
 		/* bssrdf scatter to a different location on the same object, replacing
 		 * the closures with a diffuse BSDF */
 		if(sd->flag & SD_BSSRDF) {
-			const ShaderClosure *sc = shader_bssrdf_pick(sd, &throughput);
+			float bssrdf_u, bssrdf_v;
+			path_state_rng_2D(kg,
+			                  state,
+			                  PRNG_BSDF_U,
+			                  &bssrdf_u, &bssrdf_v);
+
+			const ShaderClosure *sc = shader_bssrdf_pick(sd, &throughput, &bssrdf_u);
 
 			/* do bssrdf scatter step if we picked a bssrdf closure */
 			if(sc) {
 				uint lcg_state = lcg_state_init(state, 0x68bc21eb);
 
-				float bssrdf_u, bssrdf_v;
-				path_state_rng_2D(kg,
-				                  state,
-				                  PRNG_BSDF_U,
-				                  &bssrdf_u, &bssrdf_v);
 				subsurface_scatter_step(kg,
 				                        sd,
 				                        state,
@@ -587,8 +587,7 @@ ccl_device_forceinline void kernel_path_integrate(
 
 		/* Setup and evaluate shader. */
 		shader_setup_from_ray(kg, &sd, &isect, ray);
-		float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
-		shader_eval_surface(kg, &sd, state, rbsdf, state->flag);
+		shader_eval_surface(kg, &sd, state, state->flag);
 
 		/* Apply shadow catcher, holdout, emission. */
 		if(!kernel_path_shader_apply(kg,
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index e525e008945..010988d2a02 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -339,7 +339,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
 					/* scatter sample. if we use distance sampling and take just one
 					 * sample for direct and indirect light, we could share this
 					 * computation, but makes code a bit complex */
-					float rphase = path_state_rng_1D(kg, &ps, PRNG_PHASE);
+					float rphase = path_state_rng_1D(kg, &ps, PRNG_PHASE_CHANNEL);
 					float rscatter = path_state_rng_1D(kg, &ps, PRNG_SCATTER_DISTANCE);
 
 					VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
@@ -439,7 +439,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
 
 		/* Setup and evaluate shader. */
 		shader_setup_from_ray(kg, &sd, &isect, &ray);
-		shader_eval_surface(kg, &sd, &state, 0.0f, state.flag);
+		shader_eval_surface(kg, &sd, &state, state.flag);
 		shader_merge_closures(&sd);
 
 		/* Apply shadow catcher, holdout, emission. */
diff --git a/intern/cycles/kernel/kernel_path_subsurface.h b/intern/cycles/kernel/kernel_path_subsurface.h
index cc6231eb6b1..1753618607a 100644
--- a/intern/cycles/kernel/kernel_path_subsurface.h
+++ b/intern/cycles/kernel/kernel_path_subsurface.h
@@ -32,7 +32,10 @@ bool kernel_path_subsurface_scatter(
         ccl_addr_space float3 *throughput,
         ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
 {
-	const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput);
+	float bssrdf_u, bssrdf_v;
+	path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+
+	const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u);
 
 	/* do bssrdf scatter step if we picked a bssrdf closure */
 	if(sc) {
@@ -45,8 +48,6 @@ bool kernel_path_subsurface_scatter(
 		uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
 
 		SubsurfaceIntersection ss_isect;
-		float bssrdf_u, bssrdf_v;
-		path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
 		int num_hits = subsurface_scatter_multi_intersect(kg,
 		                                                  &ss_isect,
 		                                                  sd,
diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h
index f645a109ce9..3cf897ac49c 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -77,7 +77,7 @@ bool kernel_path_volume_bounce(
 	float3 phase_omega_in;
 	differential3 phase_domega_in;
 	float phase_u, phase_v;
-	path_state_rng_2D(kg, state, PRNG_PHASE_U, &phase_u, &phase_v);
+	path_state_rng_2D(kg, state, PRNG_BSDF_U, &phase_u, &phase_v);
 	int label;
 
 	label = shader_volume_phase_sample(kg, sd, phase_u, phase_v, &phase_eval,
@@ -155,7 +155,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
 				float3 tp = throughput;
 
 				/* sample position on volume segment */
-				float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
+				float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
 				float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
 
 				VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
@@ -201,7 +201,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
 				float3 tp = throughput;
 
 				/* sample position on volume segment */
-				float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
+				float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
 				float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
 
 				VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
@@ -238,7 +238,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
 		float3 tp = throughput;
 
 		/* sample position on volume segment */
-		float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
+		float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
 		float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
 
 		VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 88aa1f712a4..5ef4475e259 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -575,7 +575,8 @@ void shader_bsdf_eval(KernelGlobals *kg,
 	}
 }
 
-ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd)
+ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd,
+                                                        float *randu)
 {
 	int sampled = 0;
 
@@ -591,19 +592,25 @@ ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd)
 			}
 		}
 
-		float r = sd->randb_closure*sum;
+		float r = (*randu)*sum;
 		float partial_sum = 0.0f;
 
 		for(int i = 0; i < sd->num_closure; i++) {
 			const ShaderClosure *sc = &sd->closure[i];
 
 			if(CLOSURE_IS_BSDF(sc->type)) {
-				partial_sum += sc->sa

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list