xeokit-sdk icon indicating copy to clipboard operation
xeokit-sdk copied to clipboard

Rendering optimization: compact draw lists

Open xeolabs opened this issue 2 months ago • 0 comments

Currently multi-pass drawing is wasteful, where if for instance you have three transparent objects in a 100000-object model, then you're drawing one color pass with 100000 objects, then a second transparent drawing pass over the same 100000 objects, this time drawing three objects while culling the other 999993 in the vertex shader. That's still putting 200000 objects through the shader, regardless of culling.

My idea is to modify data textures to continue to use one texture for the entire elements array, but to partition it into "color opaque", "color transparent", "selected", "highlighted" and "xray" bins. The array tracks the first/count elements for each portion. When drawing a bin, the gl.drawElements call uses the first/count to draw just that portion.

An object can only be in one of the five visual states corresponding to the bins - they are mutually exclusive. This means that, to change the visual state of an object, we can simply copy it from one portion to another, adjusting boundaries if necessary with ~3-4 copies in the worst case.

The main changes would be

  • make data texture track those bin portion boundaries
  • remove the vertex shader's render pass masking (selected, highlighted, xrayed etc), which removes a conditional from the shader which is also good
  • remove the flags for these modes from data textures (they are only used for render pass masking at this level) - this reduces memory footprint slightly as well
  • This can also be applied to the VBO shaders, pretty much in the same way.

This is the technique I use in xeokit V3: https://github.com/xeokit/sdk/blob/dtx-refactor/packages/sdk/src/webglrenderer/viewManager/dtxMemory/dtx/DTXPrimDrawList.ts

xeolabs avatar Oct 20 '25 11:10 xeolabs