[Bf-blender-cvs] [4ba94091be0] greasepencil-refactor: GPencil: Refactor: Add offscreen compositing foundation

Clément Foucault noreply at git.blender.org
Fri Dec 13 19:44:57 CET 2019


Commit: 4ba94091be0baf992ab73e2514c8651ca676030c
Author: Clément Foucault
Date:   Fri Dec 13 14:31:55 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB4ba94091be0baf992ab73e2514c8651ca676030c

GPencil: Refactor: Add offscreen compositing foundation

This put all Grease pencil drawing into a separate buffer that is then
composited on top of the rendered image.

This framebuffer has 2 RGB color target (one color and one alpha) to be
able to record any color blend types.

Moreover these buffers are floating point (R11_G11_B10) which will allow
the use of linear colors.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
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_composite_frag.glsl
M	source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 9d5231e5e00..896149443d4 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -278,6 +278,7 @@ data_to_c_simple(intern/shaders/common_fullscreen_vert.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_frag.glsl SRC)
 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_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_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index db84f4e044e..c9c8ec77720 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -45,11 +45,13 @@
 /* TODO remove the _new suffix. */
 GPENCIL_tObject *gpencil_object_cache_add_new(GPENCIL_PrivateData *pd, Object *ob)
 {
+  bGPdata *gpd = (bGPdata *)ob->data;
   GPENCIL_tObject *tgp_ob = BLI_memblock_alloc(pd->gp_object_pool);
 
   tgp_ob->layers.first = tgp_ob->layers.last = NULL;
   tgp_ob->vfx.first = tgp_ob->vfx.last = NULL;
   tgp_ob->camera_z = dot_v3v3(pd->camera_z_axis, ob->obmat[3]);
+  tgp_ob->is_drawmode3d = (gpd->draw_mode == GP_DRAWMODE_3D);
 
   BLI_LINKS_APPEND(&pd->tobjects, tgp_ob);
 
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 05de8a888f7..d3ffa0bb1f4 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -400,10 +400,24 @@ static void gpencil_check_screen_switches(const DRWContextState *draw_ctx,
 static void GPENCIL_cache_init_new(void *ved)
 {
   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
+  GPENCIL_PassList *psl = vedata->psl;
   GPENCIL_PrivateData *pd = vedata->stl->pd;
+  DRWShadingGroup *grp;
 
   const DRWContextState *draw_ctx = DRW_context_state_get();
   pd->cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
+
+  {
+    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);
+    grp = DRW_shgroup_create(sh, psl->composite_ps);
+    DRW_shgroup_uniform_texture_ref(grp, "colorBuf", &pd->color);
+    DRW_shgroup_uniform_texture_ref(grp, "alphaBuf", &pd->alpha);
+    DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+  }
 }
 
 void GPENCIL_cache_init(void *vedata)
@@ -799,9 +813,6 @@ static void gp_layer_cache_populate(bGPDlayer *gpl,
   DRW_shgroup_uniform_float_copy(iter->grp, "thicknessWorldScale", thickness_scale);
   DRW_shgroup_uniform_float_copy(iter->grp, "vertexColorOpacity", gpl->vertex_paint_opacity);
   DRW_shgroup_uniform_vec4_copy(iter->grp, "layerTint", gpl->tintcolor);
-  /* Should do this clear for the whole object. */
-  float clear_depth = is_stroke_order_3D ? 1.0f : 0.0f;
-  DRW_shgroup_clear_framebuffer(iter->grp, GPU_DEPTH_BIT, 0, 0, 0, 0, clear_depth, 0);
 }
 
 static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
@@ -999,6 +1010,7 @@ static void GPENCIL_cache_finish_new(void *ved)
 {
   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
   GPENCIL_PrivateData *pd = vedata->stl->pd;
+  GPENCIL_FramebufferList *fbl = vedata->fbl;
 
   /* Upload UBO data. */
   BLI_memblock_iter iter;
@@ -1011,6 +1023,24 @@ static void GPENCIL_cache_finish_new(void *ved)
 
   /* Sort object by distance to the camera. */
   pd->tobjects.first = gpencil_tobject_sort_fn_r(pd->tobjects.first, gpencil_tobject_dist_sort);
+
+  if (pd->tobjects.first) {
+    /* Create framebuffers only if needed. */
+    const float *size = DRW_viewport_size_get();
+    pd->depth = DRW_texture_pool_query_2d(
+        size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type);
+    pd->color = DRW_texture_pool_query_2d(
+        size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
+    pd->alpha = DRW_texture_pool_query_2d(
+        size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
+
+    GPU_framebuffer_ensure_config(&fbl->gpencil_fb,
+                                  {
+                                      GPU_ATTACHMENT_TEXTURE(pd->depth),
+                                      GPU_ATTACHMENT_TEXTURE(pd->color),
+                                      GPU_ATTACHMENT_TEXTURE(pd->alpha),
+                                  });
+  }
 }
 
 void GPENCIL_cache_finish(void *vedata)
@@ -1207,11 +1237,24 @@ static void drw_gpencil_select_render(GPENCIL_StorageList *stl, GPENCIL_PassList
 static void GPENCIL_draw_scene_new(void *ved)
 {
   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
+  GPENCIL_PassList *psl = vedata->psl;
   GPENCIL_PrivateData *pd = vedata->stl->pd;
+  GPENCIL_FramebufferList *fbl = vedata->fbl;
+  DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+  float clear_col[4] = {0.0f};
+
+  if (pd->tobjects.first == NULL) {
+    return;
+  }
+
+  GPU_framebuffer_bind(fbl->gpencil_fb);
+  GPU_framebuffer_clear_color(fbl->gpencil_fb, clear_col);
 
   for (GPENCIL_tObject *ob = pd->tobjects.first; ob; ob = ob->next) {
     DRW_stats_group_start("GPencil Object");
 
+    GPU_framebuffer_clear_depth(fbl->gpencil_fb, ob->is_drawmode3d ? 1.0f : 0.0f);
+
     if (ob->vfx.first) {
       /* TODO vfx */
       // GPU_framebuffer_bind(fbl->object_fb);
@@ -1239,6 +1282,9 @@ static void GPENCIL_draw_scene_new(void *ved)
     DRW_stats_group_end();
   }
 
+  GPU_framebuffer_bind(dfbl->default_fb);
+  DRW_draw_pass(psl->composite_ps);
+
   pd->gp_object_pool = pd->gp_layer_pool = pd->gp_vfx_pool = NULL;
 }
 
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index b5e3527f631..72b27632f71 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -196,6 +196,8 @@ typedef struct GPENCIL_tObject {
 
   /* Distance to camera. Used for sorting. */
   float camera_z;
+
+  bool is_drawmode3d;
 } GPENCIL_tObject;
 
 /* *********** LISTS *********** */
@@ -307,6 +309,10 @@ typedef struct GPENCIL_PassList {
   struct DRWPass *fx_shader_pass;
   struct DRWPass *fx_shader_pass_blend;
 
+  /* Refactored */
+
+  /* Composite the main GPencil buffer onto the rendered image. */
+  struct DRWPass *composite_ps;
 } GPENCIL_PassList;
 
 typedef struct GPENCIL_FramebufferList {
@@ -317,6 +323,9 @@ typedef struct GPENCIL_FramebufferList {
   struct GPUFrameBuffer *background_fb;
 
   struct GPUFrameBuffer *multisample_fb;
+
+  /* Refactored */
+  struct GPUFrameBuffer *gpencil_fb;
 } GPENCIL_FramebufferList;
 
 typedef struct GPENCIL_TextureList {
@@ -398,6 +407,10 @@ typedef struct GPENCIL_PrivateData {
   struct {
     GPENCIL_tObject *first, *last;
   } tobjects;
+  /* Temp Textures (shared with other engines). */
+  GPUTexture *depth;
+  GPUTexture *color;
+  GPUTexture *alpha;
   /* Current frame */
   int cfra;
   /* Used for computing object distance to camera. */
@@ -419,6 +432,8 @@ typedef struct GPENCIL_e_data {
 
   /* GPencil Object rendering */
   struct GPUShader *gpencil_sh;
+  /* Final Compositing over rendered background. */
+  struct GPUShader *composite_sh;
 
   /* general drawing shaders */
   struct GPUShader *gpencil_fill_sh;
@@ -650,6 +665,7 @@ void gpencil_fx_draw(struct GPENCIL_e_data *e_data,
 
 /* Shaders */
 struct GPUShader *GPENCIL_shader_geometry_get(GPENCIL_e_data *e_data);
+struct GPUShader *GPENCIL_shader_composite_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 e3542f52f28..ad83734c2a2 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader.c
@@ -26,6 +26,7 @@
 extern char datatoc_gpencil_common_lib_glsl[];
 extern char datatoc_gpencil_frag_glsl[];
 extern char datatoc_gpencil_vert_glsl[];
+extern char datatoc_gpencil_composite_frag_glsl[];
 
 extern char datatoc_common_colormanagement_lib_glsl[];
 extern char datatoc_common_view_lib_glsl[];
@@ -57,3 +58,11 @@ struct GPUShader *GPENCIL_shader_geometry_get(GPENCIL_e_data *e_data)
   }
   return e_data->gpencil_sh;
 }
+
+struct GPUShader *GPENCIL_shader_composite_get(GPENCIL_e_data *e_data)
+{
+  if (!e_data->composite_sh) {
+    e_data->composite_sh = DRW_shader_create_fullscreen(datatoc_gpencil_composite_frag_glsl, NULL);
+  }
+  return e_data->composite_sh;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_composite_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_composite_frag.glsl
new file mode 100644
index 00000000000..ffac7d21124
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_composite_frag.glsl
@@ -0,0 +1,21 @@
+
+uniform sampler2D colorBuf;
+uniform sampler2D alphaBuf;
+
+in vec4 uvcoordsvar;
+
+/* Reminder: Blending func is fragRevealage * DST + fragColor .*/
+layout(location = 0, index = 0) out vec4 fragColor;
+layout(location = 0, index = 1) out vec4 fragRevealage;
+
+void main()
+{
+  /* Invert alpha to convert to revealage. */
+  fragRevealage.rgb = 1.0 - textureLod(alphaBuf, uvcoordsvar.xy, 0.0).rgb;
+  /* Average for alpha channel. */
+  fragRevealage.a = clamp(dot(fragRevealage.rgb, vec3(0.333334)), 0.0, 1.0);
+  /* Color buf is already premultiplied. Just add it to the color. */
+  fragColor.rgb = textureLod(colorBuf, uvcoordsvar.xy, 0.0).rgb;
+  /* Add the alpha. */
+  fragColor.a = 1.0 - fragRevealage.a;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
index 27c5622302b..63a36ab3aff 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
@@ -8,7 +8,8 @@ in vec2 finalUvs;
 flat in int matFlag;
 flat in float depth;
 
-out vec

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list