From a23167c57d38d885c8f953ec26c5eff395d07bc3 Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Tue, 15 Nov 2022 11:24:42 -0800 Subject: [PATCH] - changed splat to adapt to canvas - compare stencils script - blit divergence vertex shader --- compare_stencils.py | 106 +++++++++++++++++++++++++++++++ loader.js | 1 + src/main.c | 38 +++++++---- src/shaders/blit_div_vertex.glsl | 14 ++++ src/shaders/blit_vertex.glsl | 6 +- 5 files changed, 151 insertions(+), 14 deletions(-) create mode 100644 compare_stencils.py create mode 100644 src/shaders/blit_div_vertex.glsl diff --git a/compare_stencils.py b/compare_stencils.py new file mode 100644 index 0000000..c9b1339 --- /dev/null +++ b/compare_stencils.py @@ -0,0 +1,106 @@ + +from sympy import sqrt, symbols, factorial, IndexedBase, Symbol + +p = IndexedBase("p") +h = Symbol("h") + +def taylor(a, b, c): + n = 4 + derivatives = [0] * n + steps = [0] * n + + result = p + + for order in range(1, n+1): + for i in range(0, 3**order): + for j in range(0, order): + derivatives[j] = int((i / (3**(order-1-j))) % 3 + 1) + step = [a, b, c][derivatives[j] - 1] + steps[j] = step + + total_step = 1 + symbol_name = "" + for j in range(0, order): + total_step *= (steps[j] * h) + component = derivatives[j] - 1 + symbol_name += ["x", "y", "z"][component] + + result += (1 / factorial(order)) * total_step * Symbol(symbol_name) + return result; + +def expand_laplacian(face, corner): + # Note: Any linear combination of the face and corner coefficients will + # produce a valid discretized Laplacian, except for when normalization == 0 + center = face * 4 + corner * 4 + normalization = face + 2 * corner + + expr = ( + - center * taylor(0, 0, 0) + + + face * taylor( 1, 0, 0) + + face * taylor(-1, 0, 0) + + face * taylor( 0, -1, 0) + + face * taylor( 0, 1, 0) + + + corner * taylor( 1, 1, 0) + + corner * taylor( 1, -1, 0) + + corner * taylor(-1, 1, 0) + + corner * taylor(-1, -1, 0) + + ) / (normalization*h*h) + + print("Laplacian:") + print("\tCenter: {:+d}".format(-center)) + print("\tFace: {:+d}".format(face)) + print("\tCorner: {:+d}".format(corner)) + print("\tNormalization: {:+d}".format(normalization)) + print("\tExpansion: {}".format(expr.simplify())) + print() + + return expr + +#a = expand_laplacian(1, 0) +#b = expand_laplacian(0, 1) +#c = expand_laplacian(1, 1) +#d = expand_laplacian(2, 1) +#e = expand_laplacian(1, 2) + +expr_colocated = ( + -4*taylor(0, 0, 0) + +1*taylor(-2, 0, 0) + +1*taylor(+2, 0, 0) + +1*taylor(0, -2, 0) + +1*taylor(0, +2, 0) +) / (4*h*h) + +expr_wide = ( + -8*taylor(0, 0, 0) + +1*taylor(-1, 0, 0) + +1*taylor(+1, 0, 0) + +1*taylor(0, -1, 0) + +1*taylor(0, +1, 0) + +1*taylor(-1,-1, 0) + +1*taylor(+1,+1, 0) + +1*taylor(+1, -1, 0) + +1*taylor(-1, +1, 0) +) / (3*h*h) + +expr_vertex = ( + -4*taylor(0, 0, 0) + +1*taylor(-1,-1, 0) + +1*taylor(+1,+1, 0) + +1*taylor(+1, -1, 0) + +1*taylor(-1, +1, 0) +) / (2*h*h) + +expr_mac = ( + -4*taylor(0, 0, 0) + +1*taylor(-1, 0, 0) + +1*taylor(+1, 0, 0) + +1*taylor(0, -1, 0) + +1*taylor(0, +1, 0) +) / (h*h) + +print((expr_colocated - expr_mac).simplify()) +print((expr_colocated - expr_wide).simplify()) +print((expr_colocated - expr_vertex).simplify()) diff --git a/loader.js b/loader.js index c61ba7e..a9dc170 100644 --- a/loader.js +++ b/loader.js @@ -808,6 +808,7 @@ function GLBindImports(env) env.glUniform1f = function(loc, v0) { GLctx.uniform1f(GLuniforms[loc], v0); }; env.glUniform1i = function(loc, v0) { GLctx.uniform1i(GLuniforms[loc], v0); }; + env.glUniform2i = function(loc, v0, v1) { GLctx.uniform2i(GLuniforms[loc], v0, v1); }; env.glUniform2f = function(loc, v0, v1) { GLctx.uniform2f(GLuniforms[loc], v0, v1); }; env.glUniform3f = function(loc, v0, v1, v2) { GLctx.uniform3f(GLuniforms[loc], v0, v1, v2); }; diff --git a/src/main.c b/src/main.c index 38c1bf8..b750c9a 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ #include"blit_vertex_shader.h" #include"blit_fragment_shader.h" +#include"blit_div_vertex_shader.h" #include"blit_div_fragment_shader.h" #include"common_vertex_shader.h" #include"advect_shader.h" @@ -181,6 +182,7 @@ typedef struct blit_program GLint pos; GLint mvp; + GLint gridSize; GLint tex; } blit_program; @@ -326,12 +328,13 @@ void init_blit(blit_program* program) program->pos = glGetAttribLocation(program->prog, "pos"); program->mvp = glGetUniformLocation(program->prog, "mvp"); program->tex = glGetUniformLocation(program->prog, "tex"); + program->gridSize = glGetUniformLocation(program->prog, "gridSize"); } void init_blit_div(blit_program* program) { console_log_fmt("compiling blit div..."); - program->prog = compile_shader(blit_vertex_shader_src, blit_div_fragment_shader_src); + program->prog = compile_shader(blit_div_vertex_shader_src, blit_div_fragment_shader_src); program->pos = glGetAttribLocation(program->prog, "pos"); program->mvp = glGetUniformLocation(program->prog, "mvp"); program->tex = glGetUniformLocation(program->prog, "tex"); @@ -340,7 +343,7 @@ void init_blit_div(blit_program* program) void init_blit_residue(blit_residue_program* program) { console_log_fmt("compiling blit residue..."); - program->prog = compile_shader(blit_vertex_shader_src, blit_residue_fragment_shader_src); + program->prog = compile_shader(blit_div_vertex_shader_src, blit_residue_fragment_shader_src); program->pos = glGetAttribLocation(program->prog, "pos"); program->mvp = glGetUniformLocation(program->prog, "mvp"); program->xTex = glGetUniformLocation(program->prog, "xTex"); @@ -586,7 +589,7 @@ int init(float canvasSize) return(0); } -void apply_splat(float splatPosX, float splatPosY, float splatVelX, float splatVelY, float r, float g, float b, bool randomize) +void apply_splat(float splatPosX, float splatPosY, float radius, float splatVelX, float splatVelY, float r, float g, float b, bool randomize) { glUseProgram(splatProgram.prog); @@ -611,7 +614,7 @@ void apply_splat(float splatPosX, float splatPosY, float splatVelX, float splatV glUniform1f(splatProgram.additive, 1); glUniform1f(splatProgram.blending, 0); - glUniform1f(splatProgram.radius, 0.01); + glUniform1f(splatProgram.radius, radius); glDrawArrays(GL_TRIANGLES, 0, 6); @@ -628,7 +631,7 @@ void apply_splat(float splatPosX, float splatPosY, float splatVelX, float splatV glUniform3f(splatProgram.splatColor, r, g, b); glUniform1f(splatProgram.additive, 0); glUniform1f(splatProgram.blending, 1); - glUniform1f(splatProgram.radius, 0.01); + glUniform1f(splatProgram.radius, radius); glDrawArrays(GL_TRIANGLES, 0, 6); @@ -709,22 +712,29 @@ void input_splat(float t) //NOTE: apply force and dye if(mouseInput.down && (mouseInput.deltaX || mouseInput.deltaY)) { + // account for margin + float margin = 32; + float canvasWidth = canvas_width(); float canvasHeight = canvas_height(); + float offset = margin/texWidth; + float ratio = 1 - 2*margin/texWidth; - float splatPosX = mouseInput.x/canvasWidth; - float splatPosY = 1 - mouseInput.y/canvasHeight; + float splatPosX = (mouseInput.x/canvasWidth)*ratio + offset; + float splatPosY = (1 - mouseInput.y/canvasHeight)*ratio + offset; - float splatVelX = 10000.*DELTA*mouseInput.deltaX/canvasWidth; - float splatVelY = -10000.*DELTA*mouseInput.deltaY/canvasWidth; + float splatVelX = (10000.*DELTA*mouseInput.deltaX/canvasWidth)*ratio; + float splatVelY = (-10000.*DELTA*mouseInput.deltaY/canvasWidth)*ratio; - float intensity = 100*sqrtf(square(mouseInput.deltaX/canvasWidth) + square(mouseInput.deltaY/canvasHeight)); + float intensity = 100*sqrtf(square(ratio*mouseInput.deltaX/canvasWidth) + square(ratio*mouseInput.deltaY/canvasHeight)); float r = intensity * (sinf(2*PI*0.1*t) + 1); float g = 0.5*intensity * (cosf(2*PI*0.1/EULER*t + 654) + 1); float b = intensity * (sinf(2*PI*0.1/SQRT2*t + 937) + 1); - apply_splat(splatPosX, splatPosY, splatVelX, splatVelY, r, g, b, false); + float radius = 0.005; + + apply_splat(splatPosX, splatPosY, radius, splatVelX, splatVelY, r, g, b, false); mouseInput.deltaX = 0; mouseInput.deltaY = 0; @@ -838,7 +848,7 @@ void WAFNDraw() #else multigrid_clear(&pressureBuffer[0]); - for(int i=0; i<2; i++) + for(int i=0; i<1; i++) { jacobi_solve(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, 2); multigrid_coarsen_residual(&divBuffer[1], &pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE); @@ -848,7 +858,7 @@ void WAFNDraw() multigrid_coarsen_residual(&divBuffer[2], &pressureBuffer[1], &divBuffer[1], 2*INV_GRID_SIZE); multigrid_clear(&pressureBuffer[2]); - jacobi_solve(&pressureBuffer[2], &divBuffer[2], 4*INV_GRID_SIZE, 40); + jacobi_solve(&pressureBuffer[2], &divBuffer[2], 4*INV_GRID_SIZE, 30); multigrid_prolongate_and_correct(&pressureBuffer[1], &pressureBuffer[2], 2*INV_GRID_SIZE); jacobi_solve(&pressureBuffer[1], &divBuffer[1], 2*INV_GRID_SIZE, 8); @@ -934,6 +944,8 @@ void WAFNDraw() glBindTexture(GL_TEXTURE_2D, colorBuffer.textures[0]); glUniform1i(blitProgram.tex, 0); + glUniform2i(blitProgram.gridSize, texWidth, texHeight); + glUniformMatrix4fv(blitProgram.mvp, 1, GL_FALSE, displayMatrix); glDrawArrays(GL_TRIANGLES, 0, 6); diff --git a/src/shaders/blit_div_vertex.glsl b/src/shaders/blit_div_vertex.glsl new file mode 100644 index 0000000..f69dc76 --- /dev/null +++ b/src/shaders/blit_div_vertex.glsl @@ -0,0 +1,14 @@ +#version 300 es + +precision highp float; + +in vec2 pos; +out vec2 texCoord; + +uniform mat4 mvp; + +void main() +{ + texCoord = 0.5*(pos + vec2(1,1)); + gl_Position = mvp * vec4(pos, 0, 1); +} diff --git a/src/shaders/blit_vertex.glsl b/src/shaders/blit_vertex.glsl index f69dc76..d397a76 100644 --- a/src/shaders/blit_vertex.glsl +++ b/src/shaders/blit_vertex.glsl @@ -6,9 +6,13 @@ in vec2 pos; out vec2 texCoord; uniform mat4 mvp; +uniform ivec2 gridSize; void main() { - texCoord = 0.5*(pos + vec2(1,1)); + float margin = 32.; + float ratio = 1. - 2.*margin/float(gridSize.x); + + texCoord = margin/float(gridSize.x) + ratio*(0.5*(pos + vec2(1,1))); gl_Position = mvp * vec4(pos, 0, 1); }