[Bf-blender-cvs] [e509164b4e2] cycles-x: Fix access shadow catcher pass without catcher objects in Cycles X

Sergey Sharybin noreply at git.blender.org
Fri Jul 9 11:12:22 CEST 2021


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();



More information about the Bf-blender-cvs mailing list