var canvas = document.createElement('canvas'), width = canvas.width = window.innerWidth, height = canvas.height = window.innerHeight, halfWidth = width/2, halfHeight = height/2, fov = 250; var context = canvas.getContext('2d'); document.body.appendChild(canvas); // set up an grid of 3D points that are laid // down horizontally on the floor var pixels = []; for(var x = -250; x<250; x+=5) { for(var z = -250; z<250; z+=5) { var pixel = {x:x, y:40, z:z}; pixels.push(pixel); } } // call the render function 30 times a second setInterval(render,1000/30); function render() { // clear the canvas context.clearRect(0,0,width, height); // and get the imagedata out of it var imagedata = context.getImageData(0, 0, canvas.width, canvas.height); // iterate through every point in the array var i=pixels.length; while(i--){ var pixel = pixels[i]; // here's the 3D to 2D formula, first work out // scale for that pixel's z position (distance from // camera) var scale = fov/(fov+pixel.z); // and multiply our 3D x and y to get our // 2D x and y. Add halfWidth and halfHeight // so that our 2D origin is in the middle of // the screen. var x2d = (pixel.x * scale) + halfWidth; var y2d = (pixel.y * scale) + halfHeight; // and set that 2D pixel to be green setPixel(imagedata, x2d, y2d, 0, 255, 60); // add 1 to the z position to bring it a little // closer to the camera each frame pixel.z-=1; // if it's now too close to the camera, // move it to the back if(pixel.z<-fov) pixel.z += (fov*2); } // and write all those pixel values into the canvas context.putImageData(imagedata,0,0); } function setPixel(imagedata, x, y, r, g, b) { if((x<0) || (x>width) || (y<0) || (y>width)) return; var i = ((y>>0) * imagedata.width + (x>>0)) * 4; imagedata.data[i] = r; imagedata.data[i+1] = g; imagedata.data[i+2] = b; imagedata.data[i+3] = 255; }
body { background:black; margin:0px; overflow:hidden; }