[Bf-blender-cvs] [0bbe7ed517e] cycles-x: Cycles X: Use approximate shadow catcher in viewport

Sergey Sharybin noreply at git.blender.org
Thu Jun 3 16:58:38 CEST 2021


Commit: 0bbe7ed517e7b746c387a716d98cee83717aff74
Author: Sergey Sharybin
Date:   Thu Jun 3 16:55:20 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB0bbe7ed517e7b746c387a716d98cee83717aff74

Cycles X: Use approximate shadow catcher in viewport

This change makes it so that shadow catcher objects have effect in
the viewport. Currently is limited to the approximate mode since it
is the only one possible with the draw manager integrator.

Differential Revision: https://developer.blender.org/D11484

===================================================================

M	intern/cycles/blender/blender_sync.cpp
M	intern/cycles/render/film.cpp
M	intern/cycles/render/film.h
M	intern/cycles/render/session.cpp

===================================================================

diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index ac41fa56637..74aeecc605d 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -426,7 +426,14 @@ void BlenderSync::sync_film(BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d)
     }
   }
 
-  film->set_use_approximate_shadow_catcher(!get_boolean(crl, "use_pass_shadow_catcher"));
+  /* Blender viewport does not support proper shadow catcher compositing, so force an approximate
+   * mode to improve visual feedback. */
+  if (b_v3d) {
+    film->set_use_approximate_shadow_catcher(true);
+  }
+  else {
+    film->set_use_approximate_shadow_catcher(!get_boolean(crl, "use_pass_shadow_catcher"));
+  }
 }
 
 /* Render Layer */
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index e4a872efa22..acf83ee4705 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -168,11 +168,14 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
 
   KernelFilm *kfilm = &dscene->data.film;
 
+  const PassType display_pass_type = get_actual_display_pass_type(scene->passes,
+                                                                  get_display_pass());
+
   /* update __data */
   kfilm->exposure = exposure;
   kfilm->pass_flag = 0;
 
-  kfilm->display_pass_type = get_display_pass();
+  kfilm->display_pass_type = display_pass_type;
   kfilm->display_pass_offset = -1;
   kfilm->show_active_pixels = show_active_pixels;
   kfilm->use_approximate_shadow_catcher = get_use_approximate_shadow_catcher();
@@ -212,15 +215,6 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
 
   bool have_cryptomatte = false;
 
-  /* When shadow catcher is used the combined pass is only used to get proper value for the
-   * shadow catcher pass. It is not very useful for artists as it is. What artists expect as a
-   * combined pass is something what is to be alpha-overed onto the footage. So we swap the
-   * combined pass with shadow catcher matte here. */
-  const PassType effective_display_pass_type = (display_pass == PASS_COMBINED &&
-                                                scene->has_shadow_catcher()) ?
-                                                   PASS_SHADOW_CATCHER_MATTE :
-                                                   display_pass;
-
   for (size_t i = 0; i < scene->passes.size(); i++) {
     Pass &pass = scene->passes[i];
 
@@ -389,7 +383,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
         break;
     }
 
-    if (pass.type == effective_display_pass_type) {
+    if (pass.type == display_pass_type) {
       kfilm->display_pass_offset = kfilm->pass_stride;
     }
 
@@ -473,4 +467,36 @@ 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, const string &pass_name)
+{
+  const Pass *pass = Pass::find(passes, pass_name);
+  if (!pass) {
+    return nullptr;
+  }
+
+  const PassType actual_pass_type = get_actual_display_pass_type(passes, pass->type);
+  if (actual_pass_type != pass->type) {
+    /* This is a bit annoying to have a secondary `find()` here. But this is unlikely to become
+     * a bottleneck, so prefer to de-duplicate logic. */
+    return Pass::find(passes, PASS_SHADOW_CATCHER_MATTE);
+  }
+
+  return pass;
+}
+
+PassType Film::get_actual_display_pass_type(const vector<Pass> &passes, const PassType pass_type)
+{
+  /* When shadow catcher is used the combined pass is only used to get proper value for the
+   * shadow catcher pass. It is not very useful for artists as it is. What artists expect as a
+   * combined pass is something what is to be alpha-overed onto the footage. So we swap the
+   * combined pass with shadow catcher matte here. */
+  if (pass_type == PASS_COMBINED) {
+    if (Pass::contains(passes, PASS_SHADOW_CATCHER_MATTE)) {
+      return PASS_SHADOW_CATCHER_MATTE;
+    }
+  }
+
+  return pass_type;
+}
+
 CCL_NAMESPACE_END
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index 1b9cbac5266..44affcb31eb 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -80,6 +80,12 @@ class Film : public Node {
   void assign_and_tag_passes_update(Scene *scene, const vector<Pass> &passes);
 
   int get_aov_offset(Scene *scene, string name, bool &is_color);
+
+  /* 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, const string &pass_name);
+  static PassType get_actual_display_pass_type(const vector<Pass> &passes,
+                                               const PassType pass_type);
 };
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index b7a1b2760fa..9975fbcf362 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -557,30 +557,9 @@ int2 Session::get_render_tile_offset() const
   return make_int2(tile.x - tile.full_x, tile.y - tile.full_y);
 }
 
-static const Pass *get_actual_pass_for_pixels(const vector<Pass> &passes, const string &pass_name)
-{
-  const Pass *pass = Pass::find(passes, pass_name);
-  if (!pass) {
-    return nullptr;
-  }
-
-  /* When shadow catcher is used the combined pass is only used to get proper value for the
-   * shadow catcher pass. It is not very useful for artists as it is. What artists expect as a
-   * combined pass is something what is to be alpha-overed onto the footage. So we swap the
-   * combined pass with shadow catcher matte here. */
-  if (pass->type == PASS_COMBINED) {
-    const Pass *matte_pass = Pass::find(passes, PASS_SHADOW_CATCHER_MATTE);
-    if (matte_pass) {
-      return matte_pass;
-    }
-  }
-
-  return pass;
-}
-
 bool Session::get_render_tile_pixels(const string &pass_name, int num_components, float *pixels)
 {
-  const Pass *pass = get_actual_pass_for_pixels(scene->passes, pass_name);
+  const Pass *pass = Film::get_actual_display_pass(scene->passes, pass_name);
   if (!pass) {
     return false;
   }



More information about the Bf-blender-cvs mailing list