[Bf-blender-cvs] [55a58bc5d20] temp-eevee-next-cryptomatte: Cryptomatte sample sorting.

Jeroen Bakker noreply at git.blender.org
Wed Aug 24 15:42:58 CEST 2022


Commit: 55a58bc5d208c4f746289347cc6a2a9fc4f91aac
Author: Jeroen Bakker
Date:   Wed Aug 24 15:30:44 2022 +0200
Branches: temp-eevee-next-cryptomatte
https://developer.blender.org/rB55a58bc5d208c4f746289347cc6a2a9fc4f91aac

Cryptomatte sample sorting.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
M	source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
M	source/blender/draw/engines/eevee_next/eevee_film.hh
M	source/blender/draw/engines/eevee_next/eevee_instance.cc
M	source/blender/draw/engines/eevee_next/eevee_shader.cc
M	source/blender/draw/engines/eevee_next/eevee_shader.hh
A	source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_post_comp.glsl
A	source/blender/draw/engines/eevee_next/shaders/infos/eevee_cryptomatte_info.hh
M	source/blender/gpu/CMakeLists.txt

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index d527da0582e..3bf355b7e61 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -370,6 +370,7 @@ set(GLSL_SRC
   engines/eevee_next/shaders/eevee_camera_lib.glsl
   engines/eevee_next/shaders/eevee_colorspace_lib.glsl
   engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
+  engines/eevee_next/shaders/eevee_cryptomatte_post_comp.glsl
   engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
   engines/eevee_next/shaders/eevee_depth_of_field_bokeh_lut_comp.glsl
   engines/eevee_next/shaders/eevee_depth_of_field_downsample_comp.glsl
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
index 3975e0f11e8..9f368bf3270 100644
--- a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
@@ -11,20 +11,41 @@ namespace blender::eevee {
 void Cryptomatte::init()
 {
   eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
-  int layer_len = 0;
-  object_offset_ = (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) ? layer_len++ : -1;
-  asset_offset_ = (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET) ? layer_len++ : -1;
-  material_offset_ = (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL) ? layer_len++ : -1;
+  layer_len_ = 0;
+  object_offset_ = (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) ? layer_len_++ : -1;
+  asset_offset_ = (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET) ? layer_len_++ : -1;
+  material_offset_ = (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL) ? layer_len_++ : -1;
 
-  BLI_assert_msg(layer_len == inst_.film.cryptomatte_layer_len_get(),
+  BLI_assert_msg(layer_len_ == inst_.film.cryptomatte_layer_len_get(),
                  "Cryptomatte and film mismatch");
 }
 
 void Cryptomatte::begin_sync()
 {
+  post_ps_ = nullptr;
+
   if (object_offset_ == -1 && asset_offset_ == -1) {
     cryptomatte_object_buf.resize(16);
   }
+
+  if (layer_len_ == 0) {
+    return;
+  }
+
+  const bool do_sorting = inst_.is_viewport() == false;
+  if (!do_sorting) {
+    return;
+  }
+
+  post_ps_ = DRW_pass_create("Cryptomatte.Sort", DRW_STATE_NO_DRAW);
+  GPUShader *sh = inst_.shaders.static_shader_get(CRYPTOMATTE_POST);
+  DRWShadingGroup *grp = DRW_shgroup_create(sh, post_ps_);
+  Texture &cryptomatte_tx = inst_.film.cryptomatte_tx_get();
+  DRW_shgroup_uniform_image_ref(grp, "cryptomatte_img", &cryptomatte_tx);
+  DRW_shgroup_uniform_int_copy(grp, "cryptomatte_layer_len", layer_len_);
+  DRW_shgroup_uniform_int_copy(grp, "cryptomatte_levels", inst_.view_layer->cryptomatte_levels);
+  int3 dispatch_size = math::divide_ceil(cryptomatte_tx.size(), int3(FILM_GROUP_SIZE));
+  DRW_shgroup_call_compute(grp, UNPACK2(dispatch_size), 1);
 }
 
 void Cryptomatte::sync_object(Object *ob)
@@ -69,4 +90,12 @@ void Cryptomatte::bind_resources(DRWShadingGroup *grp)
   DRW_shgroup_storage_block_ref(grp, "cryptomatte_object_buf", &cryptomatte_object_buf);
 }
 
+void Cryptomatte::sort()
+{
+  if (post_ps_) {
+    printf("%s\n", __func__);
+    DRW_draw_pass(post_ps_);
+  }
+}
+
 }  // namespace blender::eevee
\ No newline at end of file
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
index 7fe257c0840..0ff9d602a9e 100644
--- a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
@@ -40,9 +40,12 @@ class Cryptomatte {
   int object_offset_;
   int asset_offset_;
   int material_offset_;
+  int layer_len_;
 
   CryptomatteObjectBuf cryptomatte_object_buf;
 
+  DRWPass *post_ps_ = nullptr;
+
  public:
   Cryptomatte(Instance &inst) : inst_(inst){};
   ~Cryptomatte(){};
@@ -53,6 +56,7 @@ class Cryptomatte {
   void end_sync();
 
   void bind_resources(DRWShadingGroup *grp);
+  void sort();
 
   float hash(const ID &id) const;
 };
diff --git a/source/blender/draw/engines/eevee_next/eevee_film.hh b/source/blender/draw/engines/eevee_next/eevee_film.hh
index ba8c505e9c9..add1f975fca 100644
--- a/source/blender/draw/engines/eevee_next/eevee_film.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_film.hh
@@ -97,6 +97,11 @@ class Film {
     return data_.background_opacity;
   }
 
+  Texture &cryptomatte_tx_get()
+  {
+    return cryptomatte_tx_;
+  }
+
   eViewLayerEEVEEPassType enabled_passes_get() const;
   int cryptomatte_layer_max_get() const;
   int cryptomatte_layer_len_get() const;
diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc
index 8a237ff6473..bb6ffb8fd9e 100644
--- a/source/blender/draw/engines/eevee_next/eevee_instance.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc
@@ -296,6 +296,8 @@ void Instance::render_frame(RenderLayer *render_layer, const char *view_name)
 #endif
   }
 
+  cryptomatte.sort();
+
   this->render_read_result(render_layer, view_name);
 }
 
diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.cc b/source/blender/draw/engines/eevee_next/eevee_shader.cc
index 0e49b195ea2..551d4cada8c 100644
--- a/source/blender/draw/engines/eevee_next/eevee_shader.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_shader.cc
@@ -82,6 +82,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
       return "eevee_film_frag";
     case FILM_COMP:
       return "eevee_film_comp";
+    case CRYPTOMATTE_POST:
+      return "eevee_cryptomatte_post";
     case HIZ_DEBUG:
       return "eevee_hiz_debug";
     case HIZ_UPDATE:
diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.hh b/source/blender/draw/engines/eevee_next/eevee_shader.hh
index 9ef42c84373..1bc8eeff9fe 100644
--- a/source/blender/draw/engines/eevee_next/eevee_shader.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_shader.hh
@@ -29,6 +29,8 @@ enum eShaderType {
   FILM_FRAG = 0,
   FILM_COMP,
 
+  CRYPTOMATTE_POST,
+
   DOF_BOKEH_LUT,
   DOF_DOWNSAMPLE,
   DOF_FILTER,
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_post_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_post_comp.glsl
new file mode 100644
index 00000000000..edcc069fc51
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_post_comp.glsl
@@ -0,0 +1,56 @@
+#define CRYPTOMATTE_LEVELS_MAX 16
+
+void cryptomatte_sort_layer(ivec2 texel, int layer)
+{
+  int pass_len = (cryptomatte_levels + 1) / 2;
+  int layer_id = layer * pass_len;
+
+  vec2 samples[CRYPTOMATTE_LEVELS_MAX];
+  /* Read all samples from the cryptomatte layer. */
+  for (int p = 0; p < pass_len; p++) {
+    vec4 pass_sample = imageLoad(cryptomatte_img, ivec3(texel, p + layer_id));
+    samples[p * 2] = pass_sample.xy;
+    samples[p * 2 + 1] = pass_sample.zw;
+  }
+  for (int i = pass_len * 2; i < CRYPTOMATTE_LEVELS_MAX; i++) {
+    samples[i] = vec2(0.0);
+  }
+
+  /* Sort samples. Lame implementation, can be replaced with a more efficient algorithm. */
+  bool samples_changed = false;
+  for (int i = 0; i < cryptomatte_levels - 1 && samples[i].y != 0.0; i++) {
+    int highest_index = i;
+    float highest_weight = samples[i].y;
+    for (int j = i + 1; j < cryptomatte_levels && samples[j].y != 0.0; j++) {
+      if (samples[j].y > highest_weight) {
+        highest_index = j;
+        highest_weight = samples[j].y;
+      }
+    };
+
+    if (highest_index != i) {
+      vec2 tmp = samples[i];
+      samples[i] = samples[highest_index];
+      samples[highest_index] = tmp;
+      samples_changed = true;
+    }
+  }
+
+  /* Store samples back to the cryptomatte layer. */
+  if (samples_changed) {
+    for (int p = 0; p < pass_len; p++) {
+      vec4 pass_sample;
+      pass_sample.xy = samples[p * 2];
+      pass_sample.zw = samples[p * 2 + 1];
+      imageStore(cryptomatte_img, ivec3(texel, p + layer_id), pass_sample);
+    }
+  }
+}
+
+void main()
+{
+  ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+  for (int layer = 0; layer < cryptomatte_layer_len; layer++) {
+    cryptomatte_sort_layer(texel, layer);
+  }
+}
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_cryptomatte_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_cryptomatte_info.hh
new file mode 100644
index 00000000000..5709a18b8b7
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_cryptomatte_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "eevee_defines.hh"
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(eevee_cryptomatte_post)
+    .do_static_compilation(true)
+    .image(0, GPU_RGBA32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "cryptomatte_img")
+    .push_constant(Type::INT, "cryptomatte_layer_len")
+    .push_constant(Type::INT, "cryptomatte_levels")
+    .local_group_size(FILM_GROUP_SIZE, FILM_GROUP_SIZE)
+    .compute_source("eevee_cryptomatte_post_comp.glsl");
\ No newline at end of file
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 9469db1d842..5f25bb5552f 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -490,6 +490,7 @@ list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR})
 
 set(SRC_SHADER_CREATE_INFOS
   ../draw/engines/basic/shaders/infos/basic_depth_info.hh
+  ../draw/engines/eevee_next/shaders/infos/eevee_cryptomatte_info.hh
   ../draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh
   ../draw/engines/eevee_next/shaders/infos/eevee_film_info.hh
   ../draw/engines/eevee_next/shaders/infos/eevee_hiz_info.hh



More information about the Bf-blender-cvs mailing list