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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc')
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc132
1 files changed, 132 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
new file mode 100644
index 00000000000..10be121f533
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+#include "BKE_cryptomatte.hh"
+
+#include "GPU_material.h"
+
+#include "eevee_cryptomatte.hh"
+#include "eevee_instance.hh"
+#include "eevee_renderbuffers.hh"
+
+namespace blender::eevee {
+
+void Cryptomatte::begin_sync()
+{
+ 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);
+ }
+}
+
+void Cryptomatte::sync_object(Object *ob, ResourceHandle res_handle)
+{
+ const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
+ if (!(enabled_passes &
+ (EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT | EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET))) {
+ return;
+ }
+
+ uint32_t resource_id = res_handle.resource_index();
+ float2 object_hashes(0.0f, 0.0f);
+
+ if (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) {
+ object_hashes[0] = register_id(EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT, ob->id);
+ }
+
+ if (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET) {
+ Object *asset = ob;
+ while (asset->parent) {
+ asset = asset->parent;
+ }
+ object_hashes[1] = register_id(EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET, asset->id);
+ }
+ cryptomatte_object_buf.get_or_resize(resource_id) = object_hashes;
+}
+
+void Cryptomatte::sync_material(const ::Material *material)
+{
+ /* Material crypto hashes are generated during shader codegen stage. We only need to register
+ * them to store inside the metadata. */
+ if (material_layer_ && material) {
+ material_layer_->add_ID(material->id);
+ }
+}
+
+void Cryptomatte::end_sync()
+{
+ cryptomatte_object_buf.push_update();
+
+ object_layer_ = nullptr;
+ asset_layer_ = nullptr;
+ material_layer_ = nullptr;
+}
+
+float Cryptomatte::register_id(const eViewLayerEEVEEPassType layer, const ID &id) const
+{
+ 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_MATERIAL) {
+ 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);
+}
+
+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