diff --git a/index.html b/index.html index dad2cc89e4ef02fe19c6ac5c59ee59861a12a063..373a1194dea1b2c4c857ed475ea73345060c700d 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,36 @@ } </script> + <script id="forceShader" type="x-shader/x-fragment"> + precision mediump float; + + uniform sampler2D u_velocity; + + uniform vec2 u_textureSize; + + uniform vec2 u_mouseCoord; + uniform vec2 u_mouseDir; + uniform float u_mouseEnable; + + uniform float u_dt; + + const float reciprocalRadius = 0.01; + + void main() { + + vec2 fragCoord = gl_FragCoord.xy; + + vec2 currentVelocity = texture2D(u_velocity, fragCoord/u_textureSize).xy; + + if (u_mouseEnable == 1.0){ + vec2 pxDist = fragCoord - u_mouseCoord; + currentVelocity += u_mouseDir*u_dt*exp(-(pxDist.x*pxDist.x+pxDist.y*pxDist.y)*reciprocalRadius); + } + + gl_FragColor = vec4(currentVelocity, 0, 0); + } + </script> + <script id="diffuseShader" type="x-shader/x-fragment"> precision mediump float; @@ -77,7 +107,7 @@ //implicitly solve advection if (length(currentVelocity) == 0.0) {//no velocity - gl_FragColor = vec4(texture2D(u_material, fragCoord/u_textureSize).x, 0, 0, 0); + gl_FragColor = vec4(texture2D(u_material, fragCoord/u_textureSize).xy, 0, 0); return; } @@ -93,20 +123,20 @@ vec2 ceiled = ceil(pos); vec2 floored = floor(pos); - float n = texture2D(u_material, (ceiled+pxCenter)/u_textureSize).x;//actually ne - float s = texture2D(u_material, (floored+pxCenter)/u_textureSize).x;//actually sw + vec2 n = texture2D(u_material, (ceiled+pxCenter)/u_textureSize).xy;//actually ne + vec2 s = texture2D(u_material, (floored+pxCenter)/u_textureSize).xy;//actually sw if (ceiled.x != floored.x){ - float se = texture2D(u_material, (vec2(ceiled.x, floored.y)+pxCenter)/u_textureSize).x; - float nw = texture2D(u_material, (vec2(floored.x, ceiled.y)+pxCenter)/u_textureSize).x; + vec2 se = texture2D(u_material, (vec2(ceiled.x, floored.y)+pxCenter)/u_textureSize).xy; + vec2 nw = texture2D(u_material, (vec2(floored.x, ceiled.y)+pxCenter)/u_textureSize).xy; n = n*(pos.x-floored.x) + nw*(ceiled.x-pos.x); s = se*(pos.x-floored.x) + s*(ceiled.x-pos.x); } - float materialVal = n; + vec2 materialVal = n; if (ceiled.y != floored.y){ materialVal = n*(pos.y-floored.y) + s*(ceiled.y-pos.y); } - gl_FragColor = vec4(materialVal, 0, 0, 0); + gl_FragColor = vec4(materialVal, 0, 0); } </script> diff --git a/main.js b/main.js index 64768ac74522ad938cac24f56fe73f34cec8f889..bda07e28e2dbbf3417c3b6d9c313c97ed7997800 100755 --- a/main.js +++ b/main.js @@ -2,9 +2,8 @@ var width, height; -var mouseCoordLocation; -var mouseCoordinates = [null, null]; -var mouseEnableLocation; +var lastMouseCoordinates = [0,0]; +var mouseCoordinates = [0,0]; var mouseEnable = false; var paused = false;//while window is resizing @@ -47,6 +46,11 @@ function initGL() { GPU.setUniformForProgram("advect", "u_velocity", 0, "1i"); GPU.setUniformForProgram("advect", "u_material", 1, "1i"); + GPU.createProgram("force", "2d-vertex-shader", "forceShader"); + GPU.setUniformForProgram("force" ,"u_textureSize", [width, height], "2f"); + GPU.setUniformForProgram("force", "u_dt", dt, "1f"); + GPU.setUniformForProgram("force", "u_velocity", 0, "1i"); + GPU.createProgram("diffuse", "2d-vertex-shader", "diffuseShader"); GPU.setUniformForProgram("diffuse" ,"u_textureSize", [width, height], "2f"); var alpha = dx*dx/(nu*dt); @@ -68,11 +72,6 @@ function render(){ if (!paused) { - // if (mouseEnable){ - // gl.uniform1f(mouseEnableLocation, 1); - // gl.uniform2f(mouseCoordLocation, mouseCoordinates[0], mouseCoordinates[1]); - // } else gl.uniform1f(mouseEnableLocation, 0); - // Apply the first 3 operators in Equation 12. // u = advect(u); // u = diffuse(u); @@ -83,14 +82,26 @@ function render(){ GPU.step("advect", ["velocity", "velocity"], "nextVelocity");//advect velocity GPU.swapTextures("velocity", "nextVelocity"); - for (var i=0;i<10;i++){ + for (var i=0;i<1;i++){ GPU.step("diffuse", ["velocity"], "nextVelocity");//diffuse velocity GPU.step("diffuse", ["nextVelocity"], "velocity");//diffuse velocity } - + GPU.setProgram("force"); + if (mouseEnable){ + GPU.setUniformForProgram("force", "u_mouseEnable", 1.0, "1f"); + GPU.setUniformForProgram("force", "u_mouseCoord", [mouseCoordinates[0], mouseCoordinates[1]], "2f"); + GPU.setUniformForProgram("force", "u_mouseDir", [mouseCoordinates[0]-lastMouseCoordinates[0], + mouseCoordinates[1]-lastMouseCoordinates[1]], "2f"); + } else { + GPU.setUniformForProgram("force", "u_mouseEnable", 0.0, "1f"); + } + GPU.step("force", ["velocity"], "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"); @@ -122,11 +133,12 @@ function resetWindow(){ for (var i=0;i<height;i++){ for (var j=0;j<width;j++){ var index = 4*(i*width+j); - velocity[index] = i/1000; - velocity[index+1] = j/1000; + // velocity[index] = i/1000; + // velocity[index+1] = j/1000; } } GPU.initTextureFromData("velocity", width, height, "FLOAT", velocity, true); + GPU.initFrameBufferForTexture("velocity"); GPU.initTextureFromData("nextVelocity", width, height, "FLOAT", new Float32Array(width*height*4), true); GPU.initFrameBufferForTexture("nextVelocity"); var material = new Float32Array(width*height*4); @@ -145,13 +157,12 @@ function resetWindow(){ } function onMouseMove(e){ + lastMouseCoordinates = mouseCoordinates; mouseCoordinates = [e.clientX, height-e.clientY]; } -function onMouseDown(e){ - // gl.useProgram(stepProgram); +function onMouseDown(){ mouseEnable = true; - mouseCoordinates = [e.clientX, height-e.clientY]; } function onMouseUp(){