Hello Everyone,
I am building a CesiumJS application that visualizes building floors as voxel-style grids, and the viewer crashes when I draw around 25 buildings at the same time. I would appreciate your advice on the best way to structure this.
ENVIRONMENT
- CesiumJS version: 1.146
- Browser / OS: Chrome 130 / Windows 11
- GPU: Asus Ryzen 7
- Framework: plain JS
WHAT I AM DOING
For each building, I take its footprint polygon (lon/lat), convert it to a local ENU frame, and sample a regular grid of cells (voxelSize = 2 m) inside the polygon. For every cell on every floor I create a Cesium.GeometryInstance using a shared BoxGeometry (voxelSize * 0.98 by 0.98 by floorHeight * 0.98) and a per-instance modelMatrix. All instances for a building go into a single Cesium.Primitive with:
- PerInstanceColorAppearance({ translucent: true, closed: true })
- asynchronous: false
- per-instance color with alpha 0.25
- a unique id object per instance ({ floor, x, y })
I color each floor by hue and recolor an entire floor when the user clicks it, using per-floor bookkeeping of the instance ids.
THE PROBLEM
With a small number of buildings, it works, but at ~25 the tab freezes, and the viewer crashes [frozen tab]
MY QUESTIONS
- What is the recommended approach for rendering many building floors with per-floor coloring and picking at this scale?
- Is VoxelPrimitive appropriate for this use case, and what practical limits (dimensions, number of primitives, metadata channels) should I stay within for around 25 simultaneous volumes?
- If I keep the geometry-based approach, what is the best way to reduce cost with many translucent boxes (merging, batching, or alternative appearances)?
- Are there best practices for creating and destroying many primitives to avoid GPU memory growth or WebGL context loss?
- Is there a better pattern, such as 3D Tiles or instanced models, for large numbers of repeated box-like cells?
I would appreciate your help.