Skip to content

Smooth LOD_1 → LOD_0 transition for ISS (atomic swap, no overlap) #8893

Description

@dalkia

Problem

When a scene transitions from LOD_1 (single-AB LOD) to LOD_0 (the ISS-descriptor-driven, per-asset reconstruction), there's a visible window where both representations are rendered on top of each other:

  • LOD_1 is already in the scene.
  • LOD_0 starts arriving asset-by-asset via the descriptor — each ISSDescriptorAsset is parented + positioned + SetActive(true) as its per-asset AB resolves.
  • During the (potentially long) interval between the first descriptor entry resolving and the last one finishing, the player sees LOD_0 pieces overlapping the still-present LOD_1 mesh.
  • Only once LOD_0 is fully populated does the system release LOD_1.

The result is z-fighting + double-shaded geometry for a noticeable window, which is especially obvious for large scenes whose descriptor entries trickle in over multiple seconds.

Introduced by PR #8870 (chore: new lods through ISS descriptor).

Where this happens today

  • Explorer/Assets/DCL/LOD/Systems/ResolveISSLODSystem.csPositionAsset (line 161) calls asset.Root.SetActive(true) and parents the asset under InitialSceneStateLOD.ParentContainer as each per-asset bundle resolves, immediately visible.
  • Explorer/Assets/DCL/LOD/Components/InitialSceneStateLOD.csAllAssetsInstantiated() (line 91) returns true only when every descriptor entry has finished (Assets.Count == TotalAssetsToInstantiate).

Suggested approaches (cheapest → most polished) (Beware, they were AI written. Although they make sense, thet are just guidelines)

  1. Atomic swap via deferred activation (recommended first attempt).

    • In ResolveISSLODSystem.PositionAsset, parent + position each asset but leave it SetActive(false).
    • When InitialSceneStateLOD.AllAssetsInstantiated() becomes true, walk the children of ParentContainer and SetActive(true) in a single frame, then trigger the LOD_1 unload in the same frame.
    • Tradeoff: ~one extra frame of "empty" scene if the unload-LOD_1 step happens after the activation. Mitigate by activating LOD_0 in the same tick that schedules LOD_1's release, or activate LOD_0 first and unload LOD_1 next tick (one frame of intentional overlap, much shorter than today).
  2. Activate the parent, not the children.

    • Same idea as Test #1 but operating on InitialSceneStateLOD.ParentContainer itself (SetActive(false) until ready). Slightly less per-asset work; just one SetActive call at the end. Requires EnsureParentContainer to start inactive and AddResolvedAsset to not toggle it.
  3. Hard gate on LOD_1 unload — keep LOD_1, build LOD_0 invisibly, swap.

    • Hybrid of Test #1: keep LOD_1 visible the entire time LOD_0 is assembling (no "empty frame" risk), only deactivate LOD_1 the same tick LOD_0 is activated. Memory overhead is both LODs co-resident during assembly, but the descriptor mode means LOD_0 ABs are streamed one at a time so peak overlap is bounded.
    • This is probably the cleanest UX: the player never sees a hole and never sees overlap — they see LOD_1, then in one frame they see LOD_0.
  4. Per-asset staging container with same-frame swap.

    • Spawn into a hidden "staging" GameObject parent. Once full, reparent the entire subtree under the active container and disable LOD_1, all in the same frame. ]

Repro

Easiest in Genesis Plaza: spawn / teleport out to roughly 20,20 so the central plaza is in LOD_1, then walk straight back toward 0,0. As you cross the LOD threshold the system switches into descriptor mode for LOD_0, and the overlap window is plainly visible head-on at the boundary.

Same effect is reproducible in the world test from #8892 (cozyhouse.dcl.eth on .zone) once LODs actually fire for worlds, but Genesis Plaza is the easier reproduction today since #8892 still blocks LODs in worlds.

Related

Metadata

Metadata

Labels

2-mediumMedium severity issuesbugSomething isn't workinggraphicslod

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions