Skip to content

Commit

Permalink
add stroke and glow
Browse files Browse the repository at this point in the history
  • Loading branch information
ffreyer committed Dec 28, 2023
1 parent c20300e commit 8400c90
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 5 deletions.
45 changes: 42 additions & 3 deletions WGLMakie/assets/sprites.frag
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ void fill(sampler2D image, vec4 fillcolor, vec2 uv, float infill, inout vec4 col
color = mix(color, im_color, infill);
}

void stroke(vec4 strokecolor, float signed_distance, float width, inout vec4 color){
if (width != 0.0){
float t = aastep(min(width, 0.0), max(width, 0.0), signed_distance);
vec4 bg_color = mix(color, vec4(strokecolor.rgb, 0), float(signed_distance < 0.5 * width));
color = mix(bg_color, strokecolor, t);
}
}

void glow(vec4 glowcolor, float signed_distance, float inside, inout vec4 color){
float glow_width = get_glowwidth();
float stroke_width = get_strokewidth();
if (glow_width > 0.0){
float outside = (abs(signed_distance) - stroke_width) / glow_width;
float alpha = 1.0 - outside;
color = mix(vec4(glowcolor.rgb, glowcolor.a*alpha), color, inside);
}
}

float scaled_distancefield(sampler2D distancefield, vec2 uv){
// Glyph distance field units are in pixels. Convert to same distance
Expand Down Expand Up @@ -94,19 +111,41 @@ void main() {
int shape = get_shape_type();
if(shape == CIRCLE)
signed_distance = circle(frag_uv);
else if(shape == DISTANCEFIELD)
else if(shape == DISTANCEFIELD) {
signed_distance = scaled_distancefield(distancefield, tex_uv);
else if(shape == ROUNDED_RECTANGLE)
if (get_strokewidth() > 0.0 || get_glowwidth() > 0.0) {
// Compensate for the clamping of tex_uv by an approximate
// extension of the signed distance outside the valid texture
// region.
vec2 bufuv = frag_uv - clamp(frag_uv, 0.0, 1.0);
signed_distance -= length(bufuv);
}
} else if(shape == ROUNDED_RECTANGLE)
signed_distance = rounded_rectangle(frag_uv, vec2(0.2), vec2(0.8));
else if(shape == RECTANGLE)
signed_distance = 1.0; // rectangle(f_uv);
else if(shape == TRIANGLE)
signed_distance = triangle(frag_uv);

signed_distance *= frag_uvscale;
float inside = aastep(0.0, signed_distance);


float stroke_width = get_strokewidth();
float inside_start = max(-stroke_width, 0.0);
float inside = aastep(inside_start, signed_distance);

vec4 final_color = vec4(frag_color.xyz, 0);
fill(image, frag_color, frag_uv, inside, final_color);
stroke(get_strokecolor(), signed_distance, -stroke_width, final_color);
glow(get_glowcolor(), signed_distance, aastep(-stroke_width, signed_distance), final_color);

// debug - show background
// final_color.a = clamp(final_color.a, 0.0, 1.0);
// final_color = vec4(
// vec3(1,0,0) * (1.0 - final_color.a) + final_color.rgb * final_color.a,
// 0.4 + 0.6 * final_color.a
// );

if (picking) {
if (final_color.a > 0.1) {
fragment_color = pack_int(object_id, frag_instance_id);
Expand Down
15 changes: 13 additions & 2 deletions WGLMakie/assets/sprites.vert
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,22 @@ void main(){
float sprite_from_u_scale = min(abs(get_markersize().x), abs(get_markersize().y));
frag_uvscale = viewport_from_sprite_scale * sprite_from_u_scale;
frag_distancefield_scale = distancefield_scale();

// add padding for AA, stroke and glow (non native distancefields don't need
// AA padding but CIRCLE etc do)
vec2 padded_bbox_size = bbox_radius + (
ANTIALIAS_RADIUS + max(0.0, get_strokewidth()) + max(0.0, get_glowwidth())
) / viewport_from_sprite_scale;
vec2 uv_pad_scale = padded_bbox_size / bbox_radius;

frag_color = tovec4(get_color());
frag_uv = get_uv();
frag_uv_offset_width = get_uv_offset_width();
// get_uv() returns (0, 0), (1, 0), (0, 1) or (1, 1)
// to accomodate stroke and glowwidth we need to extrude uv's outwards from (0.5, 0.5)
frag_uv = vec2(0.5) + (get_uv() - vec2(0.5)) * uv_pad_scale;

// screen space coordinates of the position
vec4 quad_vertex = (trans * vec4(2.0 * bbox_radius * get_position(), 0.0, 0.0));
vec4 quad_vertex = (trans * vec4(2.0 * padded_bbox_size * get_position(), 0.0, 0.0));
gl_Position = vclip + quad_vertex;
gl_Position.z += gl_Position.w * get_depth_shift();

Expand Down

0 comments on commit 8400c90

Please sign in to comment.