|
|
|
@ -105,43 +105,32 @@ const sdf_vs_src = `#version 300 es
@@ -105,43 +105,32 @@ const sdf_vs_src = `#version 300 es
|
|
|
|
|
in vec2 a_a; // point from
|
|
|
|
|
in vec2 a_b; // point to
|
|
|
|
|
in int a_stroke_id; |
|
|
|
|
|
|
|
|
|
in vec2 a_pressure; |
|
|
|
|
|
|
|
|
|
uniform vec2 u_scale; |
|
|
|
|
uniform vec2 u_res; |
|
|
|
|
uniform vec2 u_translation; |
|
|
|
|
uniform int u_stroke_count; |
|
|
|
|
uniform int u_stroke_texture_size; |
|
|
|
|
|
|
|
|
|
uniform highp usampler2D u_stroke_data; |
|
|
|
|
|
|
|
|
|
out vec4 v_line; |
|
|
|
|
out vec2 v_texcoord; |
|
|
|
|
out vec3 v_color; |
|
|
|
|
|
|
|
|
|
flat out vec2 v_thickness; |
|
|
|
|
|
|
|
|
|
void main() { |
|
|
|
|
vec2 screen02; |
|
|
|
|
float apron = 1.0; // google "futanari inflation rule 34"
|
|
|
|
|
|
|
|
|
|
int stroke_data_y = a_stroke_id / u_stroke_texture_size; |
|
|
|
|
int stroke_data_x = a_stroke_id % u_stroke_texture_size; |
|
|
|
|
|
|
|
|
|
uvec4 stroke_data = texelFetch(u_stroke_data, ivec2(stroke_data_x, stroke_data_y), 0); |
|
|
|
|
float radius = float(stroke_data.w); |
|
|
|
|
|
|
|
|
|
vec2 line_dir = normalize(a_b - a_a); |
|
|
|
|
vec2 up_dir = vec2(line_dir.y, -line_dir.x); |
|
|
|
|
vec2 pixel = vec2(2.0) / u_res * apron; |
|
|
|
|
float rscale = apron / u_scale.x; |
|
|
|
|
|
|
|
|
|
int vertex_index = gl_VertexID % 6; |
|
|
|
|
|
|
|
|
|
vec2 outwards; |
|
|
|
|
vec2 origin; |
|
|
|
|
|
|
|
|
|
if (vertex_index == 0) { |
|
|
|
|
// "top left" aka "p1"
|
|
|
|
|
origin = a_a; |
|
|
|
@ -163,17 +152,13 @@ const sdf_vs_src = `#version 300 es
@@ -163,17 +152,13 @@ const sdf_vs_src = `#version 300 es
|
|
|
|
|
vec2 pos = origin + normalize(outwards) * radius * 2.0 * max(a_pressure.x, a_pressure.y); // doubling is to account for max possible pressure
|
|
|
|
|
screen02 = (pos.xy * u_scale + u_translation) / u_res * 2.0 + outwards * pixel; |
|
|
|
|
v_texcoord = pos.xy + outwards * rscale; |
|
|
|
|
|
|
|
|
|
screen02.y = 2.0 - screen02.y; |
|
|
|
|
|
|
|
|
|
v_line = vec4(a_a, a_b); |
|
|
|
|
v_thickness = radius * a_pressure; // pressure 0.5 is the "neutral" pressure
|
|
|
|
|
v_color = vec3(stroke_data.xyz) / 255.0; |
|
|
|
|
|
|
|
|
|
if (a_stroke_id >> 31 != 0) { |
|
|
|
|
screen02 += vec2(100.0); // shift offscreen
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gl_Position = vec4(screen02 - 1.0, (float(a_stroke_id) / float(u_stroke_count)) * 2.0 - 1.0, 1.0); |
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
@ -212,7 +197,6 @@ const sdf_fs_src = `#version 300 es
@@ -212,7 +197,6 @@ const sdf_fs_src = `#version 300 es
|
|
|
|
|
|
|
|
|
|
const tquad_vs_src = `#version 300 es
|
|
|
|
|
in vec2 a_pos; |
|
|
|
|
in vec2 a_texcoord; |
|
|
|
|
|
|
|
|
|
uniform vec2 u_scale; |
|
|
|
|
uniform vec2 u_res; |
|
|
|
@ -225,7 +209,19 @@ const tquad_vs_src = `#version 300 es
@@ -225,7 +209,19 @@ const tquad_vs_src = `#version 300 es
|
|
|
|
|
vec2 screen02 = screen01 * 2.0; |
|
|
|
|
screen02.y = 2.0 - screen02.y; |
|
|
|
|
vec2 screen11 = screen02 - 1.0; |
|
|
|
|
v_texcoord = a_texcoord; |
|
|
|
|
|
|
|
|
|
int vertex_index = gl_VertexID % 6; |
|
|
|
|
|
|
|
|
|
if (vertex_index == 0) { |
|
|
|
|
v_texcoord = vec2(0.0, 0.0); |
|
|
|
|
} else if (vertex_index == 1 || vertex_index == 5) { |
|
|
|
|
v_texcoord = vec2(1.0, 0.0); |
|
|
|
|
} else if (vertex_index == 2 || vertex_index == 4) { |
|
|
|
|
v_texcoord = vec2(0.0, 1.0); |
|
|
|
|
} else { |
|
|
|
|
v_texcoord = vec2(1.0, 1.0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gl_Position = vec4(screen11, 0, 1); |
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
@ -236,16 +232,11 @@ const tquad_fs_src = `#version 300 es
@@ -236,16 +232,11 @@ const tquad_fs_src = `#version 300 es
|
|
|
|
|
in vec2 v_texcoord; |
|
|
|
|
|
|
|
|
|
uniform sampler2D u_texture; |
|
|
|
|
uniform bool u_outline; |
|
|
|
|
|
|
|
|
|
layout(location = 0) out vec4 FragColor; |
|
|
|
|
|
|
|
|
|
void main() { |
|
|
|
|
if (!u_outline) { |
|
|
|
|
FragColor = texture(u_texture, v_texcoord); |
|
|
|
|
} else { |
|
|
|
|
FragColor = mix(texture(u_texture, v_texcoord), vec4(0.7, 0.7, 0.95, 1), 0.5); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
@ -407,6 +398,15 @@ function init_webgl(state, context) {
@@ -407,6 +398,15 @@ function init_webgl(state, context) {
|
|
|
|
|
'grid': create_program(gl, grid_vs, dots_fs), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.locations['image'] = { |
|
|
|
|
'a_pos': gl.getAttribLocation(context.programs['image'], 'a_pos'), |
|
|
|
|
|
|
|
|
|
'u_res': gl.getUniformLocation(context.programs['image'], 'u_res'), |
|
|
|
|
'u_scale': gl.getUniformLocation(context.programs['image'], 'u_scale'), |
|
|
|
|
'u_translation': gl.getUniformLocation(context.programs['image'], 'u_translation'), |
|
|
|
|
'u_texture': gl.getUniformLocation(context.programs['image'], 'u_texture'), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.locations['debug'] = { |
|
|
|
|
'a_pos': gl.getAttribLocation(context.programs['debug'], 'a_pos'), |
|
|
|
|
|
|
|
|
@ -468,6 +468,10 @@ function init_webgl(state, context) {
@@ -468,6 +468,10 @@ function init_webgl(state, context) {
|
|
|
|
|
'b_packed': gl.createBuffer(), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.buffers['image'] = { |
|
|
|
|
'b_quads': gl.createBuffer(), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.buffers['sdf'] = { |
|
|
|
|
'b_instance': gl.createBuffer(), |
|
|
|
|
'b_dynamic_instance': gl.createBuffer(), |
|
|
|
|