Picking tutorial

Where can I find WebGL picking tutorial/example/demo?

Thanks in advance for your help.

It’s going to be tough.

WebGL doesn’t support occlusion testing (although it might one day appear as an extension on some hardware). Because it’s based on OpenGL ES it has none of the selection and feedback modes from regular OpenGL.

That leaves you with either doing it entirely yourself in software - or doing a very old-school trick of creating an FBO that’s the same size as your selection area (maybe a very tiny FBO if you’re just interested in where the mouse is clicked - larger if you want everything within a rectangular area)…and drawing each distinct “object” using a super-simple shader in a different color. When you’ve rendered everything, you read back the FBO into the CPU and read the color of the pixel(s) to figure out which object was nearest from the camera.

What an “object” is depends on what you want to pick between…if you need to know down to the nearest triangle - then you’ll be drawing each triangle in a unique color. If you only need to know at the scale of an entire mesh - then draw each mesh in a different color.

The number of objects/triangles you can pick between is limited by the number of distinct colors you can draw - which on very low end hardware might be as few as 65536. If you need to distinguish more than that then you’d have to render everything in batches of at most 65536 and read back the FBO after each batch.

It’s all very nineteen-ninety’s…but that’s the price of being able to run on bottom-end hardware.

– Steve

Thanks Steve.

I just found this article “Picking Tutorial -Color Coding”
http://www.lighthouse3d.com/opengl/picking/index.php?color1

I wish they made it simpler because many applications need picking capability.

Yeah - I agree - but it’s down to hardware capabilities. The relatively unsophisticated cell-phone chips and the god-awful Intel motherboard graphics chips simply don’t have the hardware capability to do this the easy way…and there really isn’t much that WebGL can do to fix that.

One of the problems with WebGL (especially in this first version where there is a conscious effort to try to keep it simple and portable) is that it’s more or less dumbed-down to the minimum hardware specification. Modern, high end nVidia and ATI chipsets have much fancier ways to do this kind of thing (occlusion testing being a good one).

But even if this were exposed as a WebGL extension on hardware that can handle it, you’d still have to test for it and fall back on the old-school color selection trick on older or less-capable hardware. So if your concern is software complexity then you’re no better off.

It’s unfortunate - but like so many things, you have to learn to roll with the punches. This isn’t (by far) the worst restriction! Just wait until you want to do ambient occlusion or layered fog and find that you can’t map the Z buffer into a texture map!

I finally got it working using the following as the guideline:

Picking Tutorial - Color Coding http://www.lighthouse3d.com/opengl/picking/index.php?color1
WebGL Lesson 16 – rendering to textures http://learningwebgl.com/blog/?p=1786

Thanks

You can have a look at my WebGL Joint And Object Framework (http://webtable.byethost15.com/WebGL). It is a framework for easily loading objects and bending their joints without having to know much about the lower workings of WebGL. However, it does implement Picking.

The basic theory is as follows:

  1. Create a framebuffer that you can render to so that you don’t affect the screen
  2. Render the scene to the framebuffer using a different color for each object
    (Don’t forget to turn lighting effects off if you do this since they will affect the color)
  3. Read the pixel color at the position the user’s mouse clicked at
  4. Compare the color to the colors of the rendered objects to determine which object
    was clicked.

This method allows a maximum of about 16777216 objects to be rendered in a scene since this is the amount of colors that can be generated by byte RGB values. You may be able to increase this using the alpha byte but I am not sure if the color will get returned properly when alpha is used.

This method also only gets the topmost clicked object. If you want to know the entire stack (all objects that the mouse is over) then you would probably have to repeat the above process without rendering any of the previously identified objects. For example, do the render and determine that object 34 is topmost now re-render without object 34 to find out what object 25 is the next topmost, then re-render without object 34 and 25 to find out what the next topmost object is, and so on. Time consuming!