[Bf-blender-cvs] [2c7cd5e0249] temp-eevee-next-cryptomatte: Add support of sample filtering. Keep track of 4 most weighted hashes.

Jeroen Bakker noreply at git.blender.org
Mon Sep 12 08:40:07 CEST 2022


Commit: 2c7cd5e02493d052ba4314d6932ef6b92ba40d96
Author: Jeroen Bakker
Date:   Fri Sep 2 10:51:05 2022 +0200
Branches: temp-eevee-next-cryptomatte
https://developer.blender.org/rB2c7cd5e02493d052ba4314d6932ef6b92ba40d96

Add support of sample filtering. Keep track of 4 most weighted hashes.

===================================================================

M	source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
M	source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl

===================================================================

diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
index be6e967a31d..953fd2e7320 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
@@ -1,19 +1,19 @@
 /** Storing/merging and sorting cryptomatte samples. */
 
-bool cryptomatte_can_merge_sample(vec2 cryptomatte_sample, float hash)
+bool cryptomatte_can_merge_sample(vec2 dst, vec2 src)
 {
-  if (cryptomatte_sample == vec2(0.0, 0.0)) {
+  if (dst == vec2(0.0, 0.0)) {
     return true;
   }
-  if (cryptomatte_sample.x == hash) {
+  if (dst.x == src.x) {
     return true;
   }
   return false;
 }
 
-vec2 cryptomatte_merge_sample(vec2 cryptomatte_sample, float hash, float weight)
+vec2 cryptomatte_merge_sample(vec2 dst, vec2 src)
 {
-  return vec2(hash, cryptomatte_sample.y + weight);
+  return vec2(src.x, dst.y + src.y);
 }
 
 vec4 cryptomatte_false_color(float hash)
@@ -25,34 +25,36 @@ vec4 cryptomatte_false_color(float hash)
               1.0);
 }
 
+void cryptomatte_clear_samples(FilmSample dst)
+{
+  int layer_len = imageSize(cryptomatte_img).z;
+  for (int i = 0; i < layer_len; i++) {
+    imageStore(cryptomatte_img, ivec3(dst.texel, i), vec4(0.0));
+  }
+}
+
 void cryptomatte_store_film_sample(FilmSample dst,
                                    int cryptomatte_layer_id,
-                                   float hash,
+                                   vec2 crypto_sample,
                                    out vec4 out_color)
 {
-  float weight = dst.weight;
-
-  if (!film_buf.use_history || film_buf.use_reprojection) {
-    for (int i = 0; i < film_buf.cryptomatte_samples_len / 2; i++) {
-      ivec3 img_co = ivec3(dst.texel, cryptomatte_layer_id + i);
-      imageStore(cryptomatte_img, img_co, vec4(0.0));
-    }
+  if (crypto_sample.y == 0.0) {
+    return;
   }
-
   for (int i = 0; i < film_buf.cryptomatte_samples_len / 2; i++) {
     ivec3 img_co = ivec3(dst.texel, cryptomatte_layer_id + i);
     vec4 sample_pair = imageLoad(cryptomatte_img, img_co);
-    if (cryptomatte_can_merge_sample(sample_pair.xy, hash)) {
-      sample_pair.xy = cryptomatte_merge_sample(sample_pair.xy, hash, weight);
+    if (cryptomatte_can_merge_sample(sample_pair.xy, crypto_sample)) {
+      sample_pair.xy = cryptomatte_merge_sample(sample_pair.xy, crypto_sample);
       /* In viewport only one layer is active. */
       /* TODO(jbakker):  we are displaying the first sample, but we should display the highest
        * weighted one. */
       if (cryptomatte_layer_id + i == 0) {
-        out_color = cryptomatte_false_color(sample_pair.x);
+        out_color = cryptomatte_false_color(crypto_sample.x);
       }
     }
-    else if (cryptomatte_can_merge_sample(sample_pair.zw, hash)) {
-      sample_pair.zw = cryptomatte_merge_sample(sample_pair.zw, hash, weight);
+    else if (cryptomatte_can_merge_sample(sample_pair.zw, crypto_sample)) {
+      sample_pair.zw = cryptomatte_merge_sample(sample_pair.zw, crypto_sample);
     }
     else if (i == film_buf.cryptomatte_samples_len / 2 - 1) {
       /* TODO(jbakker): New hash detected, but there is no space left to store it. Currently we
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
index 92a873f3af9..a20b08615a1 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
@@ -159,6 +159,45 @@ void film_sample_accum_combined(FilmSample samp, inout vec4 accum, inout float w
   weight_accum += weight;
 }
 
+void film_sample_cryptomatte_accum(FilmSample samp,
+                                   int layer,
+                                   sampler2D tex,
+                                   inout vec2 crypto_samples[4])
+{
+  float hash = texelFetch(tex, samp.texel, 0)[layer];
+  /* Find existing entry. */
+  for (int i = 0; i < 4; i++) {
+    if (crypto_samples[i].x == hash) {
+      crypto_samples[i].y += samp.weight;
+      return;
+    }
+  }
+  /* Overwrite entry with less weight. */
+  for (int i = 0; i < 4; i++) {
+    if (crypto_samples[i].y < samp.weight) {
+      crypto_samples[i] = vec2(hash, samp.weight);
+      return;
+    }
+  }
+}
+
+void film_cryptomatte_layer_accum_and_store(
+    FilmSample dst, ivec2 texel_film, int pass_id, int layer_component, inout vec4 out_color)
+{
+  if (pass_id == -1) {
+    return;
+  }
+  /* x = hash, y = accumed weight. Only keep track of 4 highest weighted samples. */
+  vec2 crypto_samples[4] = {vec2(0.0), vec2(0.0), vec2(0.0), vec2(0.0)};
+  for (int i = 0; i < film_buf.samples_len; i++) {
+    FilmSample src = film_sample_get(i, texel_film);
+    film_sample_cryptomatte_accum(src, layer_component, cryptomatte_tx, crypto_samples);
+  }
+  for (int i = 0; i < 4; i++) {
+    cryptomatte_store_film_sample(dst, pass_id, crypto_samples[i], out_color);
+  }
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -704,15 +743,16 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
   }
 
   if (film_buf.cryptomatte_samples_len != 0) {
-    vec4 hashes = texelFetch(cryptomatte_tx, dst.texel, 0);
-    if (film_buf.cryptomatte_object_id != -1) {
-      cryptomatte_store_film_sample(dst, film_buf.cryptomatte_object_id, hashes.x, out_color);
-    }
-    if (film_buf.cryptomatte_asset_id != -1) {
-      cryptomatte_store_film_sample(dst, film_buf.cryptomatte_asset_id, hashes.y, out_color);
-    }
-    if (film_buf.cryptomatte_material_id != -1) {
-      cryptomatte_store_film_sample(dst, film_buf.cryptomatte_material_id, hashes.z, out_color);
+    /* Cryptomatte passess cannot be cleared by a weighted store like other passes. */
+    if (!film_buf.use_history || film_buf.use_reprojection) {
+      cryptomatte_clear_samples(dst);
     }
+
+    film_cryptomatte_layer_accum_and_store(
+        dst, texel_film, film_buf.cryptomatte_object_id, 0, out_color);
+    film_cryptomatte_layer_accum_and_store(
+        dst, texel_film, film_buf.cryptomatte_asset_id, 1, out_color);
+    film_cryptomatte_layer_accum_and_store(
+        dst, texel_film, film_buf.cryptomatte_material_id, 2, out_color);
   }
 }



More information about the Bf-blender-cvs mailing list