Cryptomatte: Flexible Definition of CryptomatteLayers.
Cryptomatte layers in Blender are predefined. Other render engines might have other naming schemes. This patch will allow creation of cryptomatte layers with other names. This will be used by D3959 to load cryptomatte openexr files from other render engines. EEVEE and Cycles still use our fix naming scheme so no changes are detectable by users.
This commit is contained in:
parent
1d9092f632
commit
61b3870981
|
@ -39,13 +39,17 @@ struct RenderResult;
|
|||
|
||||
struct CryptomatteSession *BKE_cryptomatte_init(void);
|
||||
void BKE_cryptomatte_free(struct CryptomatteSession *session);
|
||||
void BKE_cryptomatte_add_layer(struct CryptomatteSession *session, const char *layer_name);
|
||||
|
||||
uint32_t BKE_cryptomatte_hash(const char *name, int name_len);
|
||||
uint32_t BKE_cryptomatte_object_hash(struct CryptomatteSession *session,
|
||||
const char *layer_name,
|
||||
const struct Object *object);
|
||||
uint32_t BKE_cryptomatte_material_hash(struct CryptomatteSession *session,
|
||||
const char *layer_name,
|
||||
const struct Material *material);
|
||||
uint32_t BKE_cryptomatte_asset_hash(struct CryptomatteSession *session,
|
||||
const char *layer_name,
|
||||
const struct Object *object);
|
||||
float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash);
|
||||
|
||||
|
@ -53,11 +57,9 @@ char *BKE_cryptomatte_entries_to_matte_id(struct NodeCryptomatte *node_storage);
|
|||
void BKE_cryptomatte_matte_id_to_entries(struct NodeCryptomatte *node_storage,
|
||||
const char *matte_id);
|
||||
|
||||
void BKE_cryptomatte_store_metadata(struct CryptomatteSession *session,
|
||||
void BKE_cryptomatte_store_metadata(const struct CryptomatteSession *session,
|
||||
struct RenderResult *render_result,
|
||||
const ViewLayer *view_layer,
|
||||
eViewLayerCryptomatteFlags cryptomatte_layer,
|
||||
const char *cryptomatte_layer_name);
|
||||
const ViewLayer *view_layer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -47,13 +47,12 @@
|
|||
#include <string_view>
|
||||
|
||||
struct CryptomatteSession {
|
||||
blender::bke::cryptomatte::CryptomatteLayer objects;
|
||||
blender::bke::cryptomatte::CryptomatteLayer assets;
|
||||
blender::bke::cryptomatte::CryptomatteLayer materials;
|
||||
blender::Map<std::string, blender::bke::cryptomatte::CryptomatteLayer> layers;
|
||||
|
||||
CryptomatteSession();
|
||||
CryptomatteSession(const Main *bmain);
|
||||
|
||||
blender::bke::cryptomatte::CryptomatteLayer &add_layer(std::string layer_name);
|
||||
std::optional<std::string> operator[](float encoded_hash) const;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
|
@ -67,21 +66,34 @@ CryptomatteSession::CryptomatteSession()
|
|||
|
||||
CryptomatteSession::CryptomatteSession(const Main *bmain)
|
||||
{
|
||||
LISTBASE_FOREACH (ID *, id, &bmain->objects) {
|
||||
objects.add_ID(*id);
|
||||
if (!BLI_listbase_is_empty(&bmain->objects)) {
|
||||
blender::bke::cryptomatte::CryptomatteLayer &objects = add_layer("CryptoObject");
|
||||
LISTBASE_FOREACH (ID *, id, &bmain->objects) {
|
||||
objects.add_ID(*id);
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (ID *, id, &bmain->materials) {
|
||||
materials.add_ID(*id);
|
||||
if (!BLI_listbase_is_empty(&bmain->materials)) {
|
||||
blender::bke::cryptomatte::CryptomatteLayer &materials = add_layer("CryptoMaterial");
|
||||
LISTBASE_FOREACH (ID *, id, &bmain->materials) {
|
||||
materials.add_ID(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blender::bke::cryptomatte::CryptomatteLayer &CryptomatteSession::add_layer(std::string layer_name)
|
||||
{
|
||||
return layers.lookup_or_add_default(layer_name);
|
||||
}
|
||||
|
||||
std::optional<std::string> CryptomatteSession::operator[](float encoded_hash) const
|
||||
{
|
||||
std::optional<std::string> result = objects[encoded_hash];
|
||||
if (result) {
|
||||
return result;
|
||||
for (const blender::bke::cryptomatte::CryptomatteLayer &layer : layers.values()) {
|
||||
std::optional<std::string> result = layer[encoded_hash];
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return materials[encoded_hash];
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
CryptomatteSession *BKE_cryptomatte_init(void)
|
||||
|
@ -90,6 +102,11 @@ CryptomatteSession *BKE_cryptomatte_init(void)
|
|||
return session;
|
||||
}
|
||||
|
||||
void BKE_cryptomatte_add_layer(struct CryptomatteSession *session, const char *layer_name)
|
||||
{
|
||||
session->add_layer(layer_name);
|
||||
}
|
||||
|
||||
void BKE_cryptomatte_free(CryptomatteSession *session)
|
||||
{
|
||||
BLI_assert(session != nullptr);
|
||||
|
@ -102,26 +119,36 @@ uint32_t BKE_cryptomatte_hash(const char *name, const int name_len)
|
|||
return hash.hash;
|
||||
}
|
||||
|
||||
uint32_t BKE_cryptomatte_object_hash(CryptomatteSession *session, const Object *object)
|
||||
uint32_t BKE_cryptomatte_object_hash(CryptomatteSession *session,
|
||||
const char *layer_name,
|
||||
const Object *object)
|
||||
{
|
||||
return session->objects.add_ID(object->id);
|
||||
blender::bke::cryptomatte::CryptomatteLayer *layer = session->layers.lookup_ptr(layer_name);
|
||||
BLI_assert(layer);
|
||||
return layer->add_ID(object->id);
|
||||
}
|
||||
|
||||
uint32_t BKE_cryptomatte_material_hash(CryptomatteSession *session, const Material *material)
|
||||
uint32_t BKE_cryptomatte_material_hash(CryptomatteSession *session,
|
||||
const char *layer_name,
|
||||
const Material *material)
|
||||
{
|
||||
if (material == nullptr) {
|
||||
return 0.0f;
|
||||
}
|
||||
return session->materials.add_ID(material->id);
|
||||
blender::bke::cryptomatte::CryptomatteLayer *layer = session->layers.lookup_ptr(layer_name);
|
||||
BLI_assert(layer);
|
||||
return layer->add_ID(material->id);
|
||||
}
|
||||
|
||||
uint32_t BKE_cryptomatte_asset_hash(CryptomatteSession *session, const Object *object)
|
||||
uint32_t BKE_cryptomatte_asset_hash(CryptomatteSession *session,
|
||||
const char *layer_name,
|
||||
const Object *object)
|
||||
{
|
||||
const Object *asset_object = object;
|
||||
while (asset_object->parent != nullptr) {
|
||||
asset_object = asset_object->parent;
|
||||
}
|
||||
return session->assets.add_ID(asset_object->id);
|
||||
return BKE_cryptomatte_object_hash(session, layer_name, asset_object);
|
||||
}
|
||||
|
||||
float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash)
|
||||
|
@ -213,37 +240,23 @@ static void add_render_result_meta_data(RenderResult *render_result,
|
|||
value.data());
|
||||
}
|
||||
|
||||
void BKE_cryptomatte_store_metadata(struct CryptomatteSession *session,
|
||||
void BKE_cryptomatte_store_metadata(const struct CryptomatteSession *session,
|
||||
RenderResult *render_result,
|
||||
const ViewLayer *view_layer,
|
||||
eViewLayerCryptomatteFlags cryptomatte_layer,
|
||||
const char *cryptomatte_layer_name)
|
||||
const ViewLayer *view_layer)
|
||||
{
|
||||
/* Create Manifest. */
|
||||
blender::bke::cryptomatte::CryptomatteLayer *layer = nullptr;
|
||||
switch (cryptomatte_layer) {
|
||||
case VIEW_LAYER_CRYPTOMATTE_OBJECT:
|
||||
layer = &session->objects;
|
||||
break;
|
||||
case VIEW_LAYER_CRYPTOMATTE_MATERIAL:
|
||||
layer = &session->materials;
|
||||
break;
|
||||
case VIEW_LAYER_CRYPTOMATTE_ASSET:
|
||||
layer = &session->assets;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(!"Incorrect cryptomatte layer");
|
||||
break;
|
||||
for (const blender::Map<std::string, blender::bke::cryptomatte::CryptomatteLayer>::Item item :
|
||||
session->layers.items()) {
|
||||
const blender::StringRefNull layer_name(item.key);
|
||||
const blender::bke::cryptomatte::CryptomatteLayer &layer = item.value;
|
||||
|
||||
const std::string manifest = layer.manifest();
|
||||
const std::string name = cryptomatte_determine_name(view_layer, layer_name);
|
||||
|
||||
add_render_result_meta_data(render_result, name, "name", name);
|
||||
add_render_result_meta_data(render_result, name, "hash", "MurmurHash3_32");
|
||||
add_render_result_meta_data(render_result, name, "conversion", "uint32_to_float32");
|
||||
add_render_result_meta_data(render_result, name, "manifest", manifest);
|
||||
}
|
||||
|
||||
const std::string manifest = layer->manifest();
|
||||
const std::string name = cryptomatte_determine_name(view_layer, cryptomatte_layer_name);
|
||||
|
||||
/* Store the meta data into the render result. */
|
||||
add_render_result_meta_data(render_result, name, "name", name);
|
||||
add_render_result_meta_data(render_result, name, "hash", "MurmurHash3_32");
|
||||
add_render_result_meta_data(render_result, name, "conversion", "uint32_to_float32");
|
||||
add_render_result_meta_data(render_result, name, "manifest", manifest);
|
||||
}
|
||||
|
||||
namespace blender::bke::cryptomatte {
|
||||
|
|
|
@ -124,8 +124,20 @@ void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata)
|
|||
if (!DRW_state_is_image_render()) {
|
||||
return;
|
||||
}
|
||||
if (eevee_cryptomatte_active_layers(view_layer) != 0) {
|
||||
g_data->cryptomatte_session = BKE_cryptomatte_init();
|
||||
const eViewLayerCryptomatteFlags active_layers = eevee_cryptomatte_active_layers(view_layer);
|
||||
if (active_layers) {
|
||||
struct CryptomatteSession *session = BKE_cryptomatte_init();
|
||||
if ((active_layers & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
|
||||
BKE_cryptomatte_add_layer(session, "CryptoObject");
|
||||
}
|
||||
if ((active_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
|
||||
BKE_cryptomatte_add_layer(session, "CryptoMaterial");
|
||||
}
|
||||
if ((active_layers & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
|
||||
BKE_cryptomatte_add_layer(session, "CryptoAsset");
|
||||
}
|
||||
g_data->cryptomatte_session = session;
|
||||
|
||||
g_data->render_passes |= EEVEE_RENDER_PASS_CRYPTOMATTE | EEVEE_RENDER_PASS_VOLUME_LIGHT;
|
||||
g_data->cryptomatte_accurate_mode = (view_layer->cryptomatte_flag &
|
||||
VIEW_LAYER_CRYPTOMATTE_ACCURATE) != 0;
|
||||
|
@ -208,20 +220,22 @@ static DRWShadingGroup *eevee_cryptomatte_shading_group_create(EEVEE_Data *vedat
|
|||
EEVEE_PassList *psl = vedata->psl;
|
||||
int layer_offset = 0;
|
||||
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
|
||||
uint32_t cryptomatte_hash = BKE_cryptomatte_object_hash(g_data->cryptomatte_session, ob);
|
||||
uint32_t cryptomatte_hash = BKE_cryptomatte_object_hash(
|
||||
g_data->cryptomatte_session, "CryptoObject", ob);
|
||||
float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
|
||||
cryptohash[layer_offset] = cryptomatte_color_value;
|
||||
layer_offset++;
|
||||
}
|
||||
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
|
||||
uint32_t cryptomatte_hash = BKE_cryptomatte_material_hash(g_data->cryptomatte_session,
|
||||
material);
|
||||
uint32_t cryptomatte_hash = BKE_cryptomatte_material_hash(
|
||||
g_data->cryptomatte_session, "CryptoMaterial", material);
|
||||
float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
|
||||
cryptohash[layer_offset] = cryptomatte_color_value;
|
||||
layer_offset++;
|
||||
}
|
||||
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
|
||||
uint32_t cryptomatte_hash = BKE_cryptomatte_asset_hash(g_data->cryptomatte_session, ob);
|
||||
uint32_t cryptomatte_hash = BKE_cryptomatte_asset_hash(
|
||||
g_data->cryptomatte_session, "CryptoAsset", ob);
|
||||
float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
|
||||
cryptohash[layer_offset] = cryptomatte_color_value;
|
||||
layer_offset++;
|
||||
|
@ -693,30 +707,9 @@ void EEVEE_cryptomatte_store_metadata(EEVEE_Data *vedata, RenderResult *render_r
|
|||
EEVEE_PrivateData *g_data = vedata->stl->g_data;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const ViewLayer *view_layer = draw_ctx->view_layer;
|
||||
const eViewLayerCryptomatteFlags cryptomatte_layers = view_layer->cryptomatte_flag &
|
||||
VIEW_LAYER_CRYPTOMATTE_ALL;
|
||||
BLI_assert(g_data->cryptomatte_session);
|
||||
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
|
||||
BKE_cryptomatte_store_metadata(g_data->cryptomatte_session,
|
||||
render_result,
|
||||
view_layer,
|
||||
VIEW_LAYER_CRYPTOMATTE_OBJECT,
|
||||
"CryptoObject");
|
||||
}
|
||||
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
|
||||
BKE_cryptomatte_store_metadata(g_data->cryptomatte_session,
|
||||
render_result,
|
||||
view_layer,
|
||||
VIEW_LAYER_CRYPTOMATTE_MATERIAL,
|
||||
"CryptoMaterial");
|
||||
}
|
||||
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
|
||||
BKE_cryptomatte_store_metadata(g_data->cryptomatte_session,
|
||||
render_result,
|
||||
view_layer,
|
||||
VIEW_LAYER_CRYPTOMATTE_ASSET,
|
||||
"CryptoAsset");
|
||||
}
|
||||
|
||||
BKE_cryptomatte_store_metadata(g_data->cryptomatte_session, render_result, view_layer);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
Loading…
Reference in New Issue