[Bf-blender-cvs] [75adea1bb75] temp-eevee-next-cryptomatte: Store cryptomatte meta data.

Jeroen Bakker noreply at git.blender.org
Fri Sep 2 08:33:12 CEST 2022


Commit: 75adea1bb75c3a2cf40393aa105032f0cb5aa637
Author: Jeroen Bakker
Date:   Tue Aug 30 14:04:31 2022 +0200
Branches: temp-eevee-next-cryptomatte
https://developer.blender.org/rB75adea1bb75c3a2cf40393aa105032f0cb5aa637

Store cryptomatte meta data.

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

M	source/blender/blenkernel/BKE_cryptomatte.h
M	source/blender/blenkernel/BKE_cryptomatte.hh
M	source/blender/blenkernel/intern/cryptomatte.cc
M	source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
M	source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
M	source/blender/draw/engines/eevee_next/eevee_engine.cc
M	source/blender/draw/engines/eevee_next/eevee_instance.cc
M	source/blender/draw/engines/eevee_next/eevee_instance.hh
M	source/blender/draw/engines/eevee_next/eevee_pipeline.cc

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

diff --git a/source/blender/blenkernel/BKE_cryptomatte.h b/source/blender/blenkernel/BKE_cryptomatte.h
index 56049ecf405..b2024f09278 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.h
+++ b/source/blender/blenkernel/BKE_cryptomatte.h
@@ -25,6 +25,8 @@ struct CryptomatteSession *BKE_cryptomatte_init(void);
 struct CryptomatteSession *BKE_cryptomatte_init_from_render_result(
     const struct RenderResult *render_result);
 struct CryptomatteSession *BKE_cryptomatte_init_from_scene(const struct Scene *scene);
+struct CryptomatteSession *BKE_cryptomatte_init_from_view_layer(
+    const struct ViewLayer *view_layer);
 void BKE_cryptomatte_free(struct CryptomatteSession *session);
 void BKE_cryptomatte_add_layer(struct CryptomatteSession *session, const char *layer_name);
 
diff --git a/source/blender/blenkernel/BKE_cryptomatte.hh b/source/blender/blenkernel/BKE_cryptomatte.hh
index cd3f8dc9f58..c4a440a1867 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.hh
+++ b/source/blender/blenkernel/BKE_cryptomatte.hh
@@ -107,6 +107,8 @@ struct CryptomatteStampDataCallbackData {
 
 const blender::Vector<std::string> &BKE_cryptomatte_layer_names_get(
     const CryptomatteSession &session);
+CryptomatteLayer *BKE_cryptomatte_layer_get(CryptomatteSession &session,
+                                            const StringRef layer_name);
 
 struct CryptomatteSessionDeleter {
   void operator()(CryptomatteSession *session)
diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc
index bb1e3bce92c..cb360931905 100644
--- a/source/blender/blenkernel/intern/cryptomatte.cc
+++ b/source/blender/blenkernel/intern/cryptomatte.cc
@@ -41,7 +41,9 @@ struct CryptomatteSession {
   CryptomatteSession() = default;
   CryptomatteSession(const Main *bmain);
   CryptomatteSession(StampData *stamp_data);
+  CryptomatteSession(const ViewLayer *view_layer);
   CryptomatteSession(const Scene *scene);
+  void init(const ViewLayer *view_layer);
 
   blender::bke::cryptomatte::CryptomatteLayer &add_layer(std::string layer_name);
   std::optional<std::string> operator[](float encoded_hash) const;
@@ -85,24 +87,34 @@ CryptomatteSession::CryptomatteSession(StampData *stamp_data)
       false);
 }
 
+CryptomatteSession::CryptomatteSession(const ViewLayer *view_layer)
+{
+  init(view_layer);
+}
+
 CryptomatteSession::CryptomatteSession(const Scene *scene)
 {
-  LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
-    eViewLayerCryptomatteFlags cryptoflags = static_cast<eViewLayerCryptomatteFlags>(
-        view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_ALL);
-    if (cryptoflags == 0) {
-      cryptoflags = static_cast<eViewLayerCryptomatteFlags>(VIEW_LAYER_CRYPTOMATTE_ALL);
-    }
+  LISTBASE_FOREACH (const ViewLayer *, view_layer, &scene->view_layers) {
+    init(view_layer);
+  }
+}
 
-    if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_OBJECT) {
-      add_layer(blender::StringRefNull(view_layer->name) + "." + RE_PASSNAME_CRYPTOMATTE_OBJECT);
-    }
-    if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_ASSET) {
-      add_layer(blender::StringRefNull(view_layer->name) + "." + RE_PASSNAME_CRYPTOMATTE_ASSET);
-    }
-    if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_MATERIAL) {
-      add_layer(blender::StringRefNull(view_layer->name) + "." + RE_PASSNAME_CRYPTOMATTE_MATERIAL);
-    }
+void CryptomatteSession::init(const ViewLayer *view_layer)
+{
+  eViewLayerCryptomatteFlags cryptoflags = static_cast<eViewLayerCryptomatteFlags>(
+      view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_ALL);
+  if (cryptoflags == 0) {
+    cryptoflags = static_cast<eViewLayerCryptomatteFlags>(VIEW_LAYER_CRYPTOMATTE_ALL);
+  }
+
+  if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_OBJECT) {
+    add_layer(blender::StringRefNull(view_layer->name) + "." + RE_PASSNAME_CRYPTOMATTE_OBJECT);
+  }
+  if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_ASSET) {
+    add_layer(blender::StringRefNull(view_layer->name) + "." + RE_PASSNAME_CRYPTOMATTE_ASSET);
+  }
+  if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_MATERIAL) {
+    add_layer(blender::StringRefNull(view_layer->name) + "." + RE_PASSNAME_CRYPTOMATTE_MATERIAL);
   }
 }
 
