I am trying to do picking in WebGl. I have two shapes rendered along with different texture mapped on each. I am trying to grab pixel on certain co-ordinates. Here is the example.
var pixelValues = new Uint8Array(4);
gl.readPixels(10, 35, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixelValues);
console.log(pixelValues);
But pixelValues always contain [0,0,0,0]. What am I doing wrong? Do I need to do something related to framebuffer?
According to WebGL latest specs, you now need to call
getContext
setting thepreserveDrawingBuffer
flag, like:this prevents the drawing buffer (color, depth, stencil) from being cleared after they are draw to screen. Keep in mind that settings this may cause a performance penalty.
You don't need
preserveDrawingBuffer: true
to callreadPixels
. What you need is to callreadPixels
before exiting the current event.The spec says if you call any function that affects the canvas (gl.clear, gl.drawXXX) then the browser will clear the canvas after the next composite operation. When that composite operation happens is up to the browser. It could be after it processes several mouse events or keyboard events or click events. The order is undefined. What is defined is that it won't do it until the current event exits so
works where as
does not work
Note that since it's the composite operation (the browser actually drawing the canvas on the page with the rest of the HTML) that triggers the clear, if the canvas is not on the page then it's not composited and won't be cleared.
In other words the case that didn't work above does work here
Now, if you want to call
readPixels
in some other event, like when the user clicks an element, then you have at least 2 optionsSet
preserveDrawingBuffer: true
Render again in your event