GPencil: Fade layer using background color
authorAntonio Vazquez <blendergit@gmail.com>
Mon, 9 Sep 2019 13:17:35 +0000 (15:17 +0200)
committerAntonio Vazquez <blendergit@gmail.com>
Mon, 9 Sep 2019 13:41:11 +0000 (15:41 +0200)
Now the fade layer uses the same logic used to fade objects and also is available in all modes.

Reviewers: mendio, pepeland

Reviewed By: mendio, pepeland

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

release/scripts/startup/bl_ui/space_view3d.py
source/blender/draw/engines/gpencil/gpencil_draw_utils.c
source/blender/draw/engines/gpencil/gpencil_engine.h
source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl

index d144c2ffab6e1c1d006fdda95105b3007793ad8b..69fa5bc8f4bd0bc8e81eb3da55726a587cef97fe 100644 (file)
@@ -6135,6 +6135,12 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
         sub.active = overlay.use_gpencil_grid
         sub.prop(overlay, "gpencil_grid_opacity", text="Canvas", slider=True)
 
+        row = col.row()
+        row.prop(overlay, "use_gpencil_fade_layers", text="")
+        sub = row.row()
+        sub.active = overlay.use_gpencil_fade_layers
+        sub.prop(overlay, "gpencil_fade_layer", text="Fade Layers", slider=True)
+
         row = col.row()
         row.prop(overlay, "use_gpencil_paper", text="")
         sub = row.row(align=True)
@@ -6142,13 +6148,6 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
         sub.prop(overlay, "gpencil_paper_opacity", text="Fade Objects", slider=True)
         sub.prop(overlay, "use_gpencil_fade_objects", text="", icon='OUTLINER_OB_GREASEPENCIL')
 
-        if context.object.mode == 'PAINT_GPENCIL':
-            row = col.row()
-            row.prop(overlay, "use_gpencil_fade_layers", text="")
-            sub = row.row()
-            sub.active = overlay.use_gpencil_fade_layers
-            sub.prop(overlay, "gpencil_fade_layer", text="Fade Layers", slider=True)
-
         if context.object.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}:
             layout.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
             layout.prop(overlay, "use_gpencil_multiedit_line_only", text="Show Edit Lines only in multiframe")
index e3c3f0b5d12e0cd666e52d9f4842514443c8f1fe..3d1aad827c563730711a9d5a2f4dfc2a13f19904 100644 (file)
@@ -83,13 +83,49 @@ static bool gpencil_fade_object_check(GPENCIL_StorageList *stl, Object *ob)
   return (bool)((!is_render) && (!playing) && (!is_mat_preview) && (!is_select));
 }
 
+/* Define Fade layer uniforms. */
+static void gpencil_set_fade_layer_uniforms(
+    GPENCIL_StorageList *stl, DRWShadingGroup *grp, Object *ob, bGPDlayer *gpl, const bool skip)
+{
+  const DRWContextState *draw_ctx = DRW_context_state_get();
+  View3D *v3d = draw_ctx->v3d;
+  const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
+  const bool is_fade = (v3d) && (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) &&
+                       (draw_ctx->obact) && (draw_ctx->obact == ob) &&
+                       ((gpl->flag & GP_LAYER_ACTIVE) == 0);
+
+  const bool playing = stl->storage->is_playing;
+  const bool is_render = (bool)stl->storage->is_render;
+  const bool is_mat_preview = (bool)stl->storage->is_mat_preview;
+  const bool is_select = (bool)(DRW_state_is_select() || DRW_state_is_depth());
+
+  /* If drawing or not fading layer, skip. */
+  if ((!overlay) || (skip) || (!is_fade) || (is_render) || (playing) || (is_mat_preview) ||
+      (is_select)) {
+    DRW_shgroup_uniform_int_copy(grp, "fade_layer", 0);
+    return;
+  }
+
+  /* If layer is above active, use alpha (2) if below use mix with background (1). */
+  if (stl->storage->is_ontop) {
+    DRW_shgroup_uniform_int_copy(grp, "fade_layer", 2);
+  }
+  else {
+    DRW_shgroup_uniform_int_copy(grp, "fade_layer", 1);
+  }
+  if (v3d) {
+    DRW_shgroup_uniform_vec3(grp, "fade_color", v3d->shading.background_color, 1);
+    DRW_shgroup_uniform_float(grp, "fade_layer_factor", &v3d->overlay.gpencil_fade_layer, 1);
+  }
+}
+
 /* Define Fade object uniforms. */
