Browse Source

Use straight up geometry for everything, finally obtaining TRANSPARENCY!

Freya 🙏 🙏 🙏
sdf
A.Olokhtonov 4 weeks ago
parent
commit
78ba044527
  1. 7
      client/webgl_draw.js
  2. 109
      client/webgl_shaders.js

7
client/webgl_draw.js

@ -320,7 +320,7 @@ async function draw(state, context, animate, ts) { @@ -320,7 +320,7 @@ async function draw(state, context, animate, ts) {
gl.vertexAttribDivisor(pr.locations['a_pressure'], 1);
// Static draw (everything already bound)
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, segment_count);
gl.drawArraysInstanced(gl.TRIANGLES, 0, 32 * 3 + 6 + 32 * 3, segment_count);
// I don't really know why I need to do this, but it
// makes background patter drawcall work properly
@ -391,7 +391,7 @@ async function draw(state, context, animate, ts) { @@ -391,7 +391,7 @@ async function draw(state, context, animate, ts) {
gl.vertexAttribDivisor(pr.locations['a_stroke_id'], 1);
gl.vertexAttribDivisor(pr.locations['a_pressure'], 1);
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, dynamic_segment_count);
gl.drawArraysInstanced(gl.TRIANGLES, 0, 32 * 3 + 6 + 32 * 3, dynamic_segment_count);
gl.vertexAttribDivisor(pr.locations['a_a'], 0);
gl.vertexAttribDivisor(pr.locations['a_b'], 0);
@ -438,8 +438,7 @@ async function draw(state, context, animate, ts) { @@ -438,8 +438,7 @@ async function draw(state, context, animate, ts) {
gl.vertexAttribDivisor(pr.locations['a_stroke_id'], 1);
gl.vertexAttribDivisor(pr.locations['a_pressure'], 1);
// Static draw (everything already bound)
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, ui_segments);
gl.drawArraysInstanced(gl.TRIANGLES, 0, 32 * 3 + 6 + 32 * 3, ui_segments);
// I don't really know why I need to do this, but it
// makes background patter drawcall work properly

109
client/webgl_shaders.js

@ -13,22 +13,19 @@ const sdf_vs_src = `#version 300 es @@ -13,22 +13,19 @@ const sdf_vs_src = `#version 300 es
uniform highp usampler2D u_stroke_data;
uniform float u_fixed_pixel_width;
out vec4 v_line;
out vec2 v_texcoord;
out vec3 v_color;
flat out vec2 v_thickness;
void main() {
const float PI = 3.1415926;
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;
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;
uvec4 stroke_data = texelFetch(u_stroke_data, ivec2(stroke_data_x, stroke_data_y), 0);
float radius = float(stroke_data.w);
@ -37,40 +34,65 @@ const sdf_vs_src = `#version 300 es @@ -37,40 +34,65 @@ const sdf_vs_src = `#version 300 es
radius = u_fixed_pixel_width / u_scale.x;
}
float rscale = apron / u_scale.x;
int vertex_index = gl_VertexID % 6;
int vertex_index = gl_VertexID % 198;
vec2 outwards;
vec2 origin;
vec2 pos;
if (vertex_index < 32 * 3) {
// first cap
float angle1 = float(vertex_index / 3) / 32.0 * PI * 2.0;
float angle2 = float((vertex_index + 1) / 3) / 32.0 * PI * 2.0;
vec2 dir1 = vec2(cos(angle1), sin(angle1));
vec2 dir2 = vec2(cos(angle2), sin(angle2));
if (vertex_index % 3 == 0) {
pos = a_a + dir1 * radius * a_pressure.x * 2.0;
} else if (vertex_index % 3 == 1) {
pos = a_a;
} else {
pos = a_a + dir2 * radius * a_pressure.x * 2.0;
}
} else if (vertex_index < 102) {
// connecting line
if (vertex_index == 96) {
// top left
pos = a_a + up_dir * radius * a_pressure.x * 2.0;
} else if (vertex_index == 97 || vertex_index == 101) {
// top right
pos = a_b + up_dir * radius * a_pressure.y * 2.0;
} else if (vertex_index == 98 || vertex_index == 100) {
// bottom left
pos = a_a - up_dir * radius * a_pressure.x * 2.0;
} else {
// bottom right
pos = a_b - up_dir * radius * a_pressure.y * 2.0;
}
if (vertex_index == 0) {
// "top left" aka "p1"
origin = a_a;
outwards = up_dir - line_dir;
} else if (vertex_index == 1 || vertex_index == 5) {
// "top right" aka "p2"
origin = a_b;
outwards = up_dir + line_dir;
} else if (vertex_index == 2 || vertex_index == 4) {
// "bottom left" aka "p3"
origin = a_a;
outwards = -up_dir - line_dir;
} else {
// "bottom right" aka "p4"
origin = a_b;
outwards = -up_dir + line_dir;
// second cap
float angle1 = float((vertex_index - 102) / 3) / 32.0 * PI * 2.0;
float angle2 = float((vertex_index - 101) / 3) / 32.0 * PI * 2.0;
vec2 dir1 = vec2(cos(angle1), sin(angle1));
vec2 dir2 = vec2(cos(angle2), sin(angle2));
if ((vertex_index - 102) % 3 == 0) {
pos = a_b + dir1 * radius * a_pressure.y * 2.0;
} else if ((vertex_index - 102) % 3 == 1) {
pos = a_a;
} else {
pos = a_b + dir2 * radius * a_pressure.y * 2.0;
}
}
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 * apron;
v_texcoord = pos.xy + outwards * rscale;
screen02 = (pos.xy * u_scale + u_translation) / u_res * 2.0;
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);
}
`;
@ -80,36 +102,13 @@ const sdf_fs_src = `#version 300 es @@ -80,36 +102,13 @@ const sdf_fs_src = `#version 300 es
uniform int u_debug_mode;
in vec4 v_line;
in vec2 v_texcoord;
in vec3 v_color;
flat in vec2 v_thickness;
layout(location = 0) out vec4 FragColor;
void main() {
if (u_debug_mode == 0) {
vec2 a = v_line.xy;
vec2 b = v_line.zw;
vec2 pa = v_texcoord - a.xy, ba = b.xy - a.xy;
float dba = dot(ba, ba);
float dist;
if (dba > 0.0) {
float h = clamp(dot(pa, ba) / dba, 0.0, 1.0);
dist = length(v_texcoord - (a + ba * h)) - mix(v_thickness.x, v_thickness.y, h);
} else {
// Special case for when we are drawing a single point. Just a circle SDF
dist = length(v_texcoord - a.xy - v_thickness.x);
}
float fade = 0.5 * length(fwidth(v_texcoord));
float alpha = 1.0 - smoothstep(-fade, fade, dist);
//if (alpha > 0.5) alpha = 0.5;
float alpha = 0.5;
FragColor = vec4(v_color * alpha, alpha);
} else {
FragColor = vec4(0.2, 0.0, 0.0, 0.2);
@ -340,7 +339,7 @@ function init_webgl(state, context) { @@ -340,7 +339,7 @@ function init_webgl(state, context) {
context.gl = context.canvas.getContext('webgl2', {
'preserveDrawingBuffer': true,
'desynchronized': true,
'antialias': false,
'antialias': true,
});
const gl = context.gl;
@ -349,8 +348,8 @@ function init_webgl(state, context) { @@ -349,8 +348,8 @@ function init_webgl(state, context) {
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
//gl.blendEquation(gl.MAX);
//gl.enable(gl.DEPTH_TEST);
//gl.depthFunc(gl.GEQUAL);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.NOTEQUAL);
context.gpu_timer_ext = gl.getExtension('EXT_disjoint_timer_query_webgl2');
if (context.gpu_timer_ext === null) {

Loading…
Cancel
Save