Search code examples
shaderrenderingwebglinstance

Ordering instances in WebGL


I'm drawing a lot of rectangles, thus I'm using the WebGL2RenderingContext.drawArraysInstanced() for it. I'm also using a lot of buffers to control shaders per instance (containing such data as position, colors, state, etc). I want now to affect the order in which my instances are being drawn (for example, to bring to the front the instance clicked by the user) and I'm looking for something like INSTANCE_ARRAY_BUFFER, something similar to ELEMENT_ARRAY_BUFFER, but for instances instead of vertices. Something that would allow me to tell "draw instances in the following order: 3,1,2,0,...". Is there any API which would allow me to control the order of the drawn instances without modifying the order of elements of all the data buffers?

Based on my research so far I suspect the answer will be "no", but maybe I missed some hidden WebGL API. Moreover, as a bonus question – was something like that introduced maybe in recent OpenGL versions or the WebGPU?


Solution

  • Your only actual question is

    Is there any API which would allow me to control the order of the drawn instances without modifying the order of elements of all the data buffers?

    Yes, put your data in textures, pass in an array of ids in a buffer

    Some examples, not just quads here and here

    I have no idea how much faster or slower this would be. My intuition is it would be slower but I haven't tested.

    It would be strange to me that the only thing you're optimizing for is draw order and that you don't need to position all the quads and change their UVs. If you do need to position all the quads and change their UVs then just write them in the correct order in the first place.

    Other comments based on the comments

    • Are instances the best way to draw lots of quads?

      I think the verdict here is not so clear. 10 years ago my experience was instancing was 30% slower than just creating the data for all the quads. My tests indicate that's no longer true, at least not on any GPU I own and not in WebGL.

    • Is writing 4 or 6 vertices to buffers per quad a good solution?

      It's common to just write all the data to buffers every frame for UIs. See pretty much every ImGUI library