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 <jeroen@blender.org>2020-12-14 16:55:53 +0300
committerJeroen Bakker <jeroen@blender.org>2020-12-14 17:03:29 +0300
commit6714b800d1716f7c7dec9a640d1c615bbf1a938f (patch)
tree22a9c13951a167f8044fcec3d108831d2ea5ae2f /source/blender/draw/engines/eevee/eevee_cryptomatte.c
parente3068f38c8c8df8cf198dc694aae9cc0c6e88633 (diff)
Cryptomatte: apply volume transmittance to Eevee.
This patch will add volumetric transmittance to the cryptomatte coverage data of all samples when post processing the cryptomatte passes. It was discussed with Cycles that this is desired, but tricky to implement in Cycles.
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_cryptomatte.c')
-rw-r--r--source/blender/draw/engines/eevee/eevee_cryptomatte.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
index 95f5aa8b628..9150de7184a 100644
--- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c
+++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
@@ -125,7 +125,7 @@ void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata)
return;
}
if (eevee_cryptomatte_active_layers(view_layer) != 0) {
- g_data->render_passes |= EEVEE_RENDER_PASS_CRYPTOMATTE;
+ 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;
}
@@ -137,7 +137,8 @@ void EEVEE_cryptomatte_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
- EEVEE_PrivateData *g_data = vedata->stl->g_data;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -469,6 +470,8 @@ static void eevee_cryptomatte_postprocess_weights(EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PrivateData *g_data = stl->g_data;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ EEVEE_TextureList *txl = vedata->txl;
const DRWContextState *draw_ctx = DRW_context_state_get();
const ViewLayer *view_layer = draw_ctx->view_layer;
const int num_cryptomatte_layers = eevee_cryptomatte_layers_count(view_layer);
@@ -478,11 +481,25 @@ static void eevee_cryptomatte_postprocess_weights(EEVEE_Data *vedata)
EEVEE_CryptomatteSample *accum_buffer = g_data->cryptomatte_accum_buffer;
BLI_assert(accum_buffer);
+ float *volumetric_transmittance_buffer = NULL;
+ if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
+ volumetric_transmittance_buffer = GPU_texture_read(
+ txl->volume_transmittance_accum, GPU_DATA_FLOAT, 0);
+ }
+ const int num_samples = effects->taa_current_sample;
+
int accum_pixel_index = 0;
int accum_pixel_stride = eevee_cryptomatte_pixel_stride(view_layer);
for (int pixel_index = 0; pixel_index < buffer_size;
pixel_index++, accum_pixel_index += accum_pixel_stride) {
+ float coverage = 1.0f;
+ if (volumetric_transmittance_buffer != NULL) {
+ coverage = (volumetric_transmittance_buffer[pixel_index * 4] +
+ volumetric_transmittance_buffer[pixel_index * 4 + 1] +
+ volumetric_transmittance_buffer[pixel_index * 4 + 2]) /
+ (3.0f * num_samples);
+ }
for (int layer = 0; layer < num_cryptomatte_layers; layer++) {
const int layer_offset = eevee_cryptomatte_layer_offset(view_layer, layer);
/* Calculate the total weight of the sample. */
@@ -493,24 +510,40 @@ static void eevee_cryptomatte_postprocess_weights(EEVEE_Data *vedata)
}
BLI_assert(total_weight > 0.0f);
- float total_weight_inv = 1.0f / total_weight;
- for (int level = 0; level < num_levels; level++) {
- EEVEE_CryptomatteSample *sample = &accum_buffer[accum_pixel_index + layer_offset + level];
- /* Remove background samples. These samples were used to determine the correct weight
- * but won't be part of the final result. */
- if (sample->hash == 0.0f) {
+ float total_weight_inv = coverage / total_weight;
+ if (total_weight_inv > 0.0f) {
+ for (int level = 0; level < num_levels; level++) {
+ EEVEE_CryptomatteSample *sample =
+ &accum_buffer[accum_pixel_index + layer_offset + level];
+ /* Remove background samples. These samples were used to determine the correct weight
+ * but won't be part of the final result. */
+ if (sample->hash == 0.0f) {
+ sample->weight = 0.0f;
+ }
+ sample->weight *= total_weight_inv;
+ }
+
+ /* Sort accum buffer by coverage of each sample. */
+ qsort(&accum_buffer[accum_pixel_index + layer_offset],
+ num_levels,
+ sizeof(EEVEE_CryptomatteSample),
+ eevee_cryptomatte_sample_cmp_reverse);
+ }
+ else {
+ /* This pixel doesn't have any weight, so clear it fully. */
+ for (int level = 0; level < num_levels; level++) {
+ EEVEE_CryptomatteSample *sample =
+ &accum_buffer[accum_pixel_index + layer_offset + level];
sample->weight = 0.0f;
+ sample->hash = 0.0f;
}
- sample->weight *= total_weight_inv;
}
-
- /* Sort accum buffer by coverage of each sample. */
- qsort(&accum_buffer[accum_pixel_index + layer_offset],
- num_levels,
- sizeof(EEVEE_CryptomatteSample),
- eevee_cryptomatte_sample_cmp_reverse);
}
}
+
+ if (volumetric_transmittance_buffer) {
+ MEM_freeN(volumetric_transmittance_buffer);
+ }
}
/* Extract cryptomatte layer from the cryptomatte_accum_buffer to render passes. */