-static void gpencil_set_fade_uniforms(View3D *v3d, DRWShadingGroup *grp, bool status)
+static void gpencil_set_fade_ob_uniforms(View3D *v3d, DRWShadingGroup *grp, bool status)
 {
-  DRW_shgroup_uniform_bool_copy(grp, "fade_on", status);
+  DRW_shgroup_uniform_bool_copy(grp, "fade_ob", status);
   if (v3d) {
     DRW_shgroup_uniform_vec3(grp, "fade_color", v3d->shading.background_color, 1);
-    DRW_shgroup_uniform_float(grp, "fade_factor", &v3d->overlay.gpencil_paper_opacity, 1);
+    DRW_shgroup_uniform_float(grp, "fade_ob_factor", &v3d->overlay.gpencil_paper_opacity, 1);
   }
 }
 
@@ -286,10 +322,6 @@ static void set_wireframe_color(Object *ob,
 {
   const DRWContextState *draw_ctx = DRW_context_state_get();
   World *world = draw_ctx->scene->world;
-  const bool is_fade = (v3d) && (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) &&
-                       (draw_ctx->obact) && (draw_ctx->obact == ob) &&
-                       ((gpl->flag & GP_LAYER_ACTIVE) == 0);
-  const float opacity = is_fade ? v3d->overlay.gpencil_fade_layer : 1.0f;
 
   float color[4];
   if (((gp_style->stroke_rgba[3] < GPENCIL_ALPHA_OPACITY_THRESH) ||
@@ -300,7 +332,6 @@ static void set_wireframe_color(Object *ob,
   else {
     copy_v4_v4(color, gp_style->stroke_rgba);
   }
-  float alpha = color[3] * opacity;
 
   /* wire color */
   if ((v3d) && (id > -1)) {
@@ -337,13 +368,13 @@ static void set_wireframe_color(Object *ob,
         else {
           copy_v3_v3(color, v3d->shading.single_color);
         }
-        color[3] = is_fade ? alpha : 1.0f;
+        color[3] = 1.0f;
         linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
         break;
       }
       case V3D_SHADING_OBJECT_COLOR: {
         copy_v4_v4(color, ob->color);
-        color[3] = is_fade ? alpha : 1.0f;
+        color[3] = 1.0f;
         linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
         break;
       }
@@ -360,7 +391,7 @@ static void set_wireframe_color(Object *ob,
         hsv_to_rgb_v(hsv, &wire_col[0]);
 
         copy_v3_v3(stl->shgroups[id].wire_color, wire_col);
-        stl->shgroups[id].wire_color[3] = is_fade ? alpha : 1.0f;
+        stl->shgroups[id].wire_color[3] = 1.0f;
         break;
       }
       default: {
@@ -375,7 +406,7 @@ static void set_wireframe_color(Object *ob,
 
   /* if solid, the alpha must be set to alpha */
   if (stl->shgroups[id].shading_type[0] == OB_SOLID) {
-    stl->shgroups[id].wire_color[3] = is_fade ? alpha : 1.0f;
+    stl->shgroups[id].wire_color[3] = 1.0f;
   }
 }
 
@@ -467,8 +498,11 @@ static DRWShadingGroup *gpencil_shgroup_fill_create(GPENCIL_Data *vedata,
 
   DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
 
+  /* Fade layer uniforms. */
+  gpencil_set_fade_layer_uniforms(stl, grp, ob, gpl, false);
+
   /* Fade object uniforms. */
-  gpencil_set_fade_uniforms(v3d, grp, gpencil_fade_object_check(stl, ob));
+  gpencil_set_fade_ob_uniforms(v3d, grp, gpencil_fade_object_check(stl, ob));
 
   /* wire color */
   set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, true);
@@ -592,8 +626,11 @@ DRWShadingGroup *gpencil_shgroup_stroke_create(GPENCIL_Data *vedata,
     }
     DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
 
+    /* Fade layer uniforms. */
+    gpencil_set_fade_layer_uniforms(stl, grp, ob, gpl, false);
+
     /* Fade object uniforms. */
-    gpencil_set_fade_uniforms(v3d, grp, gpencil_fade_object_check(stl, ob));
+    gpencil_set_fade_ob_uniforms(v3d, grp, gpencil_fade_object_check(stl, ob));
 
     /* wire color */
     set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
@@ -645,8 +682,11 @@ DRWShadingGroup *gpencil_shgroup_stroke_create(GPENCIL_Data *vedata,
     DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
   }
 
+  /* Fade layer uniforms. */
+  gpencil_set_fade_layer_uniforms(stl, grp, ob, gpl, true);
+
   /* Fade object uniforms. */
-  gpencil_set_fade_uniforms(v3d, grp, false);
+  gpencil_set_fade_ob_uniforms(v3d, grp, false);
 
   /* image texture for pattern */
   if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
@@ -747,8 +787,11 @@ static DRWShadingGroup *gpencil_shgroup_point_create(GPENCIL_Data *vedata,
     }
     DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
 
+    /* Fade layer uniforms. */
+    gpencil_set_fade_layer_uniforms(stl, grp, ob, gpl, false);
+
     /* Fade object uniforms. */
-    gpencil_set_fade_uniforms(v3d, grp, gpencil_fade_object_check(stl, ob));
+    gpencil_set_fade_ob_uniforms(v3d, grp, gpencil_fade_object_check(stl, ob));
 
     /* wire color */
     set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
@@ -808,8 +851,11 @@ static DRWShadingGroup *gpencil_shgroup_point_create(GPENCIL_Data *vedata,
     DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
   }
 
+  /* Fade layer uniforms. */
+  gpencil_set_fade_layer_uniforms(stl, grp, ob, gpl, true);
+
   /* Fade object uniforms. */
-  gpencil_set_fade_uniforms(v3d, grp, false);
+  gpencil_set_fade_ob_uniforms(v3d, grp, false);
 
   /* image texture */
   if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
@@ -1684,6 +1730,8 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
   int start_edlin = 0;
 
   uint stencil_id = 1;
+  /* Flag to determine if the layer is above active layer. */
+  stl->storage->is_ontop = false;
   for (int i = 0; i < cache->grp_used; i++) {
     elm = &cache->grp_cache[i];
     array_elm = &cache_ob->shgrp_array[idx];
@@ -1711,6 +1759,10 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
     }
 
     gpl = elm->gpl;
+    if ((!stl->storage->is_ontop) && (gpl->flag & GP_LAYER_ACTIVE)) {
+      stl->storage->is_ontop = true;
+    }
+
     bGPDframe *gpf = elm->gpf;
     bGPDstroke *gps = elm->gps;
     MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
@@ -1956,12 +2008,10 @@ void gpencil_populate_datablock(GPENCIL_e_data *e_data,
   int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
 
   bGPDframe *gpf_eval = NULL;
-  const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
   const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
 
   float opacity;
   bGPDframe *gpf = NULL;
-  bGPDlayer *gpl_active = BKE_gpencil_layer_getactive(gpd);
 
   /* check if playing animation */
   const bool playing = stl->storage->is_playing;
@@ -2017,12 +2067,6 @@ void gpencil_populate_datablock(GPENCIL_e_data *e_data,
         (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT)) {
       opacity = opacity * v3d->overlay.xray_alpha_bone;
     }
-    /* fade no active layers */
-    if ((overlay) && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL) &&
-        (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) && (draw_ctx->obact) &&
-        (draw_ctx->obact == ob) && (gpl != gpl_active)) {
-      opacity = opacity * v3d->overlay.gpencil_fade_layer;
-    }
 
     /* Get evaluated frames array data */
     int idx_eval = BLI_findindex(&gpd->layers, gpl);
index f29e83f64cf587d06c4f21611f1345d79cf6df1b..79bcffac5125dbc64f521dc4e64f4eca53b0eb58 100644 (file)
@@ -145,6 +145,7 @@ typedef struct GPENCIL_Storage {
   bool is_mat_preview;
   bool background_ready;
   int is_xray;
+  bool is_ontop;
   bool reset_cache;
   const float *pixsize;
   float render_pixsize;
index 7e8f59cf9178cde4d880b096735cf2453b29f960..0c290260b201a20b995f30c3b64e58a916ab7058 100644 (file)
@@ -26,9 +26,11 @@ uniform int viewport_xray;
 uniform int shading_type[2];
 uniform vec4 wire_color;
 
-uniform bool fade_on;
+uniform int fade_layer;
+uniform float fade_layer_factor;
+uniform bool fade_ob;
 uniform vec3 fade_color;
-uniform float fade_factor;
+uniform float fade_ob_factor;
 
 /* keep this list synchronized with list in gpencil_draw_utils.c */
 #define SOLID 0
@@ -216,7 +218,15 @@ void main()
     }
   }
   /* Apply paper opacity */
-  if (fade_on == true) {
-    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_factor);
+  if (fade_layer == 1) {
+    /* Layer is below, mix with background. */
+    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_layer_factor);
+  }
+  else if (fade_layer == 2) {
+    /* Layer is above, change opacity. */
+    fragColor.a *= fade_layer_factor;
+  }
+  else if (fade_ob == true) {
+    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_ob_factor);
   }
 }
index f59c08730fee0fa0c97e080cca3f52300c0d37b9..d79b8fb4d8ab830e83561f2437a6f53a429e2960 100644 (file)
@@ -14,9 +14,11 @@ in vec4 mColor;
 in vec2 mTexCoord;
 out vec4 fragColor;
 
-uniform bool fade_on;
+uniform int fade_layer;
+uniform float fade_layer_factor;
+uniform bool fade_ob;
 uniform vec3 fade_color;
-uniform float fade_factor;
+uniform float fade_ob_factor;
 
 #define texture2D texture
 
@@ -110,7 +112,15 @@ void main()
   }
 
   /* Apply paper opacity */
-  if (fade_on == true) {
-    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_factor);
+  if (fade_layer == 1) {
+    /* Layer is below, mix with background. */
+    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_layer_factor);
+  }
+  else if (fade_layer == 2) {
+    /* Layer is above, change opacity. */
+    fragColor.a *= fade_layer_factor;
+  }
+  else if (fade_ob == true) {
+    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_ob_factor);
   }
 }
index e64166527a10d03947885589389d59ca0ce6fa3b..0f1665b73c229d307df9905de1c25ef9432acff6 100644 (file)
@@ -8,9 +8,11 @@ uniform vec4 colormix;
 uniform float mix_stroke_factor;
 uniform int shading_type[2];
 
-uniform bool fade_on;
+uniform int fade_layer;
+uniform float fade_layer_factor;
+uniform bool fade_ob;
 uniform vec3 fade_color;
-uniform float fade_factor;
+uniform float fade_ob_factor;
 
 in vec4 mColor;
 in vec2 mTexCoord;
@@ -94,7 +96,15 @@ void main()
   }
 
   /* Apply paper opacity */
-  if (fade_on == true) {
-    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_factor);
+  if (fade_layer == 1) {
+    /* Layer is below, mix with background. */
+    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_layer_factor);
+  }
+  else if (fade_layer == 2) {
+    /* Layer is above, change opacity. */
+    fragColor.a *= fade_layer_factor;
+  }
+  else if (fade_ob == true) {
+    fragColor.rgb = mix(fade_color.rgb, fragColor.rgb, fade_ob_factor);
   }
 }