[wip] testing divergence

main
Martin Fouilleul 4 years ago
parent b3ac14d019
commit 9e1d5b8729
  1. 113
      src/main.c
  2. 33
      src/shaders/blit_div_fragment.glsl
  3. 28
      src/shaders/divergence.glsl
  4. 26
      src/shaders/jacobi_step.glsl
  5. 33
      src/shaders/splat.glsl
  6. 22
      src/shaders/subtract_pressure.glsl

@ -16,6 +16,7 @@
#include"blit_vertex_shader.h"
#include"blit_fragment_shader.h"
#include"blit_div_fragment_shader.h"
#include"common_vertex_shader.h"
#include"advect_shader.h"
#include"divergence_shader.h"
@ -183,6 +184,7 @@ typedef struct splat_program
GLint radius;
GLint additive;
GLint blending;
GLint randomize;
} splat_program;
@ -201,7 +203,7 @@ multigrid_correct_program multigridCorrectProgram;
subtract_program subtractProgram;
splat_program splatProgram;
blit_program blitProgram;
blit_program blitDivProgram;
frame_buffer colorBuffer;
frame_buffer velocityBuffer;
@ -302,6 +304,7 @@ void init_splat(splat_program* program)
program->radius = glGetUniformLocation(program->prog, "radius");
program->additive = glGetUniformLocation(program->prog, "additive");
program->blending = glGetUniformLocation(program->prog, "blending");
program->randomize = glGetUniformLocation(program->prog, "randomize");
}
void init_blit(blit_program* program)
@ -313,6 +316,16 @@ void init_blit(blit_program* program)
program->tex = glGetUniformLocation(program->prog, "tex");
}
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->pos = glGetAttribLocation(program->prog, "pos");
program->mvp = glGetUniformLocation(program->prog, "mvp");
program->tex = glGetUniformLocation(program->prog, "tex");
}
GLuint create_texture(int width, int height, GLenum internalFormat, GLenum format, GLenum type, char* initData)
{
GLuint texture;
@ -396,8 +409,11 @@ void reset_texture(GLuint texture, float width, float height, char* initData)
glTexImage2D(GL_TEXTURE_2D, 0, TEX_INTERNAL_FORMAT, width, height, 0, TEX_FORMAT, TEX_TYPE, initData);
}
static bool resetCmd = false;
void reset()
{
resetCmd = true;
console_log_fmt("reset");
reset_texture(colorBuffer.textures[0], texWidth, texHeight, (char*)colorInitData);
@ -499,6 +515,7 @@ int init(float canvasSize)
init_subtract(&subtractProgram);
init_splat(&splatProgram);
init_blit(&blitProgram);
init_blit_div(&blitDivProgram);
// init frame buffers
console_log_fmt("create color buffer");
@ -546,10 +563,19 @@ int init(float canvasSize)
return(0);
}
void apply_splat(float splatPosX, float splatPosY, float splatVelX, float splatVelY, float r, float g, float b)
void apply_splat(float splatPosX, float splatPosY, float splatVelX, float splatVelY, float r, float g, float b, bool randomize)
{
glUseProgram(splatProgram.prog);
if(randomize)
{
glUniform1f(splatProgram.randomize, 1.);
}
else
{
glUniform1f(splatProgram.randomize, 0.);
}
// force
glBindFramebuffer(GL_FRAMEBUFFER, velocityBuffer.fbos[1]);
@ -686,6 +712,7 @@ void WAFNDraw()
frame_buffer_swap(&velocityBuffer);
//NOTE: apply force and dye
/*
if(mouseInput.down && (mouseInput.deltaX || mouseInput.deltaY))
{
float canvasWidth = canvas_width();
@ -703,21 +730,61 @@ void WAFNDraw()
float g = 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);
apply_splat(splatPosX, splatPosY, splatVelX, splatVelY, r, g, b, true);
mouseInput.deltaX = 0;
mouseInput.deltaY = 0;
}
*/
//DEBUG
//*
/*
if((int)(frameT*3/2.) % 9 == 0)
{
float dirX = 0.2*cosf(2*3.141516*frameT*7.26);
float dirY = 0.3+0.1*sinf(frameT);
apply_splat(0.5, 0.1, dirX, dirY, 1.5, 1., 0.1);
apply_splat(0.5, 0., dirX, dirY, 1.5, 1., 0.1);
}
//*/
static bool splatTrig = false;
static bool splat = false;
static float splatStart = 0;
static int splatDir = 0;
if(resetCmd)
{
splat = true;
splatStart = frameT;
}
if(splat)
{
if(frameT - splatStart >= 0.5)
{
splat = false;
splatDir++;
splatDir = splatDir % 3;
}
float dirX = 0;
float dirY = 0;
if(splatDir == 0)
{
dirX = 0;
dirY = 0.3;
}
if(splatDir == 1)
{
dirX = 0.3;
dirY = 0;
}
if(splatDir == 2)
{
dirX = 0.2121;
dirY = 0.2121;
}
apply_splat(0.5, 0.5, dirX, dirY, 1.5, 1., 0.1, false);
}
resetCmd = false;
//NOTE: compute divergence of advected velocity
glUseProgram(divProgram.prog);
@ -733,9 +800,9 @@ void WAFNDraw()
//NOTE: compute pressure
#if 0
#if 1
multigrid_clear(&pressureBuffer[0]);
multigrid_smooth(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, 500);
multigrid_smooth(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, 2000);
#else
//*
multigrid_clear(&pressureBuffer[0]);
@ -807,13 +874,12 @@ void WAFNDraw()
glUniform1f(advectProgram.delta, DELTA);
glUniform1f(advectProgram.dissipation, 0.5);
glUniform1f(advectProgram.dissipation, 0.3);
glDrawArrays(GL_TRIANGLES, 0, 6);
frame_buffer_swap(&colorBuffer);
//*
//NOTE: Blit color texture to screen
float displayMatrix[16] = {
@ -822,6 +888,7 @@ void WAFNDraw()
0, 0, 1, 0,
0, 0, 0, 1 };
/*
glViewport(0, 0, canvas_width(), canvas_height());
glUseProgram(blitProgram.prog);
@ -835,16 +902,30 @@ void WAFNDraw()
glDrawArrays(GL_TRIANGLES, 0, 6);
/*/
//NOTE: Blit velocity to screen
glViewport(0, 0, window_width(), window_height());
glUseProgram(blitProgram.prog);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//NOTE: recompute divergence of (corrected) velocity
glUseProgram(divProgram.prog);
glBindFramebuffer(GL_FRAMEBUFFER, divBuffer[0].fbos[1]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, velocityBuffer.textures[0]);
glUniform1i(blitProgram.tex, 0);
glUniform1i(divProgram.src, 0);
glUniformMatrix4fv(blitProgram.mvp, 1, GL_FALSE, displayMatrix);
glDrawArrays(GL_TRIANGLES, 0, 6);
frame_buffer_swap(&divBuffer[0]);
//NOTE: Blit divergence to screen
glViewport(0, 0, canvas_width(), canvas_height());
glUseProgram(blitDivProgram.prog);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, divBuffer[0].textures[0]);
glUniform1i(blitDivProgram.tex, 0);
glUniformMatrix4fv(blitDivProgram.mvp, 1, GL_FALSE, displayMatrix);
glDrawArrays(GL_TRIANGLES, 0, 6);
//*/

