diff --git a/index.html b/index.html index 6220badfd7cf11ec71c21e5713a720e45cd3acab..567fe1e9cb09db47ca83a4772a89e54023a27f52 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,31 @@ } </script> + <script id="gradientSubtractionShader" type="x-shader/x-fragment"> + precision mediump float; + + uniform sampler2D u_velocity; + uniform sampler2D u_pressure; + + uniform vec2 u_textureSize; + + uniform float u_const; + + void main() { + + vec2 fragCoord = gl_FragCoord.xy; + + vec2 currentVelocity = texture2D(u_velocity, fragCoord/u_textureSize).xy; + + float n = texture2D(u_pressure, (fragCoord+vec2(0.0, 1.0))/u_textureSize).x; + float s = texture2D(u_pressure, (fragCoord+vec2(0.0, -1.0))/u_textureSize).x; + float e = texture2D(u_pressure, (fragCoord+vec2(1.0, 0.0))/u_textureSize).x; + float w = texture2D(u_pressure, (fragCoord+vec2(-1.0, 0.0))/u_textureSize).x; + + gl_FragColor = vec4(currentVelocity-u_const*vec2(e-w, n-s), 0, 0); + } + </script> + <script id="divergenceShader" type="x-shader/x-fragment"> precision mediump float; @@ -36,7 +61,7 @@ uniform vec2 u_textureSize; - uniform float u_halfReciprocalDx; + uniform float u_const; void main() { @@ -49,7 +74,8 @@ float e = texture2D(u_velocity, (fragCoord+vec2(1.0, 0.0))/u_textureSize).x; float w = texture2D(u_velocity, (fragCoord+vec2(-1.0, 0.0))/u_textureSize).x; - gl_FragColor = vec4(u_halfReciprocalDx*(e-w + n-s), 0, 0, 0); + float div = u_const*(e-w + n-s); + gl_FragColor = vec4(div, div, 0, 0); } </script> @@ -138,11 +164,16 @@ vec2 pxCenter = vec2(0.5, 0.5); vec2 pos = fragCoord - pxCenter - u_dt*currentVelocity; - if (pos.x < 0.0 || pos.x >= u_textureSize.x-1.0 || pos.y < 0.0 || pos.y >= u_textureSize.y-1.0){ - //boundary - gl_FragColor = vec4(0); - return; - } + //if (pos.x < 0.0 || pos.x >= u_textureSize.x-1.0 || pos.y < 0.0 || pos.y >= u_textureSize.y-1.0){ + // //boundary + // gl_FragColor = vec4(0); + // return; + //} + //periodic boundary + if (pos.x < 0.0) pos.x += u_textureSize.x-1.0; + if (pos.x >= u_textureSize.x-1.0) pos.x -= u_textureSize.x-1.0; + if (pos.y < 0.0) pos.y += u_textureSize.y-1.0; + if (pos.y >= u_textureSize.y-1.0) pos.y -= u_textureSize.y-1.0; //bilinear interp between nearest cells vec2 ceiled = ceil(pos); @@ -165,46 +196,6 @@ } </script> - <script id="2d-fragment-shader" type="x-shader/x-fragment"> - precision mediump float; - #define M_PI 3.1415926535897932384626433832795 - - //texture array - uniform sampler2D u_image;//u, v, --, -- = r, g, b, a - - uniform vec2 u_textureSize; - - uniform vec2 u_mouseCoord; - uniform float u_mouseEnable; - - const float dt = 1.0; - - void main() { - - vec2 fragCoord = gl_FragCoord.xy; - - vec2 currentState = texture2D(u_image, fragCoord/u_textureSize).xy; - float u = currentState.x; - float v = currentState.y; - - vec2 n = texture2D(u_image, (fragCoord + vec2(0.0, 1.0))/u_textureSize).xy;//north - vec2 s = texture2D(u_image, (fragCoord + vec2(0.0, -1.0))/u_textureSize).xy;//south - vec2 e = texture2D(u_image, (fragCoord + vec2(-1.0, 0.0))/u_textureSize).xy;//east - vec2 w = texture2D(u_image, (fragCoord + vec2(1.0, 0.0))/u_textureSize).xy;//west - - if (u_mouseEnable == 1.0){ - vec2 pxDistFromMouse = (fragCoord - u_mouseCoord)*(fragCoord - u_mouseCoord); - float tol = 10.0; - if (length(pxDistFromMouse)<tol){ - gl_FragColor = vec4(0.5, 0.35, 0, 1); - return; - } - } - - gl_FragColor = vec4(0,0, 0, 1); - } - </script> - <script type="text/javascript" src="dependencies/jquery-3.1.0.min.js"></script> <script type="text/javascript" src="dependencies/flat-ui.min.js"></script> diff --git a/main.js b/main.js index f19f6102c772075980ad41c86fad344ce8762db5..c44b0f58ec35261570c5723ca8c240ac98e58c94 100755 --- a/main.js +++ b/main.js @@ -11,6 +11,7 @@ var paused = false;//while window is resizing var dt = 1; var dx = 1; var nu = 1;//viscosity +var rho = 1;//density var GPU; @@ -46,9 +47,15 @@ function initGL() { GPU.setUniformForProgram("advect", "u_velocity", 0, "1i"); GPU.setUniformForProgram("advect", "u_material", 1, "1i"); + GPU.createProgram("gradientSubtraction", "2d-vertex-shader", "gradientSubtractionShader"); + GPU.setUniformForProgram("gradientSubtraction" ,"u_textureSize", [width, height], "2f"); + GPU.setUniformForProgram("gradientSubtraction", "u_const", 0.5/dx, "1f");//dt/(2*rho*dx) + GPU.setUniformForProgram("gradientSubtraction", "u_velocity", 0, "1i"); + GPU.setUniformForProgram("gradientSubtraction", "u_pressure", 1, "1i"); + GPU.createProgram("diverge", "2d-vertex-shader", "divergenceShader"); GPU.setUniformForProgram("diverge" ,"u_textureSize", [width, height], "2f"); - GPU.setUniformForProgram("diverge", "u_halfReciprocalDx", 1/(2*dx), "1f"); + GPU.setUniformForProgram("diverge", "u_const", 0.5/dx, "1f");//-2*dx*rho/dt GPU.setUniformForProgram("diverge", "u_velocity", 0, "1i"); GPU.createProgram("force", "2d-vertex-shader", "forceShader"); @@ -88,7 +95,11 @@ function render(){ GPU.step("advect", ["velocity", "velocity"], "nextVelocity");//advect velocity GPU.swapTextures("velocity", "nextVelocity"); - for (var i=0;i<1;i++){ + GPU.setProgram("jacobi"); + var alpha = dx*dx/(nu*dt); + GPU.setUniformForProgram("jacobi", "u_alpha", alpha, "1f"); + GPU.setUniformForProgram("jacobi", "u_reciprocalBeta", 1/(4+alpha), "1f"); + for (var i=0;i<3;i++){ GPU.step("jacobi", ["velocity", "velocity"], "nextVelocity");//diffuse velocity GPU.step("jacobi", ["nextVelocity", "nextVelocity"], "velocity");//diffuse velocity } @@ -104,18 +115,22 @@ function render(){ GPU.step("force", ["velocity"], "nextVelocity"); GPU.swapTextures("velocity", "nextVelocity"); - //compute pressure + // compute pressure GPU.step("diverge", ["velocity"], "velocityDivergence");//calc velocity divergence - for (var i=0;i<3;i++){ + GPU.setProgram("jacobi"); + GPU.setUniformForProgram("jacobi", "u_alpha", -dx*dx, "1f"); + GPU.setUniformForProgram("jacobi", "u_reciprocalBeta", 1/4, "1f"); + for (var i=0;i<20;i++){ GPU.step("jacobi", ["velocityDivergence", "pressure"], "nextPressure");//diffuse velocity GPU.step("jacobi", ["velocityDivergence", "nextPressure"], "pressure");//diffuse velocity } - //subtract pressure gradient + // subtract pressure gradient + GPU.step("gradientSubtraction", ["velocity", "pressure"], "nextVelocity"); + GPU.swapTextures("velocity", "nextVelocity"); // GPU.step("diffuse", ["material"], "nextMaterial"); GPU.step("advect", ["velocity", "material"], "nextMaterial"); - // GPU.step("force", ["material"], "nextMaterial"); GPU.step("render", ["nextMaterial"]); GPU.swapTextures("nextMaterial", "material"); @@ -144,6 +159,13 @@ function resetWindow(){ GPU.setSize(width, height); var velocity = new Float32Array(width*height*4); + // for (var i=0;i<height;i++){ + // for (var j=0;j<width;j++){ + // var index = 4*(i*width+j); + // velocity[index] = Math.sin(2*Math.PI*i/200)/10; + // velocity[index+1] = Math.sin(2*Math.PI*j/200)/10; + // } + // } GPU.initTextureFromData("velocity", width, height, "FLOAT", velocity, true); GPU.initFrameBufferForTexture("velocity"); GPU.initTextureFromData("nextVelocity", width, height, "FLOAT", new Float32Array(width*height*4), true); @@ -160,7 +182,8 @@ function resetWindow(){ for (var i=0;i<height;i++){ for (var j=0;j<width;j++){ var index = 4*(i*width+j); - material[index] = Math.random(); + if (((Math.floor(i/50))%2 && (Math.floor(j/50))%2) + || ((Math.floor(i/50))%2 == 0 && (Math.floor(j/50))%2 == 0)) material[index] = 1.0; } } GPU.initTextureFromData("material", width, height, "FLOAT", material, true);