Part Selection

This technique goes one step further by allowing you to select different parts of an object. Each part is numbered, and this information is passed to the vertex shader. Again, the object is drawn twice. In the first pass, the part number is stored in the alpha component of the color variable, allowing you to retrieve it using readPixels() later.

Originally the two triangles were blue. When one of them is clicked, its color changes to white. The white triangle may be switched by clicking the other triangle.
RESETRUNFULL
<!DOCTYPE html><html><head>
<script src="/shared/webgl-library.js"></script>
<script id="vs" type="x-shader/x-vertex">
   attribute vec4 p;
   attribute float part;
   uniform int pickedPart;
   varying vec4 vc;
   void main(){
      gl_Position = p;
      int pa = int(part);
      vec3 color = (pa==pickedPart)?vec3(1.0):vec3(0.0,0.0,1.0);
      if (pickedPart == 0){
         vc = vec4(color, part/255.0);
      } else {
         vc = vec4(color, 1.0);
      }
   }
</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.0,0.0,  -0.5, 0.5,0.0,  0.5, 0.5,0.0,
                                    0.0,0.0,0.0,  -0.5,-0.5,0.0,  0.5,-0.5,0.0 ]);
   initArrayBuffer(gl, 'p', vertices, 3);
   var parts = new Float32Array([1.0,1.0,1.0, 2.0,2.0,2.0]);
   initArrayBuffer(gl, 'part', parts, 1);
   gl.clearColor(0.0, 0.0, 0.0, 1.0);
   var pickedPart = gl.getUniformLocation(gl.program,'pickedPart');
   gl.uniform1i(pickedPart, -1);
   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 part = checkPart(gl, x_in_canvas, y_in_canvas, pickedPart);
         gl.uniform1i(pickedPart, part);
         draw(gl);
      }
   }
   var tick = function() {
      draw(gl);
      requestAnimationFrame(tick, canvas);
   };
   tick();
}
function draw(gl) {
   gl.clear(gl.COLOR_BUFFER_BIT);
   gl.drawArrays(gl.TRIANGLES,0,6);
}
function checkPart(gl, x, y, pickedPart) {
  var pixels = new Uint8Array(4);
  gl.uniform1i(pickedPart, 0);
  draw(gl);
  gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
  return pixels[3];
}
</script></head>
<body onload="WebGLStart()">
   <canvas id="myCanvas" width="500" height="500"></canvas>
</body></html>