diff --git a/index.html b/index.html
index 7dbadebb271d154fb924d6b9ce2d89184f5d7ebf..c40a3f661c4be19cfcc3172683827f458822674f 100644
--- a/index.html
+++ b/index.html
@@ -20,13 +20,12 @@
     <script id="2d-render-shader" type="x-shader/x-fragment">
         precision mediump float;
 
-        uniform sampler2D u_velocity;
+        uniform sampler2D u_material;
         uniform vec2 u_textureSize;
 
         void main() {
             vec2 fragCoord = gl_FragCoord.xy;
-            vec2 currentVelocity = texture2D(u_velocity, fragCoord/u_textureSize).xy;
-            gl_FragColor = vec4(currentVelocity.x/4.0, 0, 1, 1);
+            gl_FragColor = vec4(texture2D(u_material, fragCoord/u_textureSize).x, 0, 1, 1);
         }
     </script>
 
@@ -47,11 +46,38 @@
             vec2 currentVelocity = texture2D(u_velocity, fragCoord/u_textureSize).xy;
 
             //implicitly solve advection
-            vec2 pos = fragCoord - u_dt * currentVelocity;
 
-            // todo bilinear interp between nearest cells
-            gl_FragColor = texture2D(u_material, pos/u_textureSize);
-            gl_FragColor = vec4(1,1,1,1);
+            if (length(currentVelocity) == 0.0) {//no velocity
+                gl_FragColor = vec4(texture2D(u_material, fragCoord/u_textureSize).x, 0, 0, 0);
+                return;
+            }
+
+            vec2 pxCenter = vec2(0.5, 0.5);
+            vec2 pos = fragCoord - pxCenter - u_dt*currentVelocity;
+            if (pos.x < 0.0 || pos.x >= u_textureSize.x || pos.y < 0.0 || pos.y >= u_textureSize.y){
+                //boundary
+                gl_FragColor = vec4(0);
+                return;
+            }
+
+            //bilinear interp between nearest cells
+            vec2 ceiled = ceil(pos);
+            vec2 floored = floor(pos);
+
+            float n = texture2D(u_material, (ceiled+pxCenter)/u_textureSize).x;;
+            float s = texture2D(u_material, (floored+pxCenter)/u_textureSize).x;
+            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;
+                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;
+            if (ceiled.y != floored.y){
+                materialVal = n*(pos.y-floored.y) + s*(ceiled.y-pos.y);
+            }
+
+            gl_FragColor = vec4(materialVal, 0, 0, 0);
         }
     </script>
 
diff --git a/main.js b/main.js
index 5d6f13a63333b4f98d0da68d6c7f4bb79a40c2c0..61c5c964836c6a4637d8dc413cb654c296ec77b8 100755
--- a/main.js
+++ b/main.js
@@ -39,12 +39,13 @@ function initGL() {
     // setup a GLSL programs
     GPU.createProgram("advect", "2d-vertex-shader", "advectShader");
     GPU.setUniformForProgram("advect" ,"u_textureSize", [width, height], "2f");
+    GPU.setUniformForProgram("advect", "u_dt", 1.0, "1f");
     GPU.setUniformForProgram("advect", "u_velocity", 0, "1i");
     GPU.setUniformForProgram("advect", "u_material", 1, "1i");
 
     GPU.createProgram("render", "2d-vertex-shader", "2d-render-shader");
     GPU.setUniformForProgram("render" ,"u_textureSize", [width, height], "2f");
-    GPU.setUniformForProgram("render", "u_velocity", 0, "1i");
+    GPU.setUniformForProgram("render", "u_material", 0, "1i");
 
     resetWindow();
 
@@ -56,8 +57,6 @@ function render(){
 
     if (!paused) {
 
-
-
         // if (mouseEnable){
         //     gl.uniform1f(mouseEnableLocation, 1);
         //     gl.uniform2f(mouseCoordLocation, mouseCoordinates[0], mouseCoordinates[1]);
@@ -65,7 +64,9 @@ function render(){
 
         GPU.step("advect", ["velocity", "material"], "advectedMaterial");
 
-        GPU.step("render", ["velocity"]);
+        GPU.step("render", ["advectedMaterial"]);
+
+        GPU.swapTextures("advectedMaterial", "material");
 
     } else resetWindow();
 
@@ -84,10 +85,10 @@ function onResize(){
 }
 
 function resetWindow(){
-    canvas.width = canvas.clientWidth;
-    canvas.height = canvas.clientHeight;
-    width = canvas.clientWidth;
-    height = canvas.clientHeight;
+    // canvas.width = canvas.clientWidth;
+    // canvas.height = canvas.clientHeight;
+    // width = canvas.clientWidth;
+    // height = canvas.clientHeight;
 
     GPU.setSize(width, height);
 
@@ -100,6 +101,12 @@ function resetWindow(){
     }
     GPU.initTextureFromData("velocity", width, height, "FLOAT", velocity, true);
     var material = 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);
+            material[index] = Math.random();
+        }
+    }
     GPU.initTextureFromData("material", width, height, "FLOAT", material, true);
     GPU.initFrameBufferForTexture("material");
     GPU.initTextureFromData("advectedMaterial", width, height, "FLOAT", new Float32Array(width*height*4), true);