I am implementing a UI library, and I want to implement pixel-perfect hit detection.

For example, if a UI element is a red ellipse, when I click on a red pixel, I want a click event to be emitted; otherwise, no event should be emitted.

I wonder how I can implement this pixel perfect hit-detection without a heavy performance cost.

The somewhat naive approach would be to render the id of the UI element onto a stencil attachment of some frame buffer. Then, every frame, I can read the pixel value of the texel my mouse is currently hovering on using glReadPixels.

The problem is that glReadPixels is synchronous and therefore blocking; it will halt the CPU execution until the frame is ready, perform the read operation and only then continue.

This is a potential performance bottleneck that I need to avoid.

What are my options?

2 Replies 2

Not sure I understand the issue. Your concern is that glReadPixels will block until rendering is complete but I don't see how you can possibly perform any hit-test before the rendering process has completed, right? Or have I missed the point?

I don't think you will be able to get pixel-perfect hit-tests without reading anything back. Even if you'd perform the intersection check itself on the GPU (computer shader or something else), you'd at least have to return the id of the object that got hit. There is probably some solution with SSBOs, glFenceSync and periodically checking if the results are ready, but (without testing it), I don't think the performance will be much better than just syncing.

Is there any specific reason why you want to avoid the CPU/GPU sync or is it just about general performance? For UI interactions, you usually want results immediately (as in, during the current frame), not a couple of frames later.

The only other option I see for hit-tests without any read-backs is to perform the hit-test completely on the CPU, maybe with bounding objects (rectangles, circles, ...), but then it will probably not be pixel perfect.

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.