[Bf-blender-cvs] [cfa235b89d6] blender-v3.1-release: Image Editor: Fix background drawing of empty tiles.

Jeroen Bakker noreply at git.blender.org
Mon Jan 31 10:01:13 CET 2022


Commit: cfa235b89d686e00456e6d7af99442e5a73ffed8
Author: Jeroen Bakker
Date:   Mon Jan 31 09:57:51 2022 +0100
Branches: blender-v3.1-release
https://developer.blender.org/rBcfa235b89d686e00456e6d7af99442e5a73ffed8

Image Editor: Fix background drawing of empty tiles.

Empty (UDIM) tiles where drawn with a transparency checkerboard. They
should be rendered with a border background. The cause is that the image
engine would select a single area that contained all tiles and draw them
as being part of an image.

The fix is to separate the color and depth part of the image engine
shader and only draw the depths of tiles that are enabled.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/image/image_drawing_mode.hh
M	source/blender/draw/engines/image/image_engine.cc
M	source/blender/draw/engines/image/image_instance_data.hh
M	source/blender/draw/engines/image/image_private.hh
M	source/blender/draw/engines/image/image_shader.cc
A	source/blender/draw/engines/image/shaders/image_engine_color_frag.glsl
R093	source/blender/draw/engines/image/shaders/image_engine_vert.glsl	source/blender/draw/engines/image/shaders/image_engine_color_vert.glsl
A	source/blender/draw/engines/image/shaders/image_engine_depth_frag.glsl
A	source/blender/draw/engines/image/shaders/image_engine_depth_vert.glsl
D	source/blender/draw/engines/image/shaders/image_engine_frag.glsl
M	source/blender/draw/engines/image/shaders/infos/engine_image_info.hh
M	source/blender/draw/tests/shaders_test.cc

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index f4e57d9521b..3c25252efe8 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -518,8 +518,10 @@ set(GLSL_SRC
   engines/overlay/shaders/wireframe_frag.glsl
   engines/overlay/shaders/xray_fade_frag.glsl
 
-  engines/image/shaders/image_engine_frag.glsl
-  engines/image/shaders/image_engine_vert.glsl
+  engines/image/shaders/image_engine_color_frag.glsl
+  engines/image/shaders/image_engine_color_vert.glsl
+  engines/image/shaders/image_engine_depth_frag.glsl
+  engines/image/shaders/image_engine_depth_vert.glsl
 )
 
 set(GLSL_C)
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index f501bc78b11..d5a4a317a22 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -26,6 +26,8 @@
 
 #include "IMB_imbuf_types.h"
 
+#include "BLI_math_vec_types.hh"
+
 #include "image_batches.hh"
 #include "image_private.hh"
 #include "image_wrappers.hh"
@@ -80,13 +82,19 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
  private:
   DRWPass *create_image_pass() const
   {
-    /* Write depth is needed for background overlay rendering. Near depth is used for
-     * transparency checker and Far depth is used for indicating the image size. */
-    DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
-                                           DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL);
+    DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS |
+                                           DRW_STATE_BLEND_ALPHA_PREMUL);
     return DRW_pass_create("Image", state);
   }
 
+  DRWPass *create_depth_pass() const
+  {
+    /* Depth is needed for background overlay rendering. Near depth is used for
+     * transparency checker and Far depth is used for indicating the image size. */
+    DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
+    return DRW_pass_create("Depth", state);
+  }
+
   void add_shgroups(const IMAGE_InstanceData *instance_data) const
   {
     const ShaderParameters &sh_params = instance_data->sh_params;
@@ -97,7 +105,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
     DRW_shgroup_uniform_vec4_copy(shgrp, "shuffle", sh_params.shuffle);
     DRW_shgroup_uniform_int_copy(shgrp, "drawFlags", sh_params.flags);
     DRW_shgroup_uniform_bool_copy(shgrp, "imgPremultiplied", sh_params.use_premul_alpha);
-    DRW_shgroup_uniform_vec2_copy(shgrp, "maxUv", instance_data->max_uv);
     float image_mat[4][4];
     unit_m4(image_mat);
     for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
@@ -112,6 +119,37 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
     }
   }
 
