You can use gl.readPixels :
// Render your scene first then... var left = 0; var top = 0; var width = canvas.width; var height = canvas.height; var pixelData = new Uint8Array(width * height * 4); gl.readPixels(left, top, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
pixelData now contains scene pixel data as unsigned bytes (0-255) laid out as [R, G, B, A, R, G, B, A...] There should be the same data as getImageData , but with much lower cost.
[ EDIT: ]
I forgot to mention that if you are going to do this, you need to create your WebGL context using the preserveDrawingBuffer parameter, for example:
var gl = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});
This prevents WebGL from internally clearing the buffer before you reach it (which will result in a large number of empty pixels being read). Enabling this option may slow down the rendering, but it will still load faster than 5-8 FPS! :)
source share