Fix: GPencil mask shows in view layer render
authorFalk David <falkdavid@gmx.de>
Wed, 26 May 2021 14:07:03 +0000 (16:07 +0200)
committerFalk David <falkdavid@gmx.de>
Wed, 26 May 2021 14:32:58 +0000 (16:32 +0200)
Currently when rendering the view layer of a grease pencil layer that has
a mask layer attached, the mask layer would show in the rendered image.
This is inconsistent with the default behaviour with no mask on the
grease pencil layer, because it would only render what's on that
particular layer and not anything from any other layer.

This patch makes the masks invisible in the render.

Note: This might seem like not the best solution, but because masks are
just regular grease pencil layers, it's tricky to pass this edge-case to the
drawing code. The way it is handled right now is the best I could come
up with, without making changes that could affect something else.

Reviewed By: antoniov

Maniphest Tasks: T88202

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

source/blender/blenkernel/intern/gpencil.c

index 9c84d155330d94debb466b0f09be441827f24507..182d06f8f72a2b86667d31289e11da22d9325a6c 100644 (file)
@@ -2659,6 +2659,7 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
     bGPDframe *act_gpf = gpl->actframe;
     bGPDframe *sta_gpf = act_gpf;
     bGPDframe *end_gpf = act_gpf ? act_gpf->next : NULL;
+    float prev_opacity = gpl->opacity;
 
     if (gpl->flag & GP_LAYER_HIDE) {
       continue;
@@ -2674,9 +2675,12 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
      * This is used only in final render and never in Viewport. */
     if ((view_layer != NULL) && (gpl->viewlayername[0] != '\0') &&
         (!STREQ(view_layer->name, gpl->viewlayername))) {
-      /* If the layer is used as mask, cannot be filtered or the masking system
-       * will crash because needs the mask layer in the draw pipeline. */
-      if (!gpencil_is_layer_mask(view_layer, gpd, gpl)) {
+      /* Do not skip masks when rendering the viewlayer so that it can still be used to clip
+       * other layers. Instead set their opacity to zero. */
+      if (gpencil_is_layer_mask(view_layer, gpd, gpl)) {
+        gpl->opacity = 0.0f;
+      }
+      else {
         continue;
       }
     }
@@ -2771,6 +2775,7 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
       if (layer_cb) {
         layer_cb(gpl, act_gpf, NULL, thunk);
       }
+      gpl->opacity = prev_opacity;
       continue;
     }
 
@@ -2808,6 +2813,7 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
       /* If layer solo mode and Paint mode, only keyframes with data are displayed. */
       if (GPENCIL_PAINT_MODE(gpd) && (gpl->flag & GP_LAYER_SOLO_MODE) &&
           (act_gpf->framenum != cfra)) {
+        gpl->opacity = prev_opacity;
         continue;
       }
 
@@ -2818,6 +2824,9 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
         stroke_cb(gpl, act_gpf, gps, thunk);
       }
     }
+
+    /* Restore the opacity in case it was overwritten (used to hide masks in render). */
+    gpl->opacity = prev_opacity;
   }
 }