GPencil: Add option to mix color with texture
authorAntonioya <blendergit@gmail.com>
Thu, 18 Apr 2019 12:19:00 +0000 (14:19 +0200)
committerAntonioya <blendergit@gmail.com>
Thu, 18 Apr 2019 17:33:06 +0000 (19:33 +0200)
This was already supported in Fill, but not in Strokes. This adds more artistic options when use textured strokes.

release/scripts/startup/bl_ui/properties_material_gpencil.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_point_frag.glsl
source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
source/blender/editors/gpencil/drawgpencil.c
source/blender/makesdna/DNA_material_types.h
source/blender/makesrna/intern/rna_material.c

index e982bea..51ad691 100644 (file)
@@ -146,8 +146,14 @@ class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel):
                     col.prop(gpcolor, "pixel_size", text="UV Factor")
 
                 col.prop(gpcolor, "use_stroke_pattern", text="Use As Pattern")
-
-            if gpcolor.stroke_style == 'SOLID' or gpcolor.use_stroke_pattern is True:
+                if gpcolor.use_stroke_pattern is False:
+                    col.prop(gpcolor, "use_stroke_texture_mix", text="Mix Color")
+                    if gpcolor.use_stroke_texture_mix is True:
+                        col.prop(gpcolor, "mix_stroke_factor", text="Factor")
+
+            if gpcolor.stroke_style == 'SOLID' or \
+                gpcolor.use_stroke_pattern is True or \
+                gpcolor.use_stroke_texture_mix is True:
                 col.prop(gpcolor, "color", text="Color")
 
             if gpcolor.mode in {'DOTS', 'BOX'}:
@@ -203,7 +209,7 @@ class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel):
                 col.prop(gpcolor, "pattern_gridsize", text="Box Size")
 
         # Texture
-        if gpcolor.fill_style == 'TEXTURE' or (gpcolor.texture_mix is True and gpcolor.fill_style == 'SOLID'):
+        if gpcolor.fill_style == 'TEXTURE' or (gpcolor.use_fill_texture_mix is True and gpcolor.fill_style == 'SOLID'):
             col.template_ID(gpcolor, "fill_image", open="image.open")
 
             if gpcolor.fill_style == 'TEXTURE':
@@ -218,9 +224,9 @@ class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel):
             col.prop(gpcolor, "texture_clamp", text="Clip Image")
 
             if gpcolor.use_fill_pattern is False:
-                col.prop(gpcolor, "texture_mix", text="Mix With Color")
+                col.prop(gpcolor, "use_fill_texture_mix", text="Mix With Color")
 
-                if gpcolor.texture_mix is True:
+                if gpcolor.use_fill_texture_mix is True:
                     col.prop(gpcolor, "fill_color", text="Mix Color")
                     col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True)
 
index 320b621..5dda2fa 100644 (file)
@@ -421,7 +421,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(GPENCIL_e_data *e_data,
   DRW_shgroup_uniform_float(grp, "texture_opacity", &gp_style->texture_opacity, 1);
   DRW_shgroup_uniform_float(grp, "layer_opacity", &gpl->opacity, 1);
 
-  stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0;
+  stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_FILL_TEX_MIX ? 1 : 0;
   DRW_shgroup_uniform_int(grp, "texture_mix", &stl->shgroups[id].texture_mix, 1);
 
   stl->shgroups[id].texture_flip = gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0;
@@ -450,7 +450,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(GPENCIL_e_data *e_data,
   DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
 
   /* image texture */
-  if ((gp_style->flag & GP_STYLE_COLOR_TEX_MIX) ||
+  if ((gp_style->flag & GP_STYLE_FILL_TEX_MIX) ||
       (gp_style->fill_style & GP_STYLE_FILL_STYLE_TEXTURE)) {
     ImBuf *ibuf;
     Image *image = gp_style->ima;
@@ -569,6 +569,12 @@ DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(GPENCIL_e_data *e_data,
     /* wire color */
     set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
     DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
+
+    /* mix stroke factor */
+    stl->shgroups[id].mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+                                              gp_style->mix_stroke_factor :
+                                              0.0f;
+    DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->shgroups[id].mix_stroke_factor, 1);
   }
   else {
     stl->storage->obj_scale = 1.0f;
@@ -591,8 +597,16 @@ DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(GPENCIL_e_data *e_data,
     /* viewport x-ray */
     DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
     DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
+
+    /* mix stroke factor */
+    stl->storage->mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+                                          gp_style->mix_stroke_factor :
+                                          0.0f;
+    DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->storage->mix_stroke_factor, 1);
   }
 
+  DRW_shgroup_uniform_vec4(grp, "colormix", gp_style->stroke_rgba, 1);
+
   if ((gpd) && (id > -1)) {
     stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
     DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
@@ -703,6 +717,16 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
     /* wire color */
     set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
     DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
+
+    /* mix stroke factor */
+    stl->shgroups[id].mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+                                              gp_style->mix_stroke_factor :
+                                              0.0f;
+    DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->shgroups[id].mix_stroke_factor, 1);
+
+    /* lock rotation of dots and boxes */
+    stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
+    DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
   }
   else {
     stl->storage->obj_scale = 1.0f;
@@ -724,25 +748,28 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
     DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->storage->gradient_s, 1);
 
     /* viewport x-ray */
-    stl->shgroups[id].is_xray = ((ob) && (ob->dt == OB_WIRE)) ? 1 : stl->storage->is_xray;
-    DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
+    DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
     DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
+
+    /* mix stroke factor */
+    stl->storage->mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+                                          gp_style->mix_stroke_factor :
+                                          0.0f;
+    DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->storage->mix_stroke_factor, 1);
+
+    /* lock rotation of dots and boxes */
+    DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
   }
 
