[Bf-blender-cvs] [2cef0182fb7] greasepencil-refactor: GPencil: Refactor: Add depth merge pass

Clément Foucault noreply at git.blender.org
Sat Dec 14 03:31:20 CET 2019


Commit: 2cef0182fb76b6e5f594f9253d076b4cfbc1e6a7
Author: Clément Foucault
Date:   Sat Dec 14 02:44:53 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB2cef0182fb76b6e5f594f9253d076b4cfbc1e6a7

GPencil: Refactor: Add depth merge pass

This pass merge the stroke depth to the 3D depth buffer. This makes GP objs
to mask overlays correctly.

2D objects depth is using the object center depth only. This is to be
improved.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/gpencil_shader.c
A	source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 1783d26b9e2..52476f9a6e2 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -280,6 +280,7 @@ data_to_c_simple(engines/gpencil/shaders/gpencil_vert.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_common_lib.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_composite_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_layer_blend_frag.glsl SRC)
+data_to_c_simple(engines/gpencil/shaders/gpencil_depth_merge_frag.glsl SRC)
 
 data_to_c_simple(engines/gpencil/shaders/gpencil_fill_vert.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_fill_frag.glsl SRC)
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index c5278e54ee9..47755bcc43a 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -314,6 +314,7 @@ static void GPENCIL_engine_init_new(void *ved)
   float viewmatinv[4][4];
   DRW_view_viewmat_get(NULL, viewmatinv, true);
   copy_v3_v3(stl->pd->camera_z_axis, viewmatinv[2]);
+  stl->pd->camera_z_offset = dot_v3v3(viewmatinv[3], viewmatinv[2]);
 }
 
 void GPENCIL_engine_init(void *vedata)
@@ -355,6 +356,7 @@ static void GPENCIL_engine_free(void)
   DRW_SHADER_FREE_SAFE(e_data.gpencil_sh);
   DRW_SHADER_FREE_SAFE(e_data.composite_sh);
   DRW_SHADER_FREE_SAFE(e_data.layer_blend_sh);
+  DRW_SHADER_FREE_SAFE(e_data.depth_merge_sh);
 
   DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture);
 
@@ -413,7 +415,6 @@ static void GPENCIL_cache_init_new(void *ved)
 
   {
     DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
-
     DRW_PASS_CREATE(psl->composite_ps, state);
 
     GPUShader *sh = GPENCIL_shader_composite_get(&e_data);
@@ -422,6 +423,17 @@ static void GPENCIL_cache_init_new(void *ved)
     DRW_shgroup_uniform_texture_ref(grp, "revealBuf", &pd->reveal_tx);
     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
   }
+  {
+    DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+    DRW_PASS_CREATE(psl->merge_depth_ps, state);
+
+    GPUShader *sh = GPENCIL_shader_depth_merge_get(&e_data);
+    grp = DRW_shgroup_create(sh, psl->merge_depth_ps);
+    DRW_shgroup_uniform_texture_ref(grp, "depthBuf", &pd->depth_tx);
+    DRW_shgroup_uniform_float(grp, "strokeDepth2d", &pd->object_depth, 1);
+    DRW_shgroup_uniform_bool(grp, "strokeOrder3d", &pd->is_stroke_order_3d, 1);
+    DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+  }
 }
 
 void GPENCIL_cache_init(void *vedata)
