Currently in BoundingBoxRenderer, it renders in a loop, calling engine.drawElementsType for each bounding box in renderList, making every bounding box 1 or 2 draw call.
Since it renders on web, it would suffer the same performance issue like meshes when draw calls increases.
Proposal
Since only the worldMatrix changes for different bounding boxes, it should benefit from instancing, like thin instances for meshes.
Allocate buffers for instancing.
Loop renderList and fill buffers.
Copy buffers to gpu.
Render instanced.
With instancing the draw call needed for each BoundingBoxRenderer could be reduced to 1 or 2 (in case this.showBackLines enabled)
Example:
Alternatives
Since there are very few[1] vertex needed, and there is already vectorsWorld in BoundingBox, which updates every time world matrix updates, the computation of matrices can be skipped, and reuse computation result of vectorsWorld to rebuild vertex buffer every time it renders. In this case _indexBuffer needs to be reconstructed is count of bounding box mismatches.
[1]: 24 points in case of CreateBoxVertexData, or 8 points if constructed manually, since uvs and normals are not needed for rendering as lines
It looks like a good idea! Do you want to make a PR for it!
However, you should implement it with a flag (like useInstancing, default: false), so that itās not a breaking change: currently, onBeforeBoxRenderingObservable and onAfterBoxRenderingObservable are notified for each bounding box, and it should still be the default behavior.
I donāt think it changes anything at the GPU level, as the current bounding box renderer already issues a single draw call with 24 indices (2 indices per line), which canāt be optimized better:
Ah. Is that because drawElements doesnāt have a multiline primitive? Looks like the multidraw extension to WebGL would help, but itās not supported everywhere (Firefox lacks support).
drawElements is already multilines, as you give a list of indices and it will draw lines between index 0 and 1, 2 and 3, and so on. Maybe I didnāt understand your question?
Agreed drawElements can draw multiple single-segment lines (lines defined by two points each). By āmultilinesā I meant lines made up of multiple segments each. In my case, each multiline is three segments defined by four points. Points 0, 1, 2, 3 result in a multiline defined by line segments 0->1, 1->2, 2->3, and 3->4.
The more āefficientā box definition uses four such multilines and is only 16 total vertices instead of 24. But if the end result is a drawElement(), which can only draw single-segment lines (defined by exactly two points each), then there is no savings in space or time.
We would trigger each event only a single time (passing a dummy/undefined box), not for each box. That would be the ābreaking changeā part (as well as the display being potentially different, because drawing the black/white part of each box one after the other can be different from drawing the black part of all boxes and then the white part).
I donāt think we need a renderList (Iām not sure what the user would do with it). We could simply document that when using the instanced mode, the passed bounding box has no meaning and should be ignored (would be better to be able to not pass a bounding box at all, but it would be a breaking change).