Hey I’m integrating selection outliner in Babylon.js Editor and I noticed a small bug.
When creating an instance of a mesh which contains LODs, the outline disappears when the first LOD level awakes. This behavior is the same when outline is applied on source mesh or the instance ifself. If you remove the instance, you’ll see that everything works fine
Link to the playground, unzoom to trigger new LOD levels and you’ll see the outline disappears: https://playground.babylonjs.com/#QE7KM#246
Thanks a lot for your help
2 Likes
Ohhh thanks a ton for the repro, let me add @Evgeni_Popov to have a look
1 Like
Hey @julien-moreau , thanks for the great repro!
This turned out to be a bug in SelectionOutlineLayer._renderSubMesh. When LOD switches to a different mesh, two things went wrong:
The LOD mesh inherited world-matrix instance buffers from the scene render, which incorrectly forced it into the hardware instanced rendering path — but without the selection ID attribute, so
the outline data was lost.
The selection ID lookup never checked the master (source) mesh when rendering a LOD mesh.
Fix PR:
master ← Popov72:fix/selection-outline-lod-instances
opened 08:38PM - 02 Apr 26 UTC
## Description
Fixes the selection outline disappearing when a mesh with instan… ces transitions between LOD levels.
**Forum report:** https://forum.babylonjs.com/t/selection-outliner-bug-with-instances/63029
## Root Cause
Two issues in \ThinSelectionOutlineLayer._renderSubMesh\:
1. **Forced hardware instanced rendering on LOD meshes:** LOD meshes inherit \_userInstancedBuffersStorage\ (world matrix buffers) from the scene render. The old code used \!!renderingMesh._userInstancedBuffersStorage\ to force hardware instanced rendering, but the LOD mesh's storage lacks the \instanceSelectionId\ buffer — causing the mesh to render without selection data.
2. **Missing selection ID lookup for LOD meshes:** When a LOD mesh replaces the source mesh during rendering, the selection ID (stored on the master mesh) was never looked up.
## Fix
- Only trigger hardware instanced rendering from \_userInstancedBuffersStorage\ when it actually contains the \instanceSelectionId\ vertex buffer.
- When looking up the selection ID, fall back to the master mesh (for both \_meshUniqueIdToSelectionId\ and \instancedBuffers\).
## Testing
- Added visualization test **\Selection outline layer with instances and LOD\** (playground [\#8I487I#0](https://playground.babylonjs.com/#8I487I#0))
- All 5 existing outline visualization tests pass
3 Likes
What a quick fix!!
Thanks for the explanations!!
Just in case, I found something weird also: selectionOutliner.hasMesh(anyMesh) always returns true even if I just cleared selection.
Is that something you can see right now? I can create a repro but I’m not on my PC anymore
1 Like
You’re right, PR updated with the fix!
3 Likes
Hey @Evgeni_Popov !
I catched a last issue, else it looks perfect: when selecting the source mesh everything works as expected thanks to your fix. But I instead of the source mesh I put the instance, the outline disappears
Link to the modified PG: https://playground.babylonjs.com/#QE7KM#247
Thanks a lot !
1 Like
Thanks for reporting, here’s the fix:
master ← Popov72:fix/selection-outline-lod-instances-2
opened 08:30AM - 16 Apr 26 UTC
## Description
Fixes the selection outline disappearing when an **instance** (n… ot the source mesh) with LOD transitions is selected.
**Forum report:** https://forum.babylonjs.com/t/selection-outliner-bug-with-instances/63029/10
## Root Cause
Three issues in `ThinSelectionOutlineLayer._renderSubMesh`:
1. **LOD meshes lacked `instanceSelectionId` registration:** When LOD transitions replaced the rendering mesh, `_processInstancedBuffers` didn't process the selection ID attribute because it wasn't registered on the LOD mesh — leaving the vertex attribute at 0 (not selected).
2. **Uniform lookup ignored the actual instance:** The selection ID uniform only checked `renderingMesh._masterMesh` (source mesh), not the `ownerMesh` (the instance being rendered). When only the instance was selected, the source mesh's value was 0.
3. **LOD mesh self-draw had wrong selection ID:** The LOD mesh's own `instanceSelectionId` wasn't synced from the source mesh for the hardware instancing self-draw.
## Fix
- In `addSelection`, register `instanceSelectionId` on each LOD mesh of the source mesh and track them in `_instancedBufferSources` for cleanup.
- In `_renderSubMesh`, sync the source mesh's selection ID to the LOD mesh before hardware instanced rendering.
- In the uniform lookup, prefer `ownerMesh` (the actual instance) over the master mesh for the selection ID.
## Testing
- Added visualization test `Selection outline layer instance selected with LOD` (playground [#M4HHTC#0](https://playground.babylonjs.com/#M4HHTC#0))
- Both WebGL2 and WebGPU pass locally
1 Like