diff options
author | Jeroen Bakker <jbakker> | 2020-12-04 10:28:43 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2020-12-04 10:46:34 +0300 |
commit | 76a0b322e4d3244e59a154c8255b84a4fbc33117 (patch) | |
tree | 53ab3d8d8b13e5c4e214b06fd03281f952da3883 /source/blender/draw/engines/eevee/eevee_private.h | |
parent | 2bae11d5c08a9095f2c8ec5e465e73ada9840ed1 (diff) |
EEVEE Cryptomatte
Cryptomatte is a standard to efficiently create mattes for compositing. The
renderer outputs the required render passes, which can then be used in the
compositor to create masks for specified objects. Unlike the Material and Object
Index passes, the objects to isolate are selected in compositing, and mattes
will be anti-aliased.
Cryptomatte was already available in Cycles this patch adds it to the EEVEE
render engine. Original specification can be found at
https://raw.githubusercontent.com/Psyop/Cryptomatte/master/specification/IDmattes_poster.pdf
**Accurate mode**
Following Cycles, there are two accuracy modes. The difference between the two
modes is the number of render samples they take into account to create the
render passes. When accurate mode is off the number of levels is used. When
accuracy mode is active, the number of render samples is used.
**Deviation from standard**
Cryptomatte specification is based on a path trace approach where samples and
coverage are calculated at the same time. In EEVEE a sample is an exact match on
top of a prepared depth buffer. Coverage is at that moment always 1. By sampling
multiple times the number of surface hits decides the actual surface coverage
for a matte per pixel.
**Implementation Overview**
When drawing to the cryptomatte GPU buffer the depth of the fragment is matched
to the active depth buffer. The hashes of each cryptomatte layer is written in
the GPU buffer. The exact layout depends on the active cryptomatte layers. The
GPU buffer is downloaded and integrated into an accumulation buffer (stored in
CPU RAM).
The accumulation buffer stores the hashes + weights for a number of levels,
layers per pixel. When a hash already exists the weight will be increased. When
the hash doesn't exists it will be added to the buffer.
After all the samples have been calculated the accumulation buffer is processed.
During this phase the total pixel weights of each layer is mapped to be in a
range between 0 and 1. The hashes are also sorted (highest weight first).
Blender Kernel now has a `BKE_cryptomatte` header that access to common
functions for cryptomatte. This will in the future be used by the API.
* Alpha blended materials aren't supported. Alpha blended materials support in
render passes needs research how to implement it in a maintainable way for any
render pass.
This is a list of tasks that needs to be done for the same release that this
patch lands on (Blender 2.92)
* T82571 Add render tests.
* T82572 Documentation.
* T82573 Store hashes + Object names in the render result header.
* T82574 Use threading to increase performance in accumulation and post
processing.
* T82575 Merge the cycles and EEVEE settings as they are identical.
* T82576 Add RNA to extract the cryptomatte hashes to use in python scripts.
Reviewed By: Clément Foucault
Maniphest Tasks: T81058
Differential Revision: https://developer.blender.org/D9165
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_private.h')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_private.h | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 1385721a569..a6a480ca967 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -167,6 +167,8 @@ BLI_INLINE bool eevee_hdri_preview_overlay_enabled(const View3D *v3d) EEVEE_RENDER_PASS_ENVIRONMENT | EEVEE_RENDER_PASS_AOV) #define EEVEE_AOV_HASH_ALL -1 #define EEVEE_AOV_HASH_COLOR_TYPE_MASK 1 +#define MAX_CRYPTOMATTE_LAYERS 3 + /* Material shader variations */ enum { VAR_MAT_MESH = (1 << 0), @@ -295,6 +297,7 @@ typedef struct EEVEE_PassList { /* Renderpass Accumulation. */ struct DRWPass *material_accum_ps; struct DRWPass *background_accum_ps; + struct DRWPass *cryptomatte_ps; struct DRWPass *depth_ps; struct DRWPass *depth_cull_ps; @@ -327,6 +330,7 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP]; struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1]; struct GPUFrameBuffer *bloom_pass_accum_fb; + struct GPUFrameBuffer *cryptomatte_fb; struct GPUFrameBuffer *shadow_accum_fb; struct GPUFrameBuffer *ssr_accum_fb; struct GPUFrameBuffer *sss_blur_fb; @@ -383,6 +387,7 @@ typedef struct EEVEE_TextureList { struct GPUTexture *bloom_accum; struct GPUTexture *ssr_accum; struct GPUTexture *shadow_accum; + struct GPUTexture *cryptomatte; struct GPUTexture *refract_color; struct GPUTexture *taa_history; @@ -910,6 +915,11 @@ typedef struct EEVEE_WorldEngineData { DrawData dd; } EEVEE_WorldEngineData; +typedef struct EEVEE_CryptomatteSample { + float hash; + float weight; +} EEVEE_CryptomatteSample; + /* *********************************** */ typedef struct EEVEE_Data { @@ -967,6 +977,9 @@ typedef struct EEVEE_PrivateData { eViewLayerEEVEEPassType render_passes; int aov_hash; int num_aovs_used; + bool cryptomatte_accurate_mode; + EEVEE_CryptomatteSample *cryptomatte_accum_buffer; + float *cryptomatte_download_buffer; /* Uniform references that are referenced inside the `renderpass_pass`. They are updated * to reuse the drawing pass and the shading group. */ @@ -1120,6 +1133,7 @@ struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_layer_sh_get(void); struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void); struct GPUShader *EEVEE_shaders_effect_screen_raytrace_sh_get(EEVEE_SSRShaderOptions options); struct GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void); +struct GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair); struct GPUShader *EEVEE_shaders_shadow_sh_get(void); struct GPUShader *EEVEE_shaders_shadow_accum_sh_get(void); struct GPUShader *EEVEE_shaders_subsurface_first_pass_sh_get(void); @@ -1224,6 +1238,30 @@ void EEVEE_bloom_draw(EEVEE_Data *vedata); void EEVEE_bloom_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples); void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +/* eevee_cryptomatte.c */ +void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata); +void EEVEE_cryptomatte_output_init(EEVEE_ViewLayerData *sldata, + EEVEE_Data *vedata, + int tot_samples); +void EEVEE_cryptomatte_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_cryptomatte_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob); +void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata, + EEVEE_ViewLayerData *sldata, + Object *ob); +void EEVEE_cryptomatte_object_hair_cache_populate(EEVEE_Data *vedata, + EEVEE_ViewLayerData *sldata, + Object *ob); +void EEVEE_cryptomatte_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_cryptomatte_update_passes(struct RenderEngine *engine, + struct Scene *scene, + struct ViewLayer *view_layer); +void EEVEE_cryptomatte_render_result(struct RenderLayer *rl, + const char *viewname, + const rcti *rect, + EEVEE_Data *vedata, + EEVEE_ViewLayerData *sldata); +void EEVEE_cryptomatte_free(EEVEE_Data *vedata); + /* eevee_occlusion.c */ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, |