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:
authorJeroen Bakker <jbakker>2022-09-13 12:07:30 +0300
committerJeroen Bakker <jeroen@blender.org>2022-09-13 12:07:38 +0300
commit8068b89a681c467f3d449b9ddc2ebec5b817c2fc (patch)
tree2bed18be11a6b13ccd9092ea133993a19509a726 /source/blender/blenkernel
parentbb3a021427f2132f1db62a76eeca2ca4be1601da (diff)
EEVEE-Next: Cryptomatte render passes.
This change adds cryptomatte render passes to EEVEE-Next. Due to the upcoming viewport compositor we also improved cryptomatte so it will be real-time. This also allows viewing the cryptomatte passes in the viewport directly. {F13482749} A surface shader would store any active cryptomatte layer to a texture. Object hash is stored as R, Asset hash as G and Material hash as B. Hashes are only calculated when the cryptomatte layer is active to reduce any unneeded work. During film accumulation the hashes are separated and stored in a texture array that matches the cryptomatte standard. For the real-time use case sorting is skipped. For final rendering the samples are sorted and normalized. NOTE: Eventually we should also do sample normalization in the viewport in order to extract the correct mask when using the viewport compositor. Reviewed By: fclem Maniphest Tasks: T99390 Differential Revision: https://developer.blender.org/D15753
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_cryptomatte.h2
-rw-r--r--source/blender/blenkernel/BKE_cryptomatte.hh26
-rw-r--r--source/blender/blenkernel/intern/cryptomatte.cc79
3 files changed, 67 insertions, 40 deletions
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..dd08f7b5c4f 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.hh
+++ b/source/blender/blenkernel/BKE_cryptomatte.hh
@@ -12,6 +12,7 @@
#include "BKE_cryptomatte.h"
+#include "BLI_hash_mm3.h"
#include "BLI_map.hh"
#include "BLI_string_ref.hh"
@@ -54,10 +55,14 @@ struct CryptomatteHash {
uint32_t hash;
CryptomatteHash(uint32_t hash);
- CryptomatteHash(const char *name, int name_len);
- static CryptomatteHash from_hex_encoded(blender::StringRef hex_encoded);
+ CryptomatteHash(const char *name, int name_len)
+ {
+ hash = BLI_hash_mm3((const unsigned char *)name, name_len, 0);
+ }
+ static CryptomatteHash from_hex_encoded(blender::StringRef hex_encoded);
std::string hex_encoded() const;
+
/**
* Convert a cryptomatte hash to a float.
*
@@ -70,7 +75,20 @@ struct CryptomatteHash {
*
* Note that this conversion assumes to be running on a L-endian system.
*/
- float float_encoded() const;
+ float float_encoded() const
+ {
+ uint32_t mantissa = hash & ((1 << 23) - 1);
+ uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
+ exponent = MAX2(exponent, (uint32_t)1);
+ exponent = MIN2(exponent, (uint32_t)254);
+ exponent = exponent << 23;
+ uint32_t sign = (hash >> 31);
+ sign = sign << 31;
+ uint32_t float_bits = sign | exponent | mantissa;
+ float f;
+ memcpy(&f, &float_bits, sizeof(uint32_t));
+ return f;
+ }
};
struct CryptomatteLayer {
@@ -107,6 +125,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 102bda0f2b6..72204f6624e 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;
@@ -54,13 +56,15 @@ struct CryptomatteSession {
CryptomatteSession::CryptomatteSession(const Main *bmain)
{
if (!BLI_listbase_is_empty(&bmain->objects)) {
- blender::bke::cryptomatte::CryptomatteLayer &objects = add_layer("CryptoObject");
+ blender::bke::cryptomatte::CryptomatteLayer &objects = add_layer(
+ RE_PASSNAME_CRYPTOMATTE_OBJECT);
LISTBASE_FOREACH (ID *, id, &bmain->objects) {
objects.add_ID(*id);
}
}
if (!BLI_listbase_is_empty(&bmain->materials)) {
- blender::bke::cryptomatte::CryptomatteLayer &materials = add_layer("CryptoMaterial");
+ blender::bke::cryptomatte::CryptomatteLayer &materials = add_layer(
+ RE_PASSNAME_CRYPTOMATTE_MATERIAL);
LISTBASE_FOREACH (ID *, id, &bmain->materials) {
materials.add_ID(*id);
}
@@ -83,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) + ".CryptoObject");
- }
- if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_ASSET) {
- add_layer(blender::StringRefNull(view_layer->name) + ".CryptoAsset");
- }
- if (cryptoflags & VIEW_LAYER_CRYPTOMATTE_MATERIAL) {
- add_layer(blender::StringRefNull(view_layer->name) + ".CryptoMaterial");
- }
+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);
}
}
@@ -142,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);
@@ -485,11 +505,6 @@ CryptomatteHash::CryptomatteHash(uint32_t hash) : hash(hash)
{
}
-CryptomatteHash::CryptomatteHash(const char *name, const int name_len)
-{
- hash = BLI_hash_mm3((const unsigned char *)name, name_len, 0);
-}
-
CryptomatteHash CryptomatteHash::from_hex_encoded(blender::StringRef hex_encoded)
{
CryptomatteHash result(0);
@@ -504,21 +519,6 @@ std::string CryptomatteHash::hex_encoded() const
return encoded.str();
}
-float CryptomatteHash::float_encoded() const
-{
- uint32_t mantissa = hash & ((1 << 23) - 1);
- uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
- exponent = MAX2(exponent, (uint32_t)1);
- exponent = MIN2(exponent, (uint32_t)254);
- exponent = exponent << 23;
- uint32_t sign = (hash >> 31);
- sign = sign << 31;
- uint32_t float_bits = sign | exponent | mantissa;
- float f;
- memcpy(&f, &float_bits, sizeof(uint32_t));
- return f;
-}
-
std::unique_ptr<CryptomatteLayer> CryptomatteLayer::read_from_manifest(
blender::StringRefNull manifest)
{
@@ -625,4 +625,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