At the moment the Picking Module computes pick shader
colour for each object (node) thus:
color.g = parseFloat(Math.round((nodeIndex + 1) / 256) / 256);
color.r = parseFloat((nodeIndex - color.g * 256 + 1) / 256);
color.b = 1.0;
For each object (node) rendered, that colour is loaded into a
singleton picking fragment shader:
uniform vec3 uPickColor;
void main(void) {
gl_FragColor = vec4(uPickColor.rgb, 1.0);
}
Once frame is rendered, the colour is read from the
framebuffer:
function readPickBuffer() {
var context = boundPickBuf.canvas.context;
var pix = context.readPixels(pickX, boundPickBuf.canvas.canvas.height - pickY, 1, 1, context.RGBA, context.UNSIGNED_BYTE);
if (!pix) { // http://asalga.wordpress.com/2010/07/14/compensating-for-webgl-readpixels-spec-changes/
pix = new WebGLUnsignedByteArray(4);
context.readPixels(pickX, boundPickBuf.canvas.height - pickY, 1, 1, context.RGBA, context.UNSIGNED_BYTE, pix);
}
if (debugCfg.logTrace) {
SceneJS._loggingModule.info("Reading pick buffer - picked pixel(" + pickX + ", " + pickY + ") = {r:" + pix[0] + ", g:" + pix[1] + ", b:" + pix[2] + "}");
}
pickedNodeIndex = (pix[0] + pix[1] * 256) - 1;
}
However the pickedNodeIndex does not always map to the original
nodeIndex, probably due to inaccuracies in numeric translation
between JS and GLSL.