Commit: e509164b4e236837bb7edb89ac4f0dcd7e4fe779 Author: Sergey Sharybin Date: Thu Jul 8 15:00:45 2021 +0200 Branches: cycles-x https://developer.blender.org/rBe509164b4e236837bb7edb89ac4f0dcd7e4fe779
Fix access shadow catcher pass without catcher objects in Cycles X This fixes the following setup: - Have scene without shadow catcher objects - Enabled Shadow Catcher pass - F12 Differential Revision: https://developer.blender.org/D11850 =================================================================== M intern/cycles/kernel/kernel_film.h M intern/cycles/render/film.cpp M intern/cycles/render/film.h M intern/cycles/render/scene.cpp M intern/cycles/render/session.cpp =================================================================== diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h index 589af4b852e..3bb1433a272 100644 --- a/intern/cycles/kernel/kernel_film.h +++ b/intern/cycles/kernel/kernel_film.h @@ -327,14 +327,9 @@ film_calculate_shadow_catcher(const KernelFilmConvert *ccl_restrict kfilm_conver return film_calculate_shadow_catcher_denoised(kfilm_convert, buffer); } - kernel_assert(kfilm_convert->pass_offset != PASS_UNUSED); - kernel_assert(kfilm_convert->pass_combined != PASS_UNUSED); kernel_assert(kfilm_convert->pass_shadow_catcher != PASS_UNUSED); - kernel_assert(kfilm_convert->pass_shadow_catcher_matte != PASS_UNUSED); - ccl_global const float *in_combined = buffer + kfilm_convert->pass_combined; ccl_global const float *in_catcher = buffer + kfilm_convert->pass_shadow_catcher; - ccl_global const float *in_matte = buffer + kfilm_convert->pass_shadow_catcher_matte; /* If there is no shadow catcher object in this pixel, there is no modification of the light * needed, so return one. */ @@ -343,6 +338,17 @@ film_calculate_shadow_catcher(const KernelFilmConvert *ccl_restrict kfilm_conver return one_float4(); } + /* NOTE: It is possible that the Shadow Catcher pass is requested as an output without actual + * shadow catcher objects in the scene. In this case there will be no auxillary passes required + * for the devision (to save up memory). So delay the asserts to this point so that the number of + * samples check handles such configuration. */ + kernel_assert(kfilm_convert->pass_offset != PASS_UNUSED); + kernel_assert(kfilm_convert->pass_combined != PASS_UNUSED); + kernel_assert(kfilm_convert->pass_shadow_catcher_matte != PASS_UNUSED); + + ccl_global const float *in_combined = buffer + kfilm_convert->pass_combined; + ccl_global const float *in_matte = buffer + kfilm_convert->pass_shadow_catcher_matte; + /* No scaling needed. The integration works in way that number of samples in the combined and * shadow catcher passes are the same, and exposure is cancelled during the division. */ const float3 color_catcher = make_float3(in_catcher[0], in_catcher[1], in_catcher[2]); diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index c74fb52b9ae..0151da837e4 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -168,9 +168,9 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) KernelFilm *kfilm = &dscene->data.film; - const Pass *display_pass = get_actual_display_pass(scene->passes, get_display_pass()); + const Pass *display_pass = get_actual_display_pass(scene, get_display_pass()); const Pass *display_pass_denoised = get_actual_display_pass( - scene->passes, get_display_pass(), PassMode::DENOISED); + scene, get_display_pass(), PassMode::DENOISED); /* update __data */ kfilm->exposure = exposure; @@ -476,15 +476,13 @@ int Film::get_aov_offset(Scene *scene, string name, bool &is_color) return -1; } -const Pass *Film::get_actual_display_pass(const vector<Pass> &passes, - PassType pass_type, - PassMode pass_mode) +const Pass *Film::get_actual_display_pass(Scene *scene, PassType pass_type, PassMode pass_mode) { - const Pass *pass = Pass::find(passes, pass_type, pass_mode); - return get_actual_display_pass(passes, pass); + const Pass *pass = Pass::find(scene->passes, pass_type, pass_mode); + return get_actual_display_pass(scene, pass); } -const Pass *Film::get_actual_display_pass(const vector<Pass> &passes, const Pass *pass) +const Pass *Film::get_actual_display_pass(Scene *scene, const Pass *pass) { if (!pass) { return nullptr; @@ -492,7 +490,7 @@ const Pass *Film::get_actual_display_pass(const vector<Pass> &passes, const Pass if (!pass->is_written()) { if (pass->mode == PassMode::DENOISED) { - pass = Pass::find(passes, pass->type); + pass = Pass::find(scene->passes, pass->type); if (!pass) { return nullptr; } @@ -502,9 +500,9 @@ const Pass *Film::get_actual_display_pass(const vector<Pass> &passes, const Pass } } - if (pass->type == PASS_COMBINED) { + if (pass->type == PASS_COMBINED && scene->has_shadow_catcher()) { const Pass *shadow_catcher_matte_pass = Pass::find( - passes, PASS_SHADOW_CATCHER_MATTE, pass->mode); + scene->passes, PASS_SHADOW_CATCHER_MATTE, pass->mode); if (shadow_catcher_matte_pass) { pass = shadow_catcher_matte_pass; } diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h index a1a7e542a46..b622de00be8 100644 --- a/intern/cycles/render/film.h +++ b/intern/cycles/render/film.h @@ -83,10 +83,10 @@ class Film : public Node { /* Get display pass from its name. * Will do special logic to replace combined pass with shadow catcher matte. */ - static const Pass *get_actual_display_pass(const vector<Pass> &passes, + static const Pass *get_actual_display_pass(Scene *scene, PassType pass_type, PassMode pass_mode = PassMode::NOISY); - static const Pass *get_actual_display_pass(const vector<Pass> &passes, const Pass *pass); + static const Pass *get_actual_display_pass(Scene *scene, const Pass *pass); }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 72e97deba9a..5f3bd91c692 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -582,7 +582,7 @@ void Scene::update_passes() } /* Create passes for shadow catcher. */ - if (display_pass == PASS_SHADOW_CATCHER || has_shadow_catcher()) { + if (has_shadow_catcher()) { Pass::add_internal(passes, PASS_SHADOW_CATCHER, Pass::FLAG_AUTO); Pass::add_internal(passes, PASS_SHADOW_CATCHER_MATTE, Pass::FLAG_AUTO); diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 687e8f47429..9a64617e192 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -595,7 +595,7 @@ bool Session::get_render_tile_pixels(const string &pass_name, int num_components } } - pass = Film::get_actual_display_pass(scene->passes, pass); + pass = Film::get_actual_display_pass(scene, pass); const float exposure = scene->film->get_exposure(); const int num_samples = render_scheduler_.get_num_rendered_samples(); _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