+  DRW_shgroup_uniform_vec4(grp, "colormix", gp_style->stroke_rgba, 1);
+
   if ((gpd) && (id > -1)) {
     stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
     DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&stl->shgroups[id].xray_mode, 1);
-
-    /* lock rotation of dots and boxes */
-    stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
-    DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
   }
   else {
     /* for drawing always on predefined z-depth */
     DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
-
-    /* lock rotation of dots and boxes */
-    DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
   }
 
   /* image texture */
index 3add2cb..2ac1dc3 100644 (file)
@@ -134,6 +134,8 @@ typedef struct GPENCIL_shgroup {
   float gradient_f;
   float gradient_s[2];
 
+  float mix_stroke_factor;
+
   /* color of the wireframe */
   float wire_color[4];
   /* shading type and mode */
@@ -182,6 +184,8 @@ typedef struct GPENCIL_Storage {
   float gradient_s[2];
   int use_follow_path;
 
+  float mix_stroke_factor;
+
   /* Render Matrices and data */
   float persmat[4][4], persinv[4][4];
   float viewmat[4][4], viewinv[4][4];
index c8af822..204d196 100644 (file)
@@ -5,6 +5,9 @@ uniform sampler2D myTexture;
 uniform float gradient_f;
 uniform vec2 gradient_s;
 
+uniform vec4 colormix;
+uniform float mix_stroke_factor;
+
 in vec4 mColor;
 in vec2 mTexCoord;
 out vec4 fragColor;
@@ -47,7 +50,15 @@ void main()
   }
   /* texture */
   if (color_type == GPENCIL_COLOR_TEXTURE) {
-    fragColor = texture2D(myTexture, mTexCoord);
+    vec4 text_color = texture2D(myTexture, mTexCoord);
+    if (mix_stroke_factor > 0.0) {
+      fragColor.rgb = mix(text_color.rgb, colormix.rgb, mix_stroke_factor);
+      fragColor.a = text_color.a;
+    }
+    else {
+      fragColor = text_color;
+    }
+
     /* mult both alpha factor to use strength factor with texture */
     fragColor.a = min(fragColor.a * mColor.a, fragColor.a);
   }
index 35d0730..8964bee 100644 (file)
@@ -3,6 +3,9 @@ uniform sampler2D myTexture;
 
 uniform float gradient_f;
 
+uniform vec4 colormix;
+uniform float mix_stroke_factor;
+
 in vec4 mColor;
 in vec2 mTexCoord;
 in vec2 uvfac;
@@ -46,7 +49,14 @@ void main()
 
   /* texture */
   if (color_type == GPENCIL_COLOR_TEXTURE) {
-    fragColor = text_color;
+    if (mix_stroke_factor > 0.0) {
+      fragColor.rgb = mix(text_color.rgb, colormix.rgb, mix_stroke_factor);
+      fragColor.a = text_color.a;
+    }
+    else {
+      fragColor = text_color;
+    }
+
     /* mult both alpha factor to use strength factor */
     fragColor.a = min(fragColor.a * tColor.a, fragColor.a);
   }
index 2caaf7f..8110b1f 100644 (file)
@@ -447,7 +447,7 @@ static void gp_draw_stroke_fill(bGPdata *gpd,
   immUniform2fv("texture_scale", gp_style->texture_scale);
   immUniform2fv("texture_offset", gp_style->texture_offset);
   immUniform1f("texture_opacity", gp_style->texture_opacity);
-  immUniform1i("t_mix", (gp_style->flag & GP_STYLE_COLOR_TEX_MIX) != 0);
+  immUniform1i("t_mix", (gp_style->flag & GP_STYLE_FILL_TEX_MIX) != 0);
   immUniform1i("t_flip", (gp_style->flag & GP_STYLE_COLOR_FLIP_FILL) != 0);
 #if 0 /* GPXX disabled, not used in annotations */
   /* image texture */
index 882653a..02f8245 100644 (file)
@@ -96,7 +96,9 @@ typedef struct MaterialGPencilStyle {
 
   /** Type of gradient. */
   int gradient_type;
-  char _pad[4];
+
+  /** Factor used to mix texture and stroke color. */
+  float mix_stroke_factor;
 } MaterialGPencilStyle;
 
 /* MaterialGPencilStyle->flag */
@@ -111,8 +113,8 @@ typedef enum eMaterialGPencilStyle_Flag {
   GP_STYLE_COLOR_ONIONSKIN = (1 << 3),
   /* clamp texture */
   GP_STYLE_COLOR_TEX_CLAMP = (1 << 4),
-  /* mix texture */
-  GP_STYLE_COLOR_TEX_MIX = (1 << 5),
+  /* mix fill texture */
+  GP_STYLE_FILL_TEX_MIX = (1 << 5),
   /* Flip fill colors */
   GP_STYLE_COLOR_FLIP_FILL = (1 << 6),
   /* Stroke Texture is a pattern */
@@ -123,6 +125,8 @@ typedef enum eMaterialGPencilStyle_Flag {
   GP_STYLE_FILL_SHOW = (1 << 9),
   /* Don't rotate dots/boxes */
   GP_STYLE_COLOR_LOCK_DOTS = (1 << 10),
+  /* mix stroke texture */
+  GP_STYLE_STROKE_TEX_MIX = (1 << 11),
 } eMaterialGPencilStyle_Flag;
 
 typedef enum eMaterialGPencilStyle_Mode {
index 8fb26e4..d986f47 100644 (file)
@@ -475,6 +475,13 @@ static void rna_def_material_greasepencil(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "Mix", "Mix Adjustment Factor");
   RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
 
+  /* Stroke Mix factor */
+  prop = RNA_def_property(srna, "mix_stroke_factor", PROP_FLOAT, PROP_NONE);
+  RNA_def_property_float_sdna(prop, NULL, "mix_stroke_factor");
+  RNA_def_property_range(prop, 0.0f, 1.0f);
+  RNA_def_property_ui_text(prop, "Mix", "Mix Stroke Color");
+  RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
+
   /* Scale factor for uv coordinates */
   prop = RNA_def_property(srna, "pattern_scale", PROP_FLOAT, PROP_COORDS);
   RNA_def_property_float_sdna(prop, NULL, "gradient_scale");
@@ -569,9 +576,14 @@ static void rna_def_material_greasepencil(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "Clamp", "Do not repeat texture and clamp to one instance only");
   RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
 
-  prop = RNA_def_property(srna, "texture_mix", PROP_BOOLEAN, PROP_NONE);
-  RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_COLOR_TEX_MIX);
-  RNA_def_property_ui_text(prop, "Mix Texture", "Mix texture image with filling colors");
+  prop = RNA_def_property(srna, "use_fill_texture_mix", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_FILL_TEX_MIX);
+  RNA_def_property_ui_text(prop, "Mix Texture", "Mix texture image with filling color");
+  RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
+
+  prop = RNA_def_property(srna, "use_stroke_texture_mix", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_STROKE_TEX_MIX);
+  RNA_def_property_ui_text(prop, "Mix Texture", "Mix texture image with stroke color");
   RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
 
   prop = RNA_def_property(srna, "flip", PROP_BOOLEAN, PROP_NONE);