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 /source/blender/draw | |
parent | 8f3e4c8625fbd67d2162b180dd9f6e4dd16940b0 (diff) |
GPencil: Implement Stroke Hardeness
Still pending the aspect ratio
Diffstat (limited to 'source/blender/draw')
4 files changed, 28 insertions, 5 deletions
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; |