[Bf-blender-cvs] [e000dcb8490] master: Overlay: Wireframe: New method to avoid zfighting with geometry

Clément Foucault noreply at git.blender.org
Thu Mar 26 15:55:53 CET 2020


Commit: e000dcb8490880d6d49aa91588c457612685e9f1
Author: Clément Foucault
Date:   Thu Mar 26 15:36:15 2020 +0100
Branches: master
https://developer.blender.org/rBe000dcb8490880d6d49aa91588c457612685e9f1

Overlay: Wireframe: New method to avoid zfighting with geometry

This new method is only enabled if Overlay Smooth Wire is enabled.

This method gives really nice results but has some downside:
- Require a depth copy or loose the ability to write wire depth to the
  depth buffer and have correct depth ordering of wires. This patch use the former, with its associated cost.
- Require some depth sampling and prevent early depth test (i.e: has
  some performance impact).
- Has some relatively minor instability with geometry that are perpendicular
  to the view and intersecting with other geometry.

Pros:
- Compared to a fullpass approach this is surely going to have less
  performance impact and much higher quality.
- Removes the additional vertex offset. (see T74961)
- Fixes all half edges z-fighting.

{F8428014}

{F8428015}

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7233

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

M	source/blender/draw/engines/overlay/overlay_antialiasing.c
M	source/blender/draw/engines/overlay/overlay_engine.c
M	source/blender/draw/engines/overlay/overlay_private.h
M	source/blender/draw/engines/overlay/overlay_shader.c
M	source/blender/draw/engines/overlay/overlay_wireframe.c
M	source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl
M	source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl

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

diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c
index 0b7637aa098..e13d27032d5 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c
@@ -113,16 +113,6 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
                                     GPU_ATTACHMENT_TEXTURE(color_tex),
                                     GPU_ATTACHMENT_TEXTURE(line_tex),
                                 });
-
-  if (pd->xray_enabled) {
-    DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
-
-    GPU_framebuffer_ensure_config(&fbl->overlay_xray_depth_copy_fb,
-                                  {
-                                      GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx),
-                                      GPU_ATTACHMENT_NONE,
-                                  });
-  }
 }
 
 void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
@@ -168,6 +158,7 @@ void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
 {
   OVERLAY_FramebufferList *fbl = vedata->fbl;
   OVERLAY_TextureList *txl = vedata->txl;
+  OVERLAY_PassList *psl = vedata->psl;
   OVERLAY_PrivateData *pd = vedata->stl->pd;
   DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
 
@@ -191,6 +182,22 @@ void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
                                    GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
                                    GPU_ATTACHMENT_TEXTURE(txl->overlay_line_tx)});
   }
+
+  pd->antialiasing.do_depth_copy = !DRW_pass_is_empty(psl->wireframe_ps) ||
+                                   (pd->xray_enabled && pd->xray_opacity > 0.0f);
+  pd->antialiasing.do_depth_infront_copy = !DRW_pass_is_empty(psl->wireframe_xray_ps);
+
+  const bool do_wireframe = pd->antialiasing.do_depth_copy ||
+                            pd->antialiasing.do_depth_infront_copy;
+  if (pd->xray_enabled || do_wireframe) {
+    DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
+
+    GPU_framebuffer_ensure_config(&fbl->overlay_xray_depth_copy_fb,
+                                  {
+                                      GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx),
+                                      GPU_ATTACHMENT_NONE,
+                                  });
+  }
 }
 
 void OVERLAY_antialiasing_start(OVERLAY_Data *vedata)
@@ -217,18 +224,31 @@ void OVERLAY_xray_depth_copy(OVERLAY_Data *vedata)
   OVERLAY_FramebufferList *fbl = vedata->fbl;
   OVERLAY_PrivateData *pd = vedata->stl->pd;
 