@ -0,0 +1,33 @@
#version 300 es
precision highp float;
precision highp sampler2D;
in vec2 texCoord;
out vec4 fragColor;
uniform sampler2D tex;
vec3 color_map(float v)
{
float logv = log(abs(v))/log(10.0);
float f = floor(logv + 7.0);
float i = floor(4.0*(logv + 7.0 - f));
if(f < 0.0) return vec3(0.0);
if(f < 1.0) return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i/4.0);
if(f < 2.0) return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i/4.0);
if(f < 3.0) return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i/4.0);
if(f < 4.0) return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i/4.0);
if(f < 5.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i/4.0);
if(f < 6.0) return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i/4.0);
if(f < 7.0) return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i/4.0);
if(f < 8.0) return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i/4.0);
return vec3(1.0);
}
void main()
{
float f = texture(tex, texCoord).x;
fragColor = vec4(color_map(f), 1.0);
}

@ -36,15 +36,25 @@ void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 vr = pixelCoord + ivec2(1, 0);
ivec2 vl = pixelCoord - ivec2(1, 0);
ivec2 vt = pixelCoord + ivec2(0, 1);
ivec2 vb = pixelCoord - ivec2(0, 1);
if( pixelCoord.x <= 0
|| pixelCoord.x >= textureSize(src, 0).x
|| pixelCoord.y <= 0
|| pixelCoord.y >= textureSize(src, 0).y)
{
fragColor = vec4(0, 0, 0, 1);
}
else
{
ivec2 vr = pixelCoord + ivec2(1, 0);
ivec2 vl = pixelCoord - ivec2(1, 0);
ivec2 vt = pixelCoord + ivec2(0, 1);
ivec2 vb = pixelCoord - ivec2(0, 1);
float r = ux(vr);
float l = ux(vl);
float t = uy(vt);
float b = uy(vb);
float r = ux(vr);
float l = ux(vl);
float t = uy(vt);
float b = uy(vb);
fragColor = vec4(-(r - l + t - b)/2., 0, 0, 1);
fragColor = vec4(-(r - l + t - b)/2., 0, 0, 1);
}
}

