Skip to content

Commit

Permalink
add patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
ffreyer committed Jan 18, 2024
1 parent 1723364 commit 5e96d1e
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 19 deletions.
47 changes: 35 additions & 12 deletions GLMakie/assets/shader/lines.frag
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ in vec4 f_color;
in vec4 f_quad_sdf;
in vec2 f_joint_cutoff;
// in float f_line_width;
in float f_cumulative_length;
// in float f_cumulative_length;
in vec2 f_uv;
flat in vec4 f_pattern_overwrite;
flat in uvec2 f_id;

// in vec2 f_rect_sdf;
Expand All @@ -19,36 +21,51 @@ flat in uvec2 f_id;
// flat in float f_line_offset;

{{pattern_type}} pattern;

uniform float pattern_length;
uniform bool fxaa;

// Half width of antialiasing smoothstep
#define AA_THICKNESS 4
#define ANTIALIAS_RADIUS 0.8

float aastep(float threshold1, float dist) {
return smoothstep(threshold1-ANTIALIAS_RADIUS, threshold1+ANTIALIAS_RADIUS, dist);
}

// Pattern sampling
float get_pattern_sdf(sampler2D pattern, vec2 uv){
// make this texture repeating
// TODO
// vec2 uv2 = vec2((uv.x + f_line_offset) / pattern_length, 0.5 * uv.y / f_line_width);
return texture(pattern, uv).x;
float get_pattern_sdf(sampler2D pattern){
return texture(pattern, f_uv).x;
}
float get_pattern_sdf(sampler1D pattern, vec2 uv){
// make this texture repeating
return texture(pattern, uv.x / pattern_length).x;
float get_pattern_sdf(sampler1D pattern){
float sdf_offset, x;
if (f_uv.x <= f_pattern_overwrite.x) {
sdf_offset = max(f_pattern_overwrite.y * texture(pattern, f_pattern_overwrite.x).x, -AA_THICKNESS);
return f_pattern_overwrite.y * ( // +- pos ... 0
pattern_length * (f_pattern_overwrite.x - f_uv.x) + // pos ... 0
sdf_offset
);
// subtract at most AA_THICKNES
// if texture > -AA_THICKNESS start from there
// return f_pattern_overwrite.y * (pattern_length * (f_pattern_overwrite.x - f_uv.x) - AA_THICKNESS);
} else if (f_uv.x >= f_pattern_overwrite.z) {
sdf_offset = max(f_pattern_overwrite.w * texture(pattern, f_pattern_overwrite.z).x, -AA_THICKNESS);
return f_pattern_overwrite.w * ( // +- pos ... 0
pattern_length * (f_uv.x - f_pattern_overwrite.z) + // pos ... 0
sdf_offset
);
// return f_pattern_overwrite.w * (pattern_length * (f_uv.x - f_pattern_overwrite.z) - AA_THICKNESS);

} else
return texture(pattern, f_uv.x).x;
}
float get_pattern_sdf(Nothing _, vec2 uv){
float get_pattern_sdf(Nothing _){
return -10.0;
}

void write2framebuffer(vec4 color, uvec2 id);


#define DEBUG
// #define DEBUG

void main(){
// Metrics we need:
Expand All @@ -75,6 +92,8 @@ void main(){
// sdf = max(sdf, abs(f_quad_sdf.z) - f_line_width);
sdf = max(sdf, max(f_quad_sdf.z, f_quad_sdf.w));

sdf = max(sdf, get_pattern_sdf(pattern));

// draw
vec4 color = f_color;

Expand Down Expand Up @@ -144,6 +163,10 @@ void main(){
color.r += 0.3;
color.gb -= vec2(0.3);
}

// show pattern by reducing alpha heavily on off-parts
if (get_pattern_sdf(pattern) > 0)
color.a *= 0.2;
#endif


Expand Down
64 changes: 57 additions & 7 deletions GLMakie/assets/shader/lines.geom
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@ out vec4 f_color;
out vec4 f_quad_sdf; // smooth edges (along length and width)
out vec2 f_joint_cutoff; // hard edges (joint)
// out float f_line_width;
out float f_cumulative_length;
// out float f_cumulative_length;
out vec2 f_uv;
flat out vec4 f_pattern_overwrite;
flat out uvec2 f_id;

out vec3 o_view_pos;
out vec3 o_view_normal;

{{pattern_type}} pattern;
uniform float pattern_length;
uniform vec2 resolution;

// Constants
Expand Down Expand Up @@ -59,14 +63,57 @@ struct LineData {
bool is_start, is_end;
};

void process_pattern(Nothing pattern, LineData line) {
// do not adjust stuff
f_pattern_overwrite = vec4(1e5, 1.0, -1e5, 1.0);
}
void process_pattern(sampler2D pattern, LineData line) {
// TODO
// This is not a case that's used at all yet. Maybe consider it in the future...
f_pattern_overwrite = vec4(1e5, 1.0, -1e5, 1.0);
}

void process_pattern(sampler1D pattern, LineData line) {
float pattern_sample;

// line segment start
if (line.is_start) {
// get sample slightly further along
pattern_sample = texture(pattern, (g_lastlen[1] + AA_THICKNESS) / pattern_length).x;
// extend this value into the AA gap
f_pattern_overwrite.x = (g_lastlen[1] + AA_THICKNESS) / pattern_length;
f_pattern_overwrite.y = sign(pattern_sample);
} else {
// sample at "center" of corner/joint
pattern_sample = texture(pattern, g_lastlen[1] / pattern_length).x;
// overwrite until one AA gap past the corner/joint
f_pattern_overwrite.x = (g_lastlen[1] + abs(line.extrusion_a) + AA_THICKNESS) / pattern_length;
// using the sign of the sample to decide between drawing or not drawing
f_pattern_overwrite.y = sign(pattern_sample);
}

// and again for the end of the segment
if (line.is_end) {
pattern_sample = texture(pattern, (g_lastlen[2] - AA_THICKNESS) / pattern_length).x;
f_pattern_overwrite.z = (g_lastlen[2] - AA_THICKNESS) / pattern_length;
f_pattern_overwrite.w = sign(pattern_sample);
} else {
pattern_sample = texture(pattern, g_lastlen[2] / pattern_length).x;
f_pattern_overwrite.z = (g_lastlen[2] - abs(line.extrusion_b) - AA_THICKNESS) / pattern_length;
f_pattern_overwrite.w = sign(pattern_sample);
}
}

void emit_vertex(vec3 origin, vec2 center, LineData line, int index, vec2 geom_offset) {
vec3 position = origin + geom_offset.x * line.v + vec3(geom_offset.y * line.n, 0);

// sdf prototyping

// joint hard cutoff
// TODO Problem: this can cut the whole line even if the next segment does
// fill that space (due to being short for example)
// joint hard cutoff
// Options:
// - don't do this for truncated join -> overlap, need to clean extra corner generated by extrusion
// if line start/end move hard cutoff out so smooth rect cutoff can act
vec2 VP1 = position.xy - line.p1.xy;
vec2 VP2 = position.xy - line.p2.xy;
Expand Down Expand Up @@ -160,21 +207,24 @@ void emit_vertex(vec3 origin, vec2 center, LineData line, int index, vec2 geom_o
edge_normal = vec2(-edge_vector.y, edge_vector.x);
f_quad_sdf.w = dot(position.xy - corner1, -edge_normal);


// f_line_length = 0.5 * line.segment_length;
// f_line_width = 0.5 * g_thickness[index];
f_color = g_color[index];
gl_Position = vec4((2.0 * position.xy / resolution) - 1.0, position.z, 1.0);
f_id = g_id[index];
// f_line_offset = 0.5 * (g_lastlen[1] + g_lastlen[2]); // rect_sdf.x is centered
f_cumulative_length = g_lastlen[index]; // TODO
// TODO: pattern sampling
f_uv = vec2(
(g_lastlen[index] + geom_offset.x) / pattern_length,
0.5 + geom_offset.y / g_thickness[index]
);
EmitVertex();
}

void emit_quad(LineData line) {
vec2 center = 0.5 * (line.p1.xy + line.p2.xy);
float geom_linewidth = 0.5 * max(g_thickness[1], g_thickness[2]) + AA_THICKNESS;

// set up pattern overwrites at joints
process_pattern(pattern, line);

emit_vertex(line.p1, center, line, 1, vec2(- (abs(line.extrusion_a) + AA_THICKNESS), -geom_linewidth));
emit_vertex(line.p1, center, line, 1, vec2(- (abs(line.extrusion_a) + AA_THICKNESS), +geom_linewidth));
emit_vertex(line.p2, center, line, 2, vec2(+ (abs(line.extrusion_b) + AA_THICKNESS), -geom_linewidth));
Expand Down

0 comments on commit 5e96d1e

Please sign in to comment.