+  if (DRW_state_is_fbo() && pd->antialiasing.do_depth_copy) {
+    /* We copy the depth of the rendered geometry to be able to compare to the overlays depth. */
+    GPU_framebuffer_blit(
+        fbl->overlay_default_fb, 0, fbl->overlay_xray_depth_copy_fb, 0, GPU_DEPTH_BIT);
+  }
+
   if (DRW_state_is_fbo() && pd->xray_enabled) {
-    if (pd->xray_opacity > 0.0f) {
-      /* We copy the depth of the rendered geometry to be able to compare to the overlays depth. */
-      GPU_framebuffer_blit(
-          fbl->overlay_default_fb, 0, fbl->overlay_xray_depth_copy_fb, 0, GPU_DEPTH_BIT);
-    }
     /* We then clear to not occlude the overlays directly. */
     GPU_framebuffer_bind(fbl->overlay_default_fb);
     GPU_framebuffer_clear_depth(fbl->overlay_default_fb, 1.0f);
   }
 }
 
+void OVERLAY_xray_depth_infront_copy(OVERLAY_Data *vedata)
+{
+  OVERLAY_FramebufferList *fbl = vedata->fbl;
+  OVERLAY_PrivateData *pd = vedata->stl->pd;
+
+  if (DRW_state_is_fbo() && pd->antialiasing.do_depth_infront_copy) {
+    /* We copy the depth of the rendered geometry to be able to compare to the overlays depth. */
+    GPU_framebuffer_blit(
+        fbl->overlay_in_front_fb, 0, fbl->overlay_xray_depth_copy_fb, 0, GPU_DEPTH_BIT);
+  }
+}
+
 void OVERLAY_xray_fade_draw(OVERLAY_Data *vedata)
 {
   OVERLAY_PassList *psl = vedata->psl;
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index adbcd3c7f28..97f6b91b7a9 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -466,6 +466,8 @@ static void OVERLAY_draw_scene(void *vedata)
   OVERLAY_xray_fade_draw(vedata);
   OVERLAY_grid_draw(vedata);
 
+  OVERLAY_xray_depth_infront_copy(vedata);
+
   if (DRW_state_is_fbo()) {
     GPU_framebuffer_bind(fbl->overlay_line_in_front_fb);
   }
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 7cc83c76857..bd9583c6a5f 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -293,6 +293,8 @@ typedef struct OVERLAY_PrivateData {
 
   struct {
     bool enabled;
+    bool do_depth_copy;
+    bool do_depth_infront_copy;
   } antialiasing;
   struct {
     bool show_handles;
@@ -411,6 +413,7 @@ void OVERLAY_antialiasing_start(OVERLAY_Data *vedata);
 void OVERLAY_antialiasing_end(OVERLAY_Data *vedata);
 void OVERLAY_xray_fade_draw(OVERLAY_Data *vedata);
 void OVERLAY_xray_depth_copy(OVERLAY_Data *vedata);
+void OVERLAY_xray_depth_infront_copy(OVERLAY_Data *vedata);
 
 bool OVERLAY_armature_is_pose_mode(Object *ob, const struct DRWContextState *draw_ctx);
 void OVERLAY_armature_cache_init(OVERLAY_Data *vedata);
@@ -613,7 +616,7 @@ GPUShader *OVERLAY_shader_particle_shape(void);
 GPUShader *OVERLAY_shader_pointcloud_dot(void);
 GPUShader *OVERLAY_shader_sculpt_mask(void);
 GPUShader *OVERLAY_shader_volume_velocity(bool use_needle);
-GPUShader *OVERLAY_shader_wireframe(void);
+GPUShader *OVERLAY_shader_wireframe(bool custom_bias);
 GPUShader *OVERLAY_shader_wireframe_select(void);
 GPUShader *OVERLAY_shader_xray_fade(void);
 
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index 0b2f98294ec..8b70a0982af 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -192,7 +192,7 @@ typedef struct OVERLAY_Shaders {
   GPUShader *volume_velocity_needle_sh;
   GPUShader *volume_velocity_sh;
   GPUShader *wireframe_select;
-  GPUShader *wireframe;
+  GPUShader *wireframe[2];
   GPUShader *xray_fade;
 } OVERLAY_Shaders;
 
@@ -1372,24 +1372,29 @@ GPUShader *OVERLAY_shader_wireframe_select(void)
   return sh_data->wireframe_select;
 }
 
-GPUShader *OVERLAY_shader_wireframe(void)
+GPUShader *OVERLAY_shader_wireframe(bool custom_bias)
 {
   const DRWContextState *draw_ctx = DRW_context_state_get();
   const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
   OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
-  if (!sh_data->wireframe) {
-    sh_data->wireframe = GPU_shader_create_from_arrays({
+  if (!sh_data->wireframe[custom_bias]) {
+    sh_data->wireframe[custom_bias] = GPU_shader_create_from_arrays({
         .vert = (const char *[]){sh_cfg->lib,
                                  datatoc_common_view_lib_glsl,
                                  datatoc_common_globals_lib_glsl,
                                  datatoc_gpu_shader_common_obinfos_lib_glsl,
                                  datatoc_wireframe_vert_glsl,
                                  NULL},
-        .frag = (const char *[]){datatoc_common_view_lib_glsl, datatoc_wireframe_frag_glsl, NULL},
-        .defs = (const char *[]){sh_cfg->def, NULL},
+        .frag = (const char *[]){datatoc_common_view_lib_glsl,
+                                 datatoc_common_globals_lib_glsl,
+                                 datatoc_wireframe_frag_glsl,
+                                 NULL},
+        .defs = (const char *[]){sh_cfg->def,
+                                 custom_bias ? "#define CUSTOM_DEPTH_BIAS\n" : NULL,
+                                 NULL},
     });
   }
-  return sh_data->wireframe;
+  return sh_data->wireframe[custom_bias];
 }
 
 GPUShader *OVERLAY_shader_xray_fade(void)
diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.c b/source/blender/draw/engines/overlay/overlay_wireframe.c
index 17b412b143c..27f3f4ae9af 100644
--- a/source/blender/draw/engines/overlay/overlay_wireframe.c
+++ b/source/blender/draw/engines/overlay/overlay_wireframe.c
@@ -51,6 +51,7 @@ void OVERLAY_wireframe_init(OVERLAY_Data *vedata)
 void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
 {
   OVERLAY_PassList *psl = vedata->psl;
+  OVERLAY_TextureList *txl = vedata->txl;
   OVERLAY_PrivateData *pd = vedata->stl->pd;
   const DRWContextState *draw_ctx = DRW_context_state_get();
   DRWShadingGroup *grp = NULL;
@@ -66,12 +67,14 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
 
   const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
   GPUShader *wires_sh = use_select ? OVERLAY_shader_wireframe_select() :
-                                     OVERLAY_shader_wireframe();
+                                     OVERLAY_shader_wireframe(pd->antialiasing.enabled);
 
   for (int xray = 0; xray < (is_material_shmode ? 1 : 2); xray++) {
     DRWState state = DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_WRITE_COLOR |
                      DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
     DRWPass *pass;
+    GPUTexture **depth_tx = (pd->xray_enabled || pd->xray_opacity > 0.0f) ? &txl->temp_depth_tx :
+                                                                            &txl->dummy_depth_tx;
 
     if (xray == 0) {
       DRW_PASS_CREATE(psl->wireframe_ps, state | pd->clipping_state);
@@ -85,6 +88,7 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
     for (int use_coloring = 0; use_coloring < 2; use_coloring++) {
       pd->wires_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
       DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
+      DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tx);
       DRW_shgroup_uniform_float_copy(grp, "wireStepParam", pd->shdata.wire_step_param);
       DRW_shgroup_uniform_bool_copy(grp, "useColoring", use_coloring);
       DRW_shgroup_uniform_bool_copy(grp, "is

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list