diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2020-02-11 17:18:19 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2020-02-11 17:18:19 +0300 |
commit | 8b6ecdb77f697a4897be2bfd0d5aef8730df3ebc (patch) | |
tree | 468652724a24dc8716cee8ec340b668333aa2978 | |
parent | 8f3e4c8625fbd67d2162b180dd9f6e4dd16940b0 (diff) |
GPencil: Implement Stroke Hardeness
Still pending the aspect ratio
8 files changed, 35 insertions, 12 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 36101e3a3bf..0e13387a1ca 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1491,10 +1491,10 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): ma = brush.gpencil_settings.material col.separator() + col.prop(gp_settings, "gradient_factor", slider=True) subcol = col.column(align=True) if ma and ma.grease_pencil.mode == 'LINE': subcol.enabled = False - subcol.prop(gp_settings, "gradient_factor", slider=True) subcol.prop(gp_settings, "gradient_shape") elif brush.gpencil_tool == 'FILL': 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 17986db54f7..80e3df699f8 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl @@ -151,10 +151,13 @@ flat IN_OUT vec2 strokePt1; flat IN_OUT vec2 strokePt2; flat IN_OUT int matFlag; flat IN_OUT float depth; +noperspective IN_OUT float strokeHardeness; #ifdef GPU_FRAGMENT_SHADER -float stroke_round_cap_mask(vec2 p1, vec2 p2, float thickness) +# define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0, 1.0)) + +float stroke_round_cap_mask(vec2 p1, vec2 p2, float thickness, float hardfac) { /* We create our own uv space to avoid issues with triangulation and linear * interpolation artifacts. */ @@ -171,7 +174,11 @@ float stroke_round_cap_mask(vec2 p1, vec2 p2, float thickness) /* Divide by stroke radius. */ uv_end /= thickness; - return (dot(uv_end, uv_end) > 0.25) ? 0.0 : 1.0; + float dist = clamp(1.0 - length(uv_end) * 2.0, 0.0, 1.0); + /* Modulate the falloff profile */ + float hardness = 1.0 - hardfac; + dist = pow(dist, mix(0.1, 10.0, hardness)); + return smoothstep(0.0, 1.0, dist); } #endif @@ -221,6 +228,11 @@ in vec4 col2; in vec4 fcol1; +in vec2 hard; +in vec2 hard1; +in vec2 hard2; +in vec2 hard3; + void discard_vert() { /* We set the vertex at the camera origin to generate 0 fragments. */ @@ -372,6 +384,7 @@ void stroke_vertex() thickness = stroke_thickness_modulate(thickness); finalUvs = vec2(x, y) * 0.5 + 0.5; + strokeHardeness = (use_curr) ? hard1.y : hard2.y; if (is_dot) { # ifdef GP_MATERIAL_BUFFER_LEN diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl index bca922ec018..43a9286f7d5 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl @@ -85,7 +85,7 @@ void main() fragColor.rgb *= gpencil_lighting(); - fragColor *= stroke_round_cap_mask(strokePt1, strokePt2, strokeThickness); + fragColor *= stroke_round_cap_mask(strokePt1, strokePt2, strokeThickness, strokeHardeness); /* For compatibility with colored alpha buffer. * Note that we are limited to mono-chromatic alpha blending here diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl b/source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl index fdbce27b38d..c8a0a9ac4b6 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl @@ -18,7 +18,7 @@ vec3 ray_plane_intersection(vec3 ray_ori, vec3 ray_dir, vec4 plane) void main() { #ifdef USE_GPENCIL - if (stroke_round_cap_mask(strokePt1, strokePt2, strokeThickness) < 0.001) { + if (stroke_round_cap_mask(strokePt1, strokePt2, strokeThickness, strokeHardeness) < 0.001) { discard; } diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c index e77026e850a..0c7c426f81e 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.c +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c @@ -182,6 +182,8 @@ typedef struct gpStrokeVert { /** Position and thickness packed in the same attribute. */ float pos[3], thickness; float uv_fill[2], u_stroke, v_rot; + /** Aspect ratio and hardnes. */ + float aspect_ratio, hardness; } gpStrokeVert; static GPUVertFormat *gpencil_stroke_format(void) @@ -191,6 +193,7 @@ static GPUVertFormat *gpencil_stroke_format(void) GPU_vertformat_attr_add(&format, "ma", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "hard", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* IMPORTANT: This means having only 4 attributes to fit into GPU module limit of 16 attrib. */ GPU_vertformat_multiload_enable(&format, 4); } @@ -289,6 +292,9 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts, vert->thickness = max_ff(0.0f, gps->thickness * pt->pressure) * (round_cap1 ? 1.0 : -1.0); /* Tag endpoint material to -1 so they get discarded by vertex shader. */ vert->mat = (is_endpoint) ? -1 : (gps->mat_nr % GP_MATERIAL_BUFFER_LEN); + + vert->aspect_ratio = gps->gradient_s[0] / max_ff(gps->gradient_s[1], 1e-8); + vert->hardness = gps->gradient_f; } static void gpencil_buffer_add_stroke(gpStrokeVert *verts, @@ -483,13 +489,17 @@ GPUBatch *DRW_cache_gpencil_face_wireframe_get(Object *ob) bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(Object *ob) { bGPdata *gpd = (bGPdata *)ob->data; + Brush *brush = gpd->runtime.sbuffer_brush; /* Convert the sbuffer to a bGPDstroke. */ if (gpd->runtime.sbuffer_gps == NULL) { bGPDstroke *gps = MEM_callocN(sizeof(*gps), "bGPDstroke sbuffer"); gps->totpoints = gpd->runtime.sbuffer_used; gps->mat_nr = max_ii(0, gpd->runtime.matid - 1); gps->flag = gpd->runtime.sbuffer_sflag; - gps->thickness = gpd->runtime.brush_size; + gps->thickness = brush->size; + gps->gradient_f = brush->gpencil_settings->gradient_f; + copy_v2_v2(gps->gradient_s, brush->gpencil_settings->gradient_s); + /* Reduce slightly the opacity of fill to make easy fill areas while drawing. */ gps->fill_opacity_fac = 0.8f; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index a395527c52d..1f3d165cb21 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1772,7 +1772,7 @@ static void gp_init_colors(tGPsdata *p) p->material = BKE_gpencil_object_material_ensure_from_active_input_brush(p->bmain, p->ob, brush); gpd->runtime.matid = BKE_object_material_slot_find_index(p->ob, p->material); - gpd->runtime.brush_size = brush->size; + gpd->runtime.sbuffer_brush = brush; } /* (re)init new painting data */ diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 19621a67d52..6f9f221a6e6 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -139,7 +139,7 @@ static void gp_init_colors(tGPDprimitive *p) p->mat = BKE_gpencil_object_material_ensure_from_active_input_brush(p->bmain, p->ob, brush); gpd->runtime.matid = BKE_object_material_slot_find_index(p->ob, p->mat); - gpd->runtime.brush_size = brush->size; + gpd->runtime.sbuffer_brush = brush; } /* Helper to square a primitive */ diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index 93612aa2309..58b42e5fc39 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -495,9 +495,6 @@ typedef struct bGPdata_Runtime { short layer_idx; /** Material index of the stroke. */ short matid; - /** Brush size of stroke. */ - float brush_size; - char _pad1[2]; /* Stroke Buffer data (only used during paint-session) * - buffer must be initialized before use, but freed after @@ -505,6 +502,7 @@ typedef struct bGPdata_Runtime { */ /** Flags for stroke that cache represents. */ short sbuffer_sflag; + char _pad1[2]; /** Number of elements currently used in cache. */ int sbuffer_used; /** Number of total elements available in cache. */ @@ -518,9 +516,11 @@ typedef struct bGPdata_Runtime { /** Number of control-points for stroke. */ int tot_cp_points; + char _pad2[4]; /** Array of control-points for stroke. */ bGPDcontrolpoint *cp_points; - /** Runtime grease pencil drawing data */ + /** Brush pointer */ + Brush *sbuffer_brush; struct GpencilBatchCache *gpencil_cache; } bGPdata_Runtime; |