diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2016-02-06 22:35:36 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2016-02-06 23:02:02 +0300 |
commit | 7faa9d1304bc500185684a41f8bd65fb4893b8bb (patch) | |
tree | 02e6351c2be5955373bb9797a1b87f8d661e9599 | |
parent | c502114ee11dcd2e737452944b652205517b5682 (diff) |
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.
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_bake.h | 89 | ||||
-rw-r--r-- | intern/cycles/render/bake.cpp | 26 | ||||
-rw-r--r-- | intern/cycles/render/bake.h | 2 |
4 files changed, 42 insertions, 83 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 544ae97d93f..f1b524f7b44 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 96e85474647..7314af35eb9 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 6a3adcabeb1..5bf5e5113ef 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 b731b213065..8377e387197 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; |