MutomboDikey
MutomboDikey

Reputation: 175

Extract primitive id for a particular pixel

Consider a collection of objects in a scene rendered with an orthographic projection. Certain objects are occluded by other objects, and hence they are only partially visible, or do not register on the image plane at all, courtesy of the depth-buffer. Objects consist of triangles, which have their primitiveID. At this point the image is rendered and every pixel has a color assigned to it.

Now what I need to do is pick a pixel, and then tell which object is located at this pixel (depth accounted for). The internet dubbed this problem as "Object Selection / Mouse picking with ray casting". But I just can't help to think that ray-casting is an overkill for a task that seems so trivial. That is, shouldn't OpenGL keep track of the last primitiveID that painted a certain pixel? Meaning that if there is a particular colored fragment projected onto the image plane, then if OpenGL encounters a piece of geometry that is closer to the camera, it will simply override pixel color value (where the latter geometry occludes the original piece) and an associated triangle that gave rise to this color value.

And so its primitiveID could be linked to a pixel and accessed later on, which seems like a reasonable thing to do. Sadly, I couldn't find how to do it, and perhaps it is not as trivial as I thought. But I don't understand why.

Then the questions are:

As always, detailed answers and pointing in the right direction are equally much appreciated.

Upvotes: 0

Views: 1564

Answers (2)

Nicol Bolas
Nicol Bolas

Reputation: 473407

That is, shouldn't OpenGL keep track of the last primitiveID that painted a certain pixel?

Should it? Such a list of primitive IDs would require:

  1. Assigning a unique identifier to every primitive. This requires that the system bump a counter whenever a triangle gets rasterized. Which means an atomic operation for any GPU that has more than one rasterization unit (which actually exists, btw).

  2. Give the user some control over the identifier. Without control over the identifier, how would the user know which primitive it rendered mapped to which identifier? If the identifiers are globally incremented, then the user needs a way to reset them to a known value.

  3. A framebuffer-sized image that contains, for every sample, an identifier. This means that you've got another framebuffer-sized image taking up precious memory, as well as having every FS having an implicit write to such a buffer.

  4. A mechanism to read from that image at a particular pixel.

Such a system would play havoc with tessellation and geometry shaders, since those processes generate new primitives. If the user doesn't know exactly how many triangles will be generated by tessellation, how will they be able to figure out which output primitive maps to which primitive ID?

OpenGL doesn't do fixed-function stuff like this anymore. Instead, it gives you the tools to build whatever mechanisms you want.

Geometry shaders can (in theory) use atomic counters to increment themselves every time they generate a primitive, passing that value to the FS. And you can reset this counter when you feel like it. You can create an integer texture that your FS writes primitive IDs to. And you can use glReadPixels to read that value.

And equally importantly, if you don't need this (like most people don't), then resources aren't being expended for a feature you'll never use.

Upvotes: 3

ratchet freak
ratchet freak

Reputation: 48196

Opengl doesn't bother with tracking per pixel primitive ids. Instead it uses a depth buffer to store per pixel depth.

If you want to get the primitive ID you will need to add a color attachment and write out the primitive ID to it. Then you can read that texture to get the primitive ID for that pixel.

Upvotes: 4

Related Questions