@@ -1290,6 +1302,7 @@ static void GPENCIL_draw_scene_new(void *ved)
   for (GPENCIL_tObject *ob = pd->tobjects.first; ob; ob = ob->next) {
     DRW_stats_group_start("GPencil Object");
 
+    GPU_framebuffer_bind(fbl->gpencil_fb);
     GPU_framebuffer_clear_depth(fbl->gpencil_fb, ob->is_drawmode3d ? 1.0f : 0.0f);
 
     if (ob->vfx.first) {
@@ -1315,6 +1328,12 @@ static void GPENCIL_draw_scene_new(void *ved)
       /* TODO vfx */
     }
 
+    pd->object_depth = ob->camera_z - pd->camera_z_offset;
+    pd->is_stroke_order_3d = ob->is_drawmode3d;
+
+    GPU_framebuffer_bind(dfbl->depth_only_fb);
+    DRW_draw_pass(psl->merge_depth_ps);
+
     DRW_stats_group_end();
   }
 
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 8f8eb9289c4..ae074021138 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -313,6 +313,8 @@ typedef struct GPENCIL_PassList {
 
   /* Composite the main GPencil buffer onto the rendered image. */
   struct DRWPass *composite_ps;
+  /* Composite the object depth to the default depth buffer to occlude overlays. */
+  struct DRWPass *merge_depth_ps;
 } GPENCIL_PassList;
 
 typedef struct GPENCIL_FramebufferList {
@@ -422,8 +424,11 @@ typedef struct GPENCIL_PrivateData {
   GPUTexture *scene_depth_tx;
   /* Current frame */
   int cfra;
+  /* Used by the depth merge step. */
+  float object_depth;
+  int is_stroke_order_3d;
   /* Used for computing object distance to camera. */
-  float camera_z_axis[3];
+  float camera_z_axis[3], camera_z_offset;
 } GPENCIL_PrivateData;
 
 /* flags for fast drawing support */
@@ -445,6 +450,8 @@ typedef struct GPENCIL_e_data {
   struct GPUShader *composite_sh;
   /* All layer blend types in one shader! */
   struct GPUShader *layer_blend_sh;
+  /* Merge the final object depth to the depth buffer. */
+  struct GPUShader *depth_merge_sh;
 
   /* general drawing shaders */
   struct GPUShader *gpencil_fill_sh;
@@ -678,6 +685,7 @@ void gpencil_fx_draw(struct GPENCIL_e_data *e_data,
 struct GPUShader *GPENCIL_shader_geometry_get(GPENCIL_e_data *e_data);
 struct GPUShader *GPENCIL_shader_composite_get(GPENCIL_e_data *e_data);
 struct GPUShader *GPENCIL_shader_layer_blend_get(GPENCIL_e_data *e_data);
+struct GPUShader *GPENCIL_shader_depth_merge_get(GPENCIL_e_data *e_data);
 
 /* main functions */
 void GPENCIL_engine_init(void *vedata);
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader.c b/source/blender/draw/engines/gpencil/gpencil_shader.c
index 036a2a9f432..52cd91fdbc0 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader.c
@@ -28,8 +28,10 @@ extern char datatoc_gpencil_frag_glsl[];
 extern char datatoc_gpencil_vert_glsl[];
 extern char datatoc_gpencil_composite_frag_glsl[];
 extern char datatoc_gpencil_layer_blend_frag_glsl[];
+extern char datatoc_gpencil_depth_merge_frag_glsl[];
 
 extern char datatoc_common_colormanagement_lib_glsl[];
+extern char datatoc_common_fullscreen_vert_glsl[];
 extern char datatoc_common_view_lib_glsl[];
 
 struct GPUShader *GPENCIL_shader_geometry_get(GPENCIL_e_data *e_data)
@@ -76,3 +78,23 @@ struct GPUShader *GPENCIL_shader_layer_blend_get(GPENCIL_e_data *e_data)
   }
   return e_data->layer_blend_sh;
 }
+
+struct GPUShader *GPENCIL_shader_depth_merge_get(GPENCIL_e_data *e_data)
+{
+  if (!e_data->depth_merge_sh) {
+    e_data->depth_merge_sh = GPU_shader_create_from_arrays({
+        .vert =
+            (const char *[]){
+                datatoc_common_fullscreen_vert_glsl,
+                NULL,
+            },
+        .frag =
+            (const char *[]){
+                datatoc_common_view_lib_glsl,
+                datatoc_gpencil_depth_merge_frag_glsl,
+                NULL,
+            },
+    });
+  }
+  return e_data->depth_merge_sh;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl
new file mode 100644
index 00000000000..6169e69c292
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl
@@ -0,0 +1,19 @@
+
+uniform sampler2D depthBuf;
+uniform float strokeDepth2d;
+uniform bool strokeOrder3d;
+
+in vec4 uvcoordsvar;
+
+void main()
+{
+  float depth = textureLod(depthBuf, uvcoordsvar.xy, 0).r;
+
+  if (strokeOrder3d) {
+    gl_FragDepth = depth;
+  }
+  else {
+    vec4 p = ProjectionMatrix * vec4(0.0, 0.0, strokeDepth2d, 1.0);
+    gl_FragDepth = (depth != 0) ? ((p.z / p.w) * 0.5 + 0.5) : 1.0;
+  }
+}



More information about the Bf-blender-cvs mailing list