[Bf-blender-cvs] [7faa9d1] master: Fix T46550: Cycles combined baking black in some cases.

Brecht Van Lommel noreply at git.blender.org
Sat Feb 6 21:02:13 CET 2016


Commit: 7faa9d1304bc500185684a41f8bd65fb4893b8bb
Author: Brecht Van Lommel
Date:   Sat Feb 6 20:35:36 2016 +0100
Branches: master
https://developer.blender.org/rB7faa9d1304bc500185684a41f8bd65fb4893b8bb

Fix T46550: Cycles combined baking black in some cases.

Now pass_filter is modified to have exactly the flags for the light components
that need to be baked, based on the shader type. This simplifies the logic.

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

M	intern/cycles/blender/blender_session.cpp
M	intern/cycles/kernel/kernel_bake.h
M	intern/cycles/render/bake.cpp
M	intern/cycles/render/bake.h

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

diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 544ae97..f1b524f 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -611,7 +611,6 @@ void BlenderSession::bake(BL::Object& b_object,
 	ShaderEvalType shader_type = get_shader_type(pass_type);
 	size_t object_index = OBJECT_NONE;
 	int tri_offset = 0;
-	int bake_pass_filter = bake_pass_filter_get(pass_filter);
 
 	/* Set baking flag in advance, so kernel loading can check if we need
 	 * any baking capabilities.
@@ -629,8 +628,11 @@ void BlenderSession::bake(BL::Object& b_object,
 		Pass::add(PASS_UV, scene->film->passes);
 	}
 
-	if(BakeManager::is_light_pass(shader_type, bake_pass_filter)) {
-		/* force use_light_pass to be true */
+	int bake_pass_filter = bake_pass_filter_get(pass_filter);
+	bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter);
+
+	/* force use_light_pass to be true if we bake more than just colors */
+	if (bake_pass_filter & ~BAKE_FILTER_COLOR) {
 		Pass::add(PASS_LIGHT, scene->film->passes);
 	}
 
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 96e8547..7314af3 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN
 #ifndef __NO_BAKING__
 
 ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng,
