Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2016-02-06 22:35:36 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2016-02-06 23:02:02 +0300
commit7faa9d1304bc500185684a41f8bd65fb4893b8bb (patch)
tree02e6351c2be5955373bb9797a1b87f8d661e9599 /intern
parentc502114ee11dcd2e737452944b652205517b5682 (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.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_session.cpp8
-rw-r--r--intern/cycles/kernel/kernel_bake.h89
-rw-r--r--intern/cycles/render/bake.cpp26
-rw-r--r--intern/cycles/render/bake.h2
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;