[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