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(){