Object Selection

To know if an object has been clicked, we draw the object two times.

For the first time, we color the whole object with a specific color. We then check if the pixel clicked is of that specific color.

We then quickly draw the object the second time, using the original colors.

To check the color of a pixel, use readPixels(x,y,width,height,gl.RGBA,gl.UNSIGNED_BYTE,typed_array).
'typed_array' must be of the type Uint8Array.

A message pops up when the triangle is clicked. In more complex examples, the camera and the object may be moving, but this has no effect on this technique.
RESETRUNFULL
<!DOCTYPE html><html><head>
<script src="/shared/webgl-library.js"></script>
<script id="vs" type="x-shader/x-vertex">
   varying vec4 vc;
   uniform bool clicked;
   attribute vec4 p;
   void main(){
      if (clicked){
         vc = vec4(1.0,0.0,0.0,1.0);
      } else {
         vc = vec4(0.0,0.5,0.5,1.0);
      }
      gl_Position = p;
   }
</script>
<script id="fs" type="x-shader/x-fragment">
   precision mediump float;
   varying vec4 vc;
   void main(){
      gl_FragColor=vc;
   }
</script>
<script>
function WebGLStart(){
   var canvas = document.getElementById("myCanvas");
   var gl = canvas.getContext("webgl");
   initShaders(gl,"vs","fs");
   var vertices = new Float32Array([0.0,-0.5,0.0,  -0.5,0.5,0.0,  0.5,0.5,0.0]);
   initArrayBuffer(gl, 'p', vertices, 3);
   gl.clearColor(0.0, 0.0, 0.0, 1.0);
   var u_Clicked = gl.getUniformLocation(gl.program, 'clicked');
   gl.uniform1i(u_Clicked, 0);
      canvas.onmousedown = function(ev) {
      var x = ev.clientX, y = ev.clientY;
      var rect = ev.target.getBoundingClientRect();
      if (rect.left <= x && x < rect.right &&
           rect.top <= y && y < rect.bottom) {
         var x_in_canvas = x - rect.left,
                y_in_canvas = rect.bottom - y;
         var picked= check(gl, x_in_canvas,
                                     y_in_canvas, u_Clicked);
         if (picked) alert('The triangle was selected! ');
      }
   };
   var tick = function() {
      draw(gl);
      requestAnimationFrame(tick, canvas);
   };
   tick();
}
function draw(gl) {
   gl.clear(gl.COLOR_BUFFER_BIT);
   gl.drawArrays(gl.TRIANGLES,0,3);
}
function check(gl, x, y, u_Clicked) {
  var picked = false;
  gl.uniform1i(u_Clicked, 1);
  draw(gl);
  var pixels = new Uint8Array(4);
  gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
  if (pixels[0] == 255) picked = true;
  gl.uniform1i(u_Clicked, 0);
  draw(gl);
  return picked;
}
</script>
</head><body onload="WebGLStart()">
   <canvas id="myCanvas" width="500" height="500"></canvas>
</body></html>