Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c11
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_data.c8
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h6
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c74
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl4
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl21
6 files changed, 78 insertions, 46 deletions
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 363794e1be3..c4997dace7e 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -58,6 +58,17 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
tgp_ob->is_drawmode3d = (gpd->draw_mode == GP_DRAWMODE_3D) || pd->draw_depth_only;
tgp_ob->object_scale = mat4_to_scale(ob->obmat);
+ /* Check if any material with holdout flag enabled. */
+ tgp_ob->do_mat_holdout = false;
+ for (int i = 0; i < ob->totcol; i++) {
+ MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, i + 1);
+ if ((gp_style->flag & GP_MATERIAL_IS_STROKE_HOLDOUT) ||
+ ((gp_style->flag & GP_MATERIAL_IS_FILL_HOLDOUT))) {
+ tgp_ob->do_mat_holdout = true;
+ break;
+ }
+ }
+
/* Find the normal most likely to represent the gpObject. */
/* TODO: This does not work quite well if you use
* strokes not aligned with the object axes. Maybe we could try to
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index 7faf426c4e0..89e47f88eec 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -237,6 +237,14 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje
mat_data->flag |= GP_STROKE_OVERLAP;
}
+ /* Material with holdout. */
+ if (gp_style->flag & GP_MATERIAL_IS_STROKE_HOLDOUT) {
+ mat_data->flag |= GP_STROKE_HOLDOUT;
+ }
+ if (gp_style->flag & GP_MATERIAL_IS_FILL_HOLDOUT) {
+ mat_data->flag |= GP_FILL_HOLDOUT;
+ }
+
gp_style = gpencil_viewport_material_overrides(pd, ob, color_type, gp_style);
/* Stroke Style */
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 7a516b3dd6b..0922ab6552c 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -80,6 +80,8 @@ typedef struct gpMaterial {
#define GP_STROKE_TEXTURE_STENCIL (1 << 4)
#define GP_STROKE_TEXTURE_PREMUL (1 << 5)
#define GP_STROKE_DOTS (1 << 6)
+#define GP_STROKE_HOLDOUT (1 << 7)
+#define GP_FILL_HOLDOUT (1 << 8)
#define GP_FILL_TEXTURE_USE (1 << 10)
#define GP_FILL_TEXTURE_PREMUL (1 << 11)
#define GP_FILL_TEXTURE_CLIP (1 << 12)
@@ -194,6 +196,10 @@ typedef struct GPENCIL_tObject {
float plane_mat[4][4];
bool is_drawmode3d;
+
+ /* Use Material Holdout. */
+ bool do_mat_holdout;
+
} GPENCIL_tObject;
/* *********** LISTS *********** */
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index cf6e78f4702..bf146add19d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -585,10 +585,6 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObjec
bGPdata *gpd = (bGPdata *)ob->data;
GPENCIL_FramebufferList *fbl = vedata->fbl;
GPENCIL_PrivateData *pd = vedata->stl->pd;
- /* If simplify enabled, nothing more to do. */
- if (pd->simplify_fx) {
- return;
- }
/* These may not be allocated yet, use adress of future pointer. */
gpIterVfxData iter = {
@@ -601,44 +597,46 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObjec
.target_reveal_tx = &pd->reveal_layer_tx,
.source_reveal_tx = &pd->reveal_object_tx,
};
-
- LISTBASE_FOREACH (ShaderFxData *, fx, &ob->shader_fx) {
- if (effect_is_active(gpd, fx, pd->is_viewport)) {
- switch (fx->type) {
- case eShaderFxType_Blur:
- gpencil_vfx_blur((BlurShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Colorize:
- gpencil_vfx_colorize((ColorizeShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Flip:
- gpencil_vfx_flip((FlipShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Pixel:
- gpencil_vfx_pixelize((PixelShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Rim:
- gpencil_vfx_rim((RimShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Shadow:
- gpencil_vfx_shadow((ShadowShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Glow:
- gpencil_vfx_glow((GlowShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Swirl:
- gpencil_vfx_swirl((SwirlShaderFxData *)fx, ob, &iter);
- break;
- case eShaderFxType_Wave:
- gpencil_vfx_wave((WaveShaderFxData *)fx, ob, &iter);
- break;
- default:
- break;
+ /* If simplify enabled, nothing more to do. */
+ if (!pd->simplify_fx) {
+ LISTBASE_FOREACH (ShaderFxData *, fx, &ob->shader_fx) {
+ if (effect_is_active(gpd, fx, pd->is_viewport)) {
+ switch (fx->type) {
+ case eShaderFxType_Blur:
+ gpencil_vfx_blur((BlurShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Colorize:
+ gpencil_vfx_colorize((ColorizeShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Flip:
+ gpencil_vfx_flip((FlipShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Pixel:
+ gpencil_vfx_pixelize((PixelShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Rim:
+ gpencil_vfx_rim((RimShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Shadow:
+ gpencil_vfx_shadow((ShadowShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Glow:
+ gpencil_vfx_glow((GlowShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Swirl:
+ gpencil_vfx_swirl((SwirlShaderFxData *)fx, ob, &iter);
+ break;
+ case eShaderFxType_Wave:
+ gpencil_vfx_wave((WaveShaderFxData *)fx, ob, &iter);
+ break;
+ default:
+ break;
+ }
}
}
}
- if (tgp_ob->vfx.first != NULL) {
+ if ((!pd->simplify_fx && tgp_ob->vfx.first != NULL) || tgp_ob->do_mat_holdout) {
/* We need an extra pass to combine result to main buffer. */
iter.target_fb = &fbl->gpencil_fb;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
index e1323f01d9e..5e930af7bd7 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -34,6 +34,8 @@ struct gpMaterial {
#define GP_STROKE_TEXTURE_STENCIL (1 << 4)
#define GP_STROKE_TEXTURE_PREMUL (1 << 5)
#define GP_STROKE_DOTS (1 << 6)
+#define GP_STROKE_HOLDOUT (1 << 7)
+#define GP_FILL_HOLDOUT (1 << 8)
#define GP_FILL_TEXTURE_USE (1 << 10)
#define GP_FILL_TEXTURE_PREMUL (1 << 11)
#define GP_FILL_TEXTURE_CLIP (1 << 12)
@@ -44,7 +46,7 @@ struct gpMaterial {
/* Multiline defines can crash blender with certain GPU drivers. */
/* clang-format off */
-#define GP_FILL_FLAGS (GP_FILL_TEXTURE_USE | GP_FILL_TEXTURE_PREMUL | GP_FILL_TEXTURE_CLIP | GP_FILL_GRADIENT_USE | GP_FILL_GRADIENT_RADIAL)
+#define GP_FILL_FLAGS (GP_FILL_TEXTURE_USE | GP_FILL_TEXTURE_PREMUL | GP_FILL_TEXTURE_CLIP | GP_FILL_GRADIENT_USE | GP_FILL_GRADIENT_RADIAL | GP_FILL_HOLDOUT)
/* clang-format on */
#define GP_FLAG_TEST(flag, val) (((flag) & (val)) != 0)
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
index d81c6f4fe0b..8cf457ee4dd 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
@@ -89,14 +89,21 @@ void main()
fragColor *= stroke_round_cap_mask(
strokePt1, strokePt2, strokeAspect, strokeThickness, strokeHardeness);
- /* For compatibility with colored alpha buffer.
- * Note that we are limited to mono-chromatic alpha blending here
- * because of the blend equation and the limit of 1 color target
- * when using custom color blending. */
- revealColor = vec4(0.0, 0.0, 0.0, fragColor.a);
+ /* Holdout materials. */
+ if (GP_FLAG_TEST(matFlag, GP_STROKE_HOLDOUT | GP_FILL_HOLDOUT)) {
+ revealColor = fragColor.aaaa;
+ }
+ else {
+ /* NOT holdout materials.
+ * For compatibility with colored alpha buffer.
+ * Note that we are limited to mono-chromatic alpha blending here
+ * because of the blend equation and the limit of 1 color target
+ * when using custom color blending. */
+ revealColor = vec4(0.0, 0.0, 0.0, fragColor.a);
- if (fragColor.a < 0.001) {
- discard;
+ if (fragColor.a < 0.001) {
+ discard;
+ }
}
vec2 fb_size = max(vec2(textureSize(gpSceneDepthTexture, 0).xy),