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;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to