@ -37,14 +37,24 @@ void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 vr = pixelCoord + ivec2(1, 0);
ivec2 vl = pixelCoord - ivec2(1, 0);
ivec2 vt = pixelCoord + ivec2(0, 1);
ivec2 vb = pixelCoord - ivec2(0, 1);
if( pixelCoord.x <= 0
|| pixelCoord.x >= textureSize(xTex, 0).x
|| pixelCoord.y <= 0
|| pixelCoord.y >= textureSize(xTex, 0).y)
{
fragColor = vec4(0, 0, 0, 1);
}
else
{
ivec2 vr = pixelCoord + ivec2(1, 0);
ivec2 vl = pixelCoord - ivec2(1, 0);
ivec2 vt = pixelCoord + ivec2(0, 1);
ivec2 vb = pixelCoord - ivec2(0, 1);
float w = 0.8;
float standardJacobi = (x(vl) + x(vr) + x(vt) + x(vb) + b(pixelCoord))/4.;
float weightedJacobi = w*standardJacobi + (1.-w)*x(pixelCoord);
float w = 0.8;
float standardJacobi = (x(vl) + x(vr) + x(vt) + x(vb) + b(pixelCoord))/4.;
float weightedJacobi = w*standardJacobi + (1.-w)*x(pixelCoord);
fragColor = vec4(weightedJacobi, 0, 0, 1);
fragColor = vec4(weightedJacobi, 0, 0, 1);
}
}

@ -13,30 +13,35 @@ uniform float radius;
uniform float additive;
uniform float blending;
uniform float randomize;
void main()
{
float d2 = dot(texCoord - splatPos, texCoord - splatPos);
float intensity = exp(-10.*d2/radius);
float n = 119.*gl_FragCoord.x + 107.*gl_FragCoord.y + 113.;
n = fract(n*fract(n/2.7182818));
intensity += intensity*abs(cos(2.*3.14159*n));
//NOTE: the force is added in the additive part.
vec2 force = splatColor.xy;
force.x += 0.2*sin(2.*3.14159*fract(n/1.144213));
force.y += 0.2*cos(2.*3.14159*fract(n/1.144213));
if(randomize != 0.0)
{
vec2 u = force/length(force);
float n = 119.*gl_FragCoord.x + 107.*gl_FragCoord.y + 113.;
n = fract(n*fract(n/2.7182818));
intensity += intensity*abs(cos(2.*3.14159*n));
//NOTE: the force is added in the additive part.
force.x += 0.2*sin(2.*3.14159*fract(n/1.144213));
force.y += 0.2*cos(2.*3.14159*fract(n/1.144213));
vec2 v = texCoord - splatPos;
vec2 norm = v - dot(v, u)*u;
float dFromAxis = length(norm);
{
vec2 u = force/length(force);
force += 30.*norm;
}
vec2 v = texCoord - splatPos;
vec2 norm = v - dot(v, u)*u;
float dFromAxis = length(norm);
force += 30.*norm;
}
}
vec3 u = texture(src, texCoord).xyz;
vec3 uAdd = u + intensity*vec3(force, 0);
vec3 uBlend = u*(1.-intensity) + intensity * splatColor;

@ -38,12 +38,22 @@ void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 vr = pixelCoord + ivec2(1, 0);
ivec2 vl = pixelCoord - ivec2(1, 0);
ivec2 vt = pixelCoord + ivec2(0, 1);
ivec2 vb = pixelCoord - ivec2(0, 1);
if( pixelCoord.x <= 0
|| pixelCoord.x >= textureSize(src, 0).x
|| pixelCoord.y <= 0
|| pixelCoord.y >= textureSize(src, 0).y)
{
fragColor = vec4(0, 0, 0, 1);
}
else
{
ivec2 vr = pixelCoord + ivec2(1, 0);
ivec2 vl = pixelCoord - ivec2(1, 0);
ivec2 vt = pixelCoord + ivec2(0, 1);
ivec2 vb = pixelCoord - ivec2(0, 1);
vec2 gradP = vec2(p(vr) - p(vl), p(vt) - p(vb))/2.;
vec2 gradP = vec2(p(vr) - p(vl), p(vt) - p(vb))/2.;
fragColor = vec4(u(pixelCoord) - gradP, 0, 1);
fragColor = vec4(u(pixelCoord) - gradP, 0, 1);
}
}

Loading…
Cancel
Save