[Bf-blender-cvs] [83cdd58] master: Cycles-Bake: Subsurface Scattering support (fix T40060)

Dalai Felinto noreply at git.blender.org
Wed May 7 17:03:03 CEST 2014


Commit: 83cdd5887f10e1998a434fb1632e0b76ec938d91
Author: Dalai Felinto
Date:   Wed May 7 11:55:09 2014 -0300
https://developer.blender.org/rB83cdd5887f10e1998a434fb1632e0b76ec938d91

Cycles-Bake: Subsurface Scattering support (fix T40060)

This fixes the SSS Direct/Indirect passes as well as the Combined pass.
Patch reviewed and with fixes and contributions from Brecht van Lommel.

Note: displacement/bump map (related to the report) will be handled separately

Reviewers: brecht

Differential Revision: https://developer.blender.org/D503

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

M	intern/cycles/kernel/kernel_displace.h
M	intern/cycles/kernel/kernel_path.h

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

diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h
index 012f399..e54a16a 100644
--- a/intern/cycles/kernel/kernel_displace.h
+++ b/intern/cycles/kernel/kernel_displace.h
@@ -17,7 +17,7 @@
 CCL_NAMESPACE_BEGIN
 
 ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng,
-                                   bool is_combined, bool is_ao)
+                                   bool is_combined, bool is_ao, bool is_sss)
 {
 	int samples = kernel_data.integrator.aa_samples;
 
@@ -50,13 +50,21 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
 			kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
 		}
 
+		/* sample subsurface scattering */
+		if((is_combined || is_sss) && (sd->flag & SD_BSSRDF)) {
+#ifdef __SUBSURFACE__
+			/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
+			if (kernel_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, &throughput))
+				is_sss = true;
+#endif
+		}
+
 		/* sample light and BSDF */
-		if(!is_ao) {
+		if((!is_sss) && (!is_ao)) {
 			if(kernel_path_integrate_lighting(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) {
 #ifdef __LAMP_MIS__
 				state.ray_t = 0.0f;
 #endif
-
 				/* compute indirect light */
 				kernel_path_indirect(kg, &rng, ray, throughput, state.num_samples, state, &L_sample);
 
@@ -127,7 +135,9 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 	if(is_light_pass(type)) {
 		RNG rng = cmj_hash(i, 0);
 		compute_light_pass(kg, &sd, &L, rng, (type == SHADER_EVAL_COMBINED),
-		                                     (type == SHADER_EVAL_AO));
+		                                     (type == SHADER_EVAL_AO),
+		                                     (type == SHADER_EVAL_SUBSURFACE_DIRECT ||
+		                                      type == SHADER_EVAL_SUBSURFACE_INDIRECT));
 	}
 
 	switch (type) {
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index bd7b53e..a80a003 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -601,6 +601,52 @@ ccl_device void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance *
 	}
 }
 
+#ifdef __SUBSURFACE__
+ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, Ray *ray, float3 *throughput)
+{
+	float bssrdf_probability;
+	ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability);
+
+	/* modify throughput for picking bssrdf or bsdf */
+	*throughput *= bssrdf_probability;
+
+	/* do bssrdf scatter step if we picked a bssrdf closure */
+	if(sc) {
+		uint lcg_state = lcg_state_init(rng, state, 0x68bc21eb);
+
+		ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
+		float bssrdf_u, bssrdf_v;
+		path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+		int num_hits = subsurface_scatter_multi_step(kg, sd, bssrdf_sd, state->flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
+
+		/* compute lighting with the BSDF closure */
+		for(int hit = 0; hit < num_hits; hit++) {
+			float3 tp = *throughput;
+			PathState hit_state = *state;
+			Ray hit_ray = *ray;
+
+			hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
+			hit_state.rng_offset += PRNG_BOUNCE_NUM;
+
+			if(kernel_path_integrate_lighting(kg, rng, &bssrdf_sd[hit], &tp, &hit_state, L, &hit_ray)) {
+#ifdef __LAMP_MIS__
+				hit_state.ray_t = 0.0f;
+#endif
+
+				kernel_path_indirect(kg, rng, hit_ray, tp, state->num_samples, hit_state, L);
+
+				/* for render passes, sum and reset indirect light pass variables
+				 * for the next samples */
+				path_radiance_sum_indirect(L);
+				path_radiance_reset_indirect(L);
+			}
+		}
+		return true;
+	}
+	return false;
+}
+#endif
+
 ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, ccl_global float *buffer)
 {
 	/* initialize */
@@ -776,45 +822,8 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 		/* bssrdf scatter to a different location on the same object, replacing
 		 * the closures with a diffuse BSDF */
 		if(sd.flag & SD_BSSRDF) {
-			float bssrdf_probability;
-			ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability);
-
-			/* modify throughput for picking bssrdf or bsdf */
-			throughput *= bssrdf_probability;
-
-			/* do bssrdf scatter step if we picked a bssrdf closure */
-			if(sc) {
-				uint lcg_state = lcg_state_init(rng, &state, 0x68bc21eb);
-
-				ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
-				float bssrdf_u, bssrdf_v;
-				path_state_rng_2D(kg, rng, &state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
-				int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
-
-				/* compute lighting with the BSDF closure */
-				for(int hit = 0; hit < num_hits; hit++) {
-					float3 tp = throughput;
-					PathState hit_state = state;
-					Ray hit_ray = ray;
-
-					hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
-					hit_state.rng_offset += PRNG_BOUNCE_NUM;
-					
-					if(kernel_path_integrate_lighting(kg, rng, &bssrdf_sd[hit], &tp, &hit_state, &L, &hit_ray)) {
-#ifdef __LAMP_MIS__
-						hit_state.ray_t = 0.0f;
-#endif
-
-						kernel_path_indirect(kg, rng, hit_ray, tp, state.num_samples, hit_state, &L);
-
-						/* for render passes, sum and reset indirect light pass variables
-						 * for the next samples */
-						path_radiance_sum_indirect(&L);
-						path_radiance_reset_indirect(&L);
-					}
-				}
+			if(kernel_path_subsurface_scatter(kg, &sd, &L, &state, rng, &ray, &throughput))
 				break;
-			}
 		}
 #endif




More information about the Bf-blender-cvs mailing list