-                                   const bool is_ao, const bool is_sss, int sample)
+                                   int pass_filter, int sample)
 {
 	/* initialize master radiance accumulator */
 	kernel_assert(kernel_data.film.use_light_pass);
@@ -31,7 +31,6 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
 	PathState state;
 	Ray ray;
 	float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
-	bool is_sss_sample = is_sss;
 
 	ray.P = sd->P + sd->Ng;
 	ray.D = -sd->Ng;
@@ -58,13 +57,21 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
 #endif
 
 		/* sample ambient occlusion */
-		if(is_ao) {
+		if(pass_filter & BAKE_FILTER_AO) {
 			kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
 		}
 
+		/* sample emission */
+		if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+			float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+			path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
+		}
+
+		bool is_sss_sample = false;
+
 #ifdef __SUBSURFACE__
 		/* sample subsurface scattering */
-		if(is_sss_sample && (sd->flag & SD_BSSRDF)) {
+		if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
 			/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
 			SubsurfaceIndirectRays ss_indirect;
 			kernel_path_subsurface_init_indirect(&ss_indirect);
@@ -99,13 +106,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
 #endif
 
 		/* sample light and BSDF */
-		if((!is_sss_sample) && (!is_ao)) {
-
-			if(sd->flag & SD_EMISSION) {
-				float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
-				path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
-			}
-
+		if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
 			kernel_path_surface_connect_light(kg, &rng, sd, throughput, &state, &L_sample);
 
 			if(kernel_path_surface_bounce(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) {
@@ -126,26 +127,26 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
 		/* branched path tracer */
 
 		/* sample ambient occlusion */
-		if(is_ao) {
+		if(pass_filter & BAKE_FILTER_AO) {
 			kernel_branched_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
 		}
 
+		/* sample emission */
+		if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+			float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+			path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
+		}
+
 #ifdef __SUBSURFACE__
 		/* sample subsurface scattering */
-		if(is_sss_sample && (sd->flag & SD_BSSRDF)) {
+		if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
 			/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
 			kernel_branched_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, throughput);
 		}
 #endif
 
 		/* sample light and BSDF */
-		if((!is_sss_sample) && (!is_ao)) {
-
-			if(sd->flag & SD_EMISSION) {
-				float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
-				path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
-			}
-
+		if(pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT)) {
 #if defined(__EMISSION__)
 			/* direct light */
 			if(kernel_data.integrator.use_direct_light) {
@@ -177,32 +178,6 @@ ccl_device bool is_aa_pass(ShaderEvalType type)
 	}
 }
 
-/* Keep it synced with BakeManager::is_light_pass. */
-ccl_device bool is_light_pass(ShaderEvalType type, const int pass_filter)
-{
-	switch(type) {
-		case SHADER_EVAL_AO:
-		case SHADER_EVAL_SHADOW:
-			return true;
-		case SHADER_EVAL_DIFFUSE:
-		case SHADER_EVAL_GLOSSY:
-		case SHADER_EVAL_TRANSMISSION:
-			return ((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
-			       ((pass_filter & BAKE_FILTER_INDIRECT) != 0);
-		case SHADER_EVAL_COMBINED:
-			return ((pass_filter & BAKE_FILTER_AO) != 0) ||
-			       ((pass_filter & BAKE_FILTER_EMISSION) != 0) ||
-			       ((((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
-			         ((pass_filter & BAKE_FILTER_INDIRECT) != 0)) &&
-			        (((pass_filter & BAKE_FILTER_DIFFUSE) != 0) ||
-			         ((pass_filter & BAKE_FILTER_GLOSSY) != 0) ||
-			         ((pass_filter & BAKE_FILTER_TRANSMISSION) != 0) ||
-			         ((pass_filter & BAKE_FILTER_SUBSURFACE) != 0)));
-		default:
-			return false;
-	}
-}
-
 /* this helps with AA but it's not the real solution as it does not AA the geometry
  *  but it's better than nothing, thus committed */
 ccl_device_inline float bake_clamp_mirror_repeat(float u)
@@ -348,25 +323,9 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 	sd.dv.dx = dvdx;
 	sd.dv.dy = dvdy;
 
-	/* light passes */
-	if(is_light_pass(type, pass_filter)) {
-		bool is_ao, is_sss;
-
-		if (type == SHADER_EVAL_COMBINED) {
-			is_ao = (pass_filter & BAKE_FILTER_AO) != 0;
-			is_sss = ((pass_filter & BAKE_FILTER_SUBSURFACE) != 0) &&
-			         (((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
-			          ((pass_filter & BAKE_FILTER_INDIRECT) != 0));
-		}
-		else {
-			is_ao = (type == SHADER_EVAL_AO);
-			is_sss = (type == SHADER_EVAL_SUBSURFACE) &&
-			         (((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
-			          ((pass_filter & BAKE_FILTER_INDIRECT) != 0));
-		}
-
-		compute_light_pass(kg, &sd, &L, rng, is_ao, is_sss, sample);
-	}
+	/* light passes if we need more than color */
+	if(pass_filter & ~BAKE_FILTER_COLOR)
+		compute_light_pass(kg, &sd, &L, rng, pass_filter, sample);
 
 	switch(type) {
 		/* data passes */
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 6a3adca..5bf5e51 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -255,30 +255,28 @@ bool BakeManager::is_aa_pass(ShaderEvalType type)
 	}
 }
 
-/* Keep it synced with kernel_bake.h::is_light_pass. */
-bool BakeManager::is_light_pass(ShaderEvalType type, const int pass_filter)
+/* Keep it synced with kernel_bake.h logic */
+int BakeManager::shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter)
 {
+	const int component_flags = pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_COLOR);
+
 	switch(type) {
 		case SHADER_EVAL_AO:
+			return BAKE_FILTER_AO;
 		case SHADER_EVAL_SHADOW:
-			return true;
+			return BAKE_FILTER_DIRECT;
 		case SHADER_EVAL_DIFFUSE:
+			return BAKE_FILTER_DIFFUSE | component_flags;
 		case SHADER_EVAL_GLOSSY:
+			return BAKE_FILTER_GLOSSY | component_flags;
 		case SHADER_EVAL_TRANSMISSION:
+			return BAKE_FILTER_TRANSMISSION | component_flags;
 		case SHADER_EVAL_SUBSURFACE:
-			return ((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
-			       ((pass_filter & BAKE_FILTER_INDIRECT) != 0);
+			return BAKE_FILTER_SUBSURFACE | component_flags;
 		case SHADER_EVAL_COMBINED:
-			return ((pass_filter & BAKE_FILTER_AO) != 0) ||
-			       ((pass_filter & BAKE_FILTER_EMISSION) != 0) ||
-			       ((((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
-			         ((pass_filter & BAKE_FILTER_INDIRECT) != 0)) &&
-			        (((pass_filter & BAKE_FILTER_DIFFUSE) != 0) ||
-			         ((pass_filter & BAKE_FILTER_GLOSSY) != 0) ||
-			         ((pass_filter & BAKE_FILTER_TRANSMISSION) != 0) ||
-			         ((pass_filter & BAKE_FILTER_SUBSURFACE) != 0)));
+			return pass_filter;
 		default:
-			return false;
+			return 0;
 	}
 }
 
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index b731b21..8377e38 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -68,7 +68,7 @@ public:
 	void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
 	void device_free(Device *device, DeviceScene *dscene);
 
-	static bool is_light_pass(ShaderEvalType type, const int pass_filter);
+	static int shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter);
 	static bool is_aa_pass(ShaderEvalType type);
 
 	bool need_update;




More information about the Bf-blender-cvs mailing list