@@ -144,6 +156,12 @@ struct CryptomatteSession *BKE_cryptomatte_init_from_scene(const struct Scene *s
   return session;
 }
 
+struct CryptomatteSession *BKE_cryptomatte_init_from_view_layer(const struct ViewLayer *view_layer)
+{
+  CryptomatteSession *session = new CryptomatteSession(view_layer);
+  return session;
+}
+
 void BKE_cryptomatte_add_layer(struct CryptomatteSession *session, const char *layer_name)
 {
   session->add_layer(layer_name);
@@ -627,4 +645,9 @@ const blender::Vector<std::string> &BKE_cryptomatte_layer_names_get(
   return session.layer_names;
 }
 
+CryptomatteLayer *BKE_cryptomatte_layer_get(CryptomatteSession &session, StringRef layer_name)
+{
+  return session.layers.lookup_ptr(layer_name);
+}
+
 }  // namespace blender::bke::cryptomatte
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
index 49d20ac35de..20344653fcc 100644
--- a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
@@ -1,4 +1,4 @@
-#include "BKE_cryptomatte.h"
+#include "BKE_cryptomatte.hh"
 
 #include "GPU_material.h"
 
@@ -10,7 +10,36 @@ namespace blender::eevee {
 
 void Cryptomatte::begin_sync()
 {
-  const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
+  const eViewLayerEEVEEPassType enabled_passes = static_cast<eViewLayerEEVEEPassType>(
+      inst_.film.enabled_passes_get() &
+      (EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT | EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET |
+       EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET));
+
+  session_.reset();
+  object_layer_ = nullptr;
+  asset_layer_ = nullptr;
+  material_layer_ = nullptr;
+
+  if (enabled_passes && !inst_.is_viewport()) {
+    session_.reset(BKE_cryptomatte_init_from_view_layer(inst_.view_layer));
+
+    for (const std::string &layer_name :
+         bke::cryptomatte::BKE_cryptomatte_layer_names_get(*session_)) {
+      StringRef layer_name_ref = layer_name;
+      bke::cryptomatte::CryptomatteLayer *layer = bke::cryptomatte::BKE_cryptomatte_layer_get(
+          *session_, layer_name);
+      if (layer_name_ref.endswith(RE_PASSNAME_CRYPTOMATTE_OBJECT)) {
+        object_layer_ = layer;
+      }
+      else if (layer_name_ref.endswith(RE_PASSNAME_CRYPTOMATTE_ASSET)) {
+        asset_layer_ = layer;
+      }
+      else if (layer_name_ref.endswith(RE_PASSNAME_CRYPTOMATTE_MATERIAL)) {
+        material_layer_ = layer;
+      }
+    }
+  }
+
   if (!(enabled_passes &
         (EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT | EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET))) {
     cryptomatte_object_buf.resize(16);
@@ -29,7 +58,7 @@ void Cryptomatte::sync_object(Object *ob)
   float2 object_hashes(0.0f, 0.0f);
 
   if (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) {
-    object_hashes[0] = hash(ob->id);
+    object_hashes[0] = register_id(EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT, ob->id);
   }
 
   if (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET) {
@@ -37,7 +66,7 @@ void Cryptomatte::sync_object(Object *ob)
     while (asset->parent) {
       asset = asset->parent;
     }
-    object_hashes[1] = hash(asset->id);
+    object_hashes[1] = register_id(EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET, asset->id);
   }
 
   cryptomatte_object_buf.get_or_resize(resource_id) = object_hashes;
@@ -46,13 +75,40 @@ void Cryptomatte::sync_object(Object *ob)
 void Cryptomatte::end_sync()
 {
   cryptomatte_object_buf.push_update();
+
+  object_layer_ = nullptr;
+  asset_layer_ = nullptr;
+  material_layer_ = nullptr;
 }
 
-float Cryptomatte::hash(const ID &id) const
+float Cryptomatte::register_id(const eViewLayerEEVEEPassType layer, const ID &id) const
 {
-  const char *name = &id.name[2];
-  const int name_len = BLI_strnlen(name, MAX_NAME - 2);
-  uint32_t cryptomatte_hash = BKE_cryptomatte_hash(name, name_len);
+  BLI_assert(ELEM(layer,
+                  EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT,
+                  EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET,
+                  EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL));
+
+  uint32_t cryptomatte_hash = 0;
+  if (session_) {
+    if (layer == EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) {
+      BLI_assert(object_layer_);
+      cryptomatte_hash = object_layer_->add_ID(id);
+    }
+    else if (layer == EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET) {
+      BLI_assert(asset_layer_);
+      cryptomatte_hash = asset_layer_->add_ID(id);
+    }
+    else if (layer == EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) {
+      BLI_assert(material_layer_);
+      cryptomatte_hash = material_layer_->add_ID(id);
+    }
+  }
+  else {
+    const char *name = &id.name[2];
+    const int name_len = BLI_strnlen(name, MAX_NAME - 2);
+    cryptomatte_hash = BKE_cryptomatte_hash(name, name_len);
+  }
+
   return BKE_cryptomatte_hash_to_float(cryptomatte_hash);
 }
 
@@ -61,4 +117,11 @@ void Cryptomatte::bind_resources(DRWShadingGroup *grp)
   DRW_shgroup_storage_block_ref(grp, "cryptomatte_object_buf", &cryptomatte_object_buf);
 }
 
+void Cryptomatte::store_metadata(RenderResult *render_result)
+{
+  if (session_) {
+    BKE_cryptomatte_store_metadata(&*session_, render_result, inst_.view_layer);
+  }
+}
+
 }  // namespace blender::eevee
\ No newline at end of file
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
index 5faf048cb93..de7afc66693 100644
--- a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
@@ -17,8 +17,11 @@
 
 #include "eevee_shader_shared.hh"
 
+#include "BKE_cryptomatte.hh"
+
 extern "C" {
 struct Material;
+struct CryptomatteSession;
 }
 
 namespace blender::eevee {
@@ -33,20 +36,29 @@ class Cryptomatte {
  private:
   class Instance &inst_;
 
+  bke::cryptomatte::CryptomatteSessionPtr session_;
+
+  /* Cached pointer to the cryptomatte layer instances. */
+  bke::cryptomatte::CryptomatteLayer *object_layer_ = nullptr;
+  bke::cryptomatte::CryptomatteLayer *asset_layer_ = nullptr;
+  bke::c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list