+  /**
+   * \brief add depth drawing calls.
+   *
+   * The depth is used to identify if the tile exist or transparent.
+   */
+  void add_depth_shgroups(IMAGE_InstanceData &instance_data,
+                          Image *image,
+                          ImageUser *UNUSED(image_user)) const
+  {
+    GPUShader *shader = IMAGE_shader_depth_get();
+    DRWShadingGroup *shgrp = DRW_shgroup_create(shader, instance_data.passes.depth_pass);
+    float image_mat[4][4];
+    unit_m4(image_mat);
+    for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
+      const TextureInfo &info = instance_data.texture_infos[i];
+      if (!info.visible) {
+        continue;
+      }
+
+      LISTBASE_FOREACH (ImageTile *, image_tile_ptr, &image->tiles) {
+        DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp);
+        const ImageTileWrapper image_tile(image_tile_ptr);
+        const int tile_x = image_tile.get_tile_x_offset();
+        const int tile_y = image_tile.get_tile_y_offset();
+        float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1);
+        DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv);
+        DRW_shgroup_call_obmat(shsub, info.batch, image_mat);
+      }
+    }
+  }
+
   /**
    * \brief Update GPUTextures for drawing the image.
    *
@@ -367,6 +405,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
   {
     IMAGE_InstanceData *instance_data = vedata->instance_data;
     instance_data->passes.image_pass = create_image_pass();
+    instance_data->passes.depth_pass = create_depth_pass();
   }
 
   void cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser) const override
@@ -376,7 +415,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
     TextureMethod method(instance_data);
 
     instance_data->partial_update.ensure_image(image);
-    instance_data->max_uv_update();
     instance_data->clear_dirty_flag();
 
     // Step: Find out which screen space textures are needed to draw on the screen. Remove the
@@ -391,6 +429,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
 
     // Step: Add the GPU textures to the shgroup.
     instance_data->update_batches();
+    add_depth_shgroups(*instance_data, image, iuser);
     add_shgroups(instance_data);
   }
 
@@ -408,6 +447,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
     GPU_framebuffer_clear_color_depth(dfbl->default_fb, clear_col, 1.0);
 
     DRW_view_set_active(instance_data->view);
+    DRW_draw_pass(instance_data->passes.depth_pass);
     DRW_draw_pass(instance_data->passes.image_pass);
     DRW_view_set_active(nullptr);
   }
diff --git a/source/blender/draw/engines/image/image_engine.cc b/source/blender/draw/engines/image/image_engine.cc
index 840d4840f1b..201733f41a7 100644
--- a/source/blender/draw/engines/image/image_engine.cc
+++ b/source/blender/draw/engines/image/image_engine.cc
@@ -145,7 +145,6 @@ class ImageEngine {
 
 static void IMAGE_engine_init(void *ved)
 {
-  IMAGE_shader_library_ensure();
   IMAGE_Data *vedata = (IMAGE_Data *)ved;
   if (vedata->instance_data == nullptr) {
     vedata->instance_data = MEM_new<IMAGE_InstanceData>(__func__);
diff --git a/source/blender/draw/engines/image/image_instance_data.hh b/source/blender/draw/engines/image/image_instance_data.hh
index 7fb0a6ca3eb..1a7a20b8b9a 100644
--- a/source/blender/draw/engines/image/image_instance_data.hh
+++ b/source/blender/draw/engines/image/image_instance_data.hh
@@ -57,29 +57,14 @@ struct IMAGE_InstanceData {
 
   struct {
     DRWPass *image_pass;
+    DRWPass *depth_pass;
   } passes;
 
   /** \brief Transform matrix to convert a normalized screen space coordinates to texture space. */
   float ss_to_texture[4][4];
   TextureInfo texture_infos[SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN];
 
-  /**
-   * \brief Maximum uv's that are on the border of the image.
-   *
-   * Larger UV coordinates would be drawn as a border. */
-  float max_uv[2];
-
  public:
-  void max_uv_update()
-  {
-    copy_v2_fl2(max_uv, 1.0f, 1.0);
-    LISTBASE_FOREACH (ImageTile *, image_tile_ptr, &image->tiles) {
-      ImageTileWrapper image_tile(image_tile_ptr);
-      max_uv[0] = max_ii(max_uv[0], image_tile.get_tile_x_offset() + 1);
-      max_uv[1] = max_ii(max_uv[1], image_tile.get_tile_y_offset() + 1);
-    }
-  }
-
   void clear_dirty_flag()
   {
     reset_dirty_flag(false);
diff --git a/source/blender/draw/engines/image/image_private.hh b/source/blender/draw/engines/image/image_private.hh
index 6d665db4c41..d8f8adb7e84 100644
--- a/source/blender/draw/engines/image/image_private.hh
+++ b/source/blender/draw/engines/image/image_private.hh
@@ -72,7 +72,7 @@ class AbstractDrawingMode {
 
 /* image_shader.c */
 GPUShader *IMAGE_shader_image_get();
-void IMAGE_shader_library_ensure();
+GPUShader *IMAGE_shader_depth_get();
 void IMAGE_shader_free();
 
 }  // namespace blender::draw::image_engine
diff --git a/source/blender/draw/engines/image/image_shader.cc b/source/blender/draw/engines/image/image_shader.cc
index e3cb60c5511..952843d7dd7 100644
--- a/source/blender/draw/engines/image/image_shader.cc
+++ b/source/blender/draw/engines/image/image_shader.cc
@@ -29,44 +29,33 @@
 #include "image_engine.h"
 #include "image_private.hh"
 
-extern "C" {
-extern char datatoc_common_colormanagement_lib_glsl[];
-extern char datatoc_common_globals_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-
-extern char datatoc_engine_image_frag_glsl[];
-extern char datatoc_engine_image_vert_glsl[];
-}
-
 namespace blender::draw::image_engine {
 
 struct IMAGE_Shaders {
   GPUShader *image_sh;
+  GPUShader *depth_sh;
 };
 
 static struct {
   IMAGE_Shaders shaders;
-  DRWShaderLibrary *lib;
 } e_data = {{nullptr}}; /* Engine data */
 
-void IMAGE_shader_library_ensure()
+GPUShader *IMAGE_shader_image_get()
 {
-  if (e_data.lib == nullptr) {
-    e_data.lib = DRW_shader_library_create();
-    /* NOTE: These need to be ordered by dependencies. */
-    DRW_SHADER_LIB_ADD(e_data.lib, common_colormanagement_lib);
-    DRW_SHADER_LIB_ADD(e_data.lib, common_globals_lib);
-    DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
+  IMAGE_Shaders *sh_data = &e_data.shaders;
+  if (sh_data->image_sh == nullptr) {
+    sh_data->image_sh = GPU_shader_create_from_info_name("image_engine_color_shader");
   }
+  return sh_data->image_sh;
 }
 
-GPUShader *IMAGE_shader_image_get()
+GPUShader *IMAGE_shader_depth_get()
 {
   IMAGE_Shaders *sh_data = &e_data.shaders;
-  if (sh_data->image_sh == nullptr) {
-    sh_data->image_sh = GPU_shader_create_from_info_name("image_engine_shader");
+  if (sh_data->depth_sh == nullptr) {
+    sh_data->depth_sh = GPU_shader_create_from_info_name("image_engine_depth_shader");
   }
-  return sh_data->image_sh;
+  return sh_data->depth_sh;
 }
 
 void IMAGE_shader_free()
@@ -75,8 +64,6 @@ void IMAGE_shader_free()
   for (int i = 0; i < (sizeof(IMAGE_Shaders) / sizeof(GPUShader *)); i++) {
     DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
   }
-
-  DRW_SHADER_LIB_FREE_SAFE(e_data.lib);
 }
 
 }  // namespace blender::draw::image_engine
diff --git a/source/blender/draw/engines/image/shaders/imag

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list