Browse Source

SSAO experiments (unfinihsed)

ssao
A.Olokhtonov 4 months ago
parent
commit
9892ebf33a
  1. 8
      client/aux.js
  2. 4
      client/bvh.js
  3. 1
      client/index.js
  4. 31
      client/webgl_draw.js
  5. 29
      client/webgl_shaders.js

8
client/aux.js

@ -265,3 +265,11 @@ function grid_snap_step(state) { @@ -265,3 +265,11 @@ function grid_snap_step(state) {
return 32 / zoom_next;
}
}
function canvas_css_rect(context) {
const el = context.canvas;
return {
'width': el.clientWidth,
'height': el.clientHeight
};
}

4
client/bvh.js

@ -220,8 +220,10 @@ function bvh_clip(state, context) { @@ -220,8 +220,10 @@ function bvh_clip(state, context) {
tv_clear(context.clipped_indices);
const canvas = canvas_css_rect(context);
const screen_topleft = screen_to_canvas(state, {'x': 0, 'y': 0});
const screen_bottomright = screen_to_canvas(state, {'x': context.canvas.width, 'y': context.canvas.height});
const screen_bottomright = screen_to_canvas(state, {'x': canvas.width, 'y': canvas.height});
const screen_topright = { 'x': screen_bottomright.x, 'y': screen_topleft.y };
const screen_bottomleft = { 'x': screen_topleft.x, 'y': screen_bottomright.y };

1
client/index.js

@ -31,6 +31,7 @@ const config = { @@ -31,6 +31,7 @@ const config = {
pattern_fadeout_min: 0.3,
pattern_fadeout_max: 0.75,
min_pressure: 50,
ssao: 0.5,
benchmark: {
zoom_level: -75,
offset: { x: 425, y: -1195 },

31
client/webgl_draw.js

@ -86,6 +86,8 @@ async function draw(state, context, animate, ts) { @@ -86,6 +86,8 @@ async function draw(state, context, animate, ts) {
const width = window.innerWidth;
const height = window.innerHeight;
const canvas = canvas_css_rect(context);
bvh_clip(state, context);
const segment_count = await geometry_write_instances(state, context);
@ -100,10 +102,10 @@ async function draw(state, context, animate, ts) { @@ -100,10 +102,10 @@ async function draw(state, context, animate, ts) {
}
// Only clear once we have the data, this might not always be on the same frame?
gl.viewport(0, 0, context.canvas.width, context.canvas.height);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(context.bgcolor.r, context.bgcolor.g, context.bgcolor.b, 1);
gl.clearDepth(0.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
// Draw the background pattern
if (state.background_pattern === 'dots') {
@ -116,7 +118,7 @@ async function draw(state, context, animate, ts) { @@ -116,7 +118,7 @@ async function draw(state, context, animate, ts) {
gl.vertexAttribPointer(locations['a_center'], 2, gl.FLOAT, false, 2 * 4, 0);
gl.vertexAttribDivisor(locations['a_center'], 1);
gl.uniform2f(locations['u_res'], context.canvas.width, context.canvas.height);
gl.uniform2f(locations['u_res'], canvas.width, canvas.height);
gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom);
gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y);
@ -124,11 +126,12 @@ async function draw(state, context, animate, ts) { @@ -124,11 +126,12 @@ async function draw(state, context, animate, ts) {
const zoom_log2 = Math.log2(zoom);
const zoom_previous = Math.pow(2, Math.floor(zoom_log2));
const zoom_next = Math.pow(2, Math.ceil(zoom_log2));
const grid_step = 32;
// Previous level
{
const one_dot = new Float32Array(geometry_gen_quad(0, 0, 1 / zoom_previous));
const dot_instances = new Float32Array(geometry_gen_fullscreen_grid(state, context, 32 / zoom_previous, 32 / zoom_previous));
const dot_instances = new Float32Array(geometry_gen_fullscreen_grid(state, context, grid_step / zoom_previous, grid_step / zoom_previous));
const t = Math.min(1.0, 1.0 - (zoom / zoom_previous) / 2.0);
gl.uniform1f(locations['u_fadeout'], t);
@ -141,7 +144,7 @@ async function draw(state, context, animate, ts) { @@ -141,7 +144,7 @@ async function draw(state, context, animate, ts) {
// Next level
if (zoom_previous != zoom_next) {
const dot_instances = new Float32Array(geometry_gen_fullscreen_grid(state, context, 32 / zoom_next, 32 / zoom_next));
const dot_instances = new Float32Array(geometry_gen_fullscreen_grid(state, context, grid_step / zoom_next, grid_step / zoom_next));
const t = Math.min(1.0, 1.0 - (zoom_next / zoom) / 2.0);
gl.uniform1f(locations['u_fadeout'], t);
@ -155,7 +158,7 @@ async function draw(state, context, animate, ts) { @@ -155,7 +158,7 @@ async function draw(state, context, animate, ts) {
const zoom = state.canvas.zoom;
let zoom_log8 = Math.log(zoom) / Math.log(8);
//if (zoom_log2 === Math.floor(zoom_log2)) {
//if (zoom_log2 === Math.floor(zoom_log2))
// zoom_log2 -= 0.001;
//}
@ -175,14 +178,14 @@ async function draw(state, context, animate, ts) { @@ -175,14 +178,14 @@ async function draw(state, context, animate, ts) {
gl.vertexAttribPointer(locations['a_data'], 2, gl.FLOAT, false, 2 * 4, 0);
gl.vertexAttribDivisor(locations['a_data'], 1);
gl.uniform2f(locations['u_res'], context.canvas.width, context.canvas.height);
gl.uniform2f(locations['u_res'], canvas.width, canvas.height);
gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom);
gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y);
gl.uniform1f(locations['u_fadeout'], 1.0);
// Previous level (major lines)
{
const grid_instances = new Float32Array(geometry_gen_fullscreen_grid_1d(state, context, 32 / zoom_previous, 32 / zoom_previous));
const grid_instances = new Float32Array(geometry_gen_fullscreen_grid_1d(state, context, grid_step / zoom_previous, grid_step / zoom_previous));
let t = (zoom / zoom_previous - 1) / -7 + 1;
t = 0.25;
@ -196,7 +199,7 @@ async function draw(state, context, animate, ts) { @@ -196,7 +199,7 @@ async function draw(state, context, animate, ts) {
// Next level (minor lines)
{
const grid_instances = new Float32Array(geometry_gen_fullscreen_grid_1d(state, context, 32 / zoom_next, 32 / zoom_next));
const grid_instances = new Float32Array(geometry_gen_fullscreen_grid_1d(state, context, grid_step / zoom_next, grid_step / zoom_next));
let t = (zoom_next / zoom - 1) / 7;
t = Math.min(0.1, -t + 1); // slight fade-in
@ -226,7 +229,7 @@ async function draw(state, context, animate, ts) { @@ -226,7 +229,7 @@ async function draw(state, context, animate, ts) {
gl.vertexAttribPointer(locations['a_pos'], 2, gl.FLOAT, false, 2 * 4, 0);
for (const entry of context.images) {
gl.uniform2f(locations['u_res'], context.canvas.width, context.canvas.height);
gl.uniform2f(locations['u_res'], canvas.width, canvas.height);
gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom);
gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y);
gl.uniform1i(locations['u_texture'], 0); // Only 1 active texture for each drawcall
@ -266,7 +269,7 @@ async function draw(state, context, animate, ts) { @@ -266,7 +269,7 @@ async function draw(state, context, animate, ts) {
gl.bindTexture(gl.TEXTURE_2D, context.textures['stroke_data']);
upload_square_rgba16ui_texture(gl, context.stroke_data, config.stroke_texture_size);
gl.uniform2f(locations['u_res'], context.canvas.width, context.canvas.height);
gl.uniform2f(locations['u_res'], canvas.width, canvas.height);
gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom);
gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y);
gl.uniform1i(locations['u_stroke_count'], state.events.length);
@ -274,6 +277,7 @@ async function draw(state, context, animate, ts) { @@ -274,6 +277,7 @@ async function draw(state, context, animate, ts) {
gl.uniform1i(locations['u_stroke_data'], 0);
gl.uniform1i(locations['u_stroke_texture_size'], config.stroke_texture_size);
gl.uniform1f(locations['u_fixed_pixel_width'], 0);
gl.uniform2f(locations['u_ssao'], config.ssao, config.ssao);
gl.enableVertexAttribArray(locations['a_a']);
gl.enableVertexAttribArray(locations['a_b']);
@ -326,7 +330,7 @@ async function draw(state, context, animate, ts) { @@ -326,7 +330,7 @@ async function draw(state, context, animate, ts) {
gl.bindTexture(gl.TEXTURE_2D, context.textures['dynamic_stroke_data']);
upload_square_rgba16ui_texture(gl, context.dynamic_stroke_data, config.dynamic_stroke_texture_size);
gl.uniform2f(locations['u_res'], context.canvas.width, context.canvas.height);
gl.uniform2f(locations['u_res'], canvas.width, canvas.height);
gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom);
gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y);
@ -335,6 +339,7 @@ async function draw(state, context, animate, ts) { @@ -335,6 +339,7 @@ async function draw(state, context, animate, ts) {
gl.uniform1i(locations['u_stroke_data'], 0);
gl.uniform1i(locations['u_stroke_texture_size'], config.dynamic_stroke_texture_size);
gl.uniform1f(locations['u_fixed_pixel_width'], 0);
gl.uniform2f(locations['u_ssao'], config.ssao, config.ssao);
gl.enableVertexAttribArray(locations['a_a']);
gl.enableVertexAttribArray(locations['a_b']);
@ -374,7 +379,7 @@ async function draw(state, context, animate, ts) { @@ -374,7 +379,7 @@ async function draw(state, context, animate, ts) {
gl.bindTexture(gl.TEXTURE_2D, context.textures['ui']);
upload_square_rgba16ui_texture(gl, handles.stroke_data, config.ui_texture_size);
gl.uniform2f(locations['u_res'], context.canvas.width, context.canvas.height);
gl.uniform2f(locations['u_res'], canvas.width, canvas.height);
gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom);
gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y);
gl.uniform1i(locations['u_stroke_count'], 8);

29
client/webgl_shaders.js

@ -12,6 +12,7 @@ const sdf_vs_src = `#version 300 es @@ -12,6 +12,7 @@ const sdf_vs_src = `#version 300 es
uniform int u_stroke_texture_size;
uniform highp usampler2D u_stroke_data;
uniform float u_fixed_pixel_width;
uniform vec2 u_ssao;
out vec4 v_line;
out vec2 v_texcoord;
@ -62,8 +63,9 @@ const sdf_vs_src = `#version 300 es @@ -62,8 +63,9 @@ 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 * apron;
v_texcoord = pos.xy + outwards * rscale;
screen02 = (pos.xy * u_scale + u_translation) / u_res * u_ssao * 2.0 + outwards * pixel * apron;
v_texcoord = pos.xy;
// 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
@ -97,10 +99,20 @@ const sdf_fs_src = `#version 300 es @@ -97,10 +99,20 @@ const sdf_fs_src = `#version 300 es
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
float dist = length(v_texcoord - (a + ba * h)) - mix(v_thickness.x, v_thickness.y, h);
/*
float fade = 0.5 * length(fwidth(v_texcoord));
float alpha = 1.0 - smoothstep(-fade, fade, dist);
*/
FragColor = vec4(v_color * alpha, alpha);
float alpha = 1.0 - step(0.0, dist);
alpha = clamp(0.0, 1.0, alpha);
if (alpha == 0.0) {
discard;
} else {
alpha = 0.5;
FragColor = vec4(v_color * alpha, alpha);
}
} else {
FragColor = vec4(0.2, 0.0, 0.0, 0.2);
}
@ -273,7 +285,7 @@ function init_webgl(state, context) { @@ -273,7 +285,7 @@ function init_webgl(state, context) {
context.gl = context.canvas.getContext('webgl2', {
'preserveDrawingBuffer': true,
'desynchronized': true,
'antialias': false,
'antialias': true,
});
const gl = context.gl;
@ -282,7 +294,7 @@ function init_webgl(state, context) { @@ -282,7 +294,7 @@ function init_webgl(state, context) {
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.GEQUAL);
gl.depthFunc(gl.NOTEQUAL);
context.gpu_timer_ext = gl.getExtension('EXT_disjoint_timer_query_webgl2');
if (context.gpu_timer_ext === null) {
@ -334,7 +346,8 @@ function init_webgl(state, context) { @@ -334,7 +346,8 @@ function init_webgl(state, context) {
'u_stroke_count': gl.getUniformLocation(context.programs['sdf'].main, 'u_stroke_count'),
'u_stroke_data': gl.getUniformLocation(context.programs['sdf'].main, 'u_stroke_data'),
'u_stroke_texture_size': gl.getUniformLocation(context.programs['sdf'].main, 'u_stroke_texture_size'),
'u_fixed_pixel_width': gl.getUniformLocation(context.programs['sdf'].main, 'u_fixed_pixel_width'),
'u_fixed_pixel_width': gl.getUniformLocation(context.programs['sdf'].main, 'u_fixed_pixel_width'),
'u_ssao': gl.getUniformLocation(context.programs['sdf'].main, 'u_ssao'),
}
};
@ -411,8 +424,8 @@ function init_webgl(state, context) { @@ -411,8 +424,8 @@ function init_webgl(state, context) {
height = Math.round(entry.contentBoxSize[0].blockSize * devicePixelRatio);
}
context.canvas.width = width;
context.canvas.height = height;
context.canvas.width = width * config.ssao;
context.canvas.height = height * config.ssao;
schedule_draw(state, context);
}

Loading…
Cancel
Save