The renderer now selects lower triangle-count variants for small, distant imported models. Ordinary large nearby objects retain their original geometry; declared terrain uses the ground policy below. High remains the default quality preset. This changes presentation only: source artifacts, entity identities, collision, shared state and checkpoints keep their existing contracts.
#Derived geometry and limits
packages/assets/lod.ts uses the pinned MIT-licensed meshoptimizer 1.3.0 simplifier. The adapter requests two index-only derivatives, targeting 50% and 25% of the original indices at relative appearance-error limits of 0.005 and 0.02. Normal, UV and optional tangent attributes participate in the error metric. Topological borders are locked, and permissive seam collapse/component pruning are not enabled. Results may stop above the requested triangle count; a level must save at least 10% over the previous accepted level to be retained.
The original vertex, normal, UV, tangent and material streams are reused. New imports derive once in the source orientation. The renderer reflects vertices and reverses stored triangle winding for mirrored instances. Retained legacy artifacts use their existing corrected-geometry derivation path. Skinned geometry is excluded; traveler instances always draw original detail. Static geometry with animated instance transforms can still select detail from its current displayed transform.
Generation accepts at most 131,072 vertices and 393,216 indices per validated primitive and skips primitives below 192 indices. There are at most two derivatives per mesh. Catalog preparation retains at most 2 MiB of extra indices within the existing 32 MiB model budget. Optional indices are trimmed when the original catalog plus the accepted catalog fit the replacement peak budget but the derivatives would not. This does not relax the original model or shared-device budget.
meshopt-1.3.0-static-lod.1 identifies these derivation settings. Change this profile when the algorithm or settings change. GPU keys combine the original mesh identity, profile and level. New imports now package variants in a versioned model artifact, generated by the isolated CLI compiler or the editor import Worker. The renderer decodes stored indices without invoking the simplifier. Retained format 1–6 models keep runtime derivation. Independently streamed variants remain future work. Reimporting a model with useful derivatives produces a new artifact identity; its original source geometry and collision are bound by the retained base hash. Existing published artifacts are not rewritten.
#Selection and drawing
packages/render/lod.ts estimates projected error using the current affine transform, camera-facing depth, conservative transformed bounds and output pixel height. It handles nonuniform scale, shear and camera rotation. Near-plane intersections and invalid arithmetic retain original detail. Coarsening is allowed below 112 projected pixels in diameter; an existing reduced level can remain up to 140 pixels. This hysteresis limits threshold flicker.
Declared streaming ground carries detail: "terrain" in presentation format 17. Its renderer uses camera-facing transformed-box depth and the same projected-error thresholds, without the ordinary small-silhouette diameter restriction. Before enabling that policy, model preparation compares every derivative’s oriented boundary edges with the original indices. Missing, reversed or additional boundary edges force full-detail ground. Adjacent terrain tiles retain their original edge vertices and normals even when they choose different levels. No source model, collision, world hash or residency selection changes. This policy is applied in editor previews, player scenes and destination views.
Estimated error thresholds are 0.65 pixels for High, 1 pixel for Balanced and 1.5 pixels for Performance. Entering a coarser level requires 20% headroom; returning toward the camera promotes detail at the full threshold. The simplifier’s appearance error is an estimate, not a mathematical maximum pixel-difference guarantee.
Each mesh batches visible instances by detail level. All levels share material and vertex buffers. Original geometry remains in the shadow pass, including off-camera casters, so shadow silhouettes do not change at LOD transitions. Source and portal renderers use their own cameras and bounded per-instance history. Renderer-owned object copies hold this transient history; the immutable presentation scene is not mutated.
F2 and exported reports show reduced-detail instance count, visible triangles saved and resident LOD index bytes for the source view. Shared GPU-pool accounting includes variant buffers, validation readiness, partial-allocation rollback and last-owner disposal. Distance changes allocate no new GPU resources. setLodEnabled(false) is a diagnostic reference used by native image comparisons; ordinary play keeps selection enabled.
#Evidence and remaining work
Acceptance evidence records headless checks, actual main/worker WebGPU comparisons, shared-player approach/recovery and regression results. In the textured sphere fixture at High quality, visible triangles decrease from 2,220 to 1,404 (including the floor). Near images are identical. Far images differ in 125 pixels, with three pixels differing by more than 32 channel values and RGB RMSE about 0.241 on a 0–255 scale over the 640×400 image. Both placements produce the same measurements. These are fixture measurements, not arbitrary-asset quality or frame-rate guarantees.
Remaining work includes independently streamed/authored LOD variants, progressive texture mip delivery, compressed variants, skinned/primitive LOD, shadow LOD, GPU-memory quality degradation, preparation optimization, physical-device and long-session qualification. This increment reduces draw work while adding bounded optional index storage; it does not evict high-detail vertices/textures or complete the streaming/asset milestones. The final character and environment art pass remains open.
#Portable import artifacts
glb-compiler.7 and asset-job profile 7 generate glb-detail.1 (model format 7) only when at least one usable variant exists. Small or unreducible assets retain their earlier model format. The detail record contains meshopt-1.3.0-static-lod.1, the original format/importer/hash, a byte census and sorted unique mesh/primitive entries. Each entry holds at most two levels with a count, absolute appearance-error estimate and canonical base64 little-endian uint32 indices. Total stored indices are capped at 2 MiB per model; the renderer still applies catalog and replacement budgets.
The format-7 identity is a hash of {format, importer, detail}. detail.baseHash separately binds every original model field through the original format's checksum. Readers reconstruct and validate that base artifact, then validate derivative references, counts, ordered errors, index ranges, encoding and budget before checking the detail identity. Transport units and compiler replies additionally hash the complete wire artifact. This avoids hashing the complete geometry a second time while retaining the identity chain. The reader does not rerun simplification or certify arbitrary authored variants' visual fidelity; pinned compiler output and native image fixtures supply the quality evidence.
The packaged author compiler includes the simplifier and MIT notice. Editor import cancellation terminates its Worker; the CLI retains its existing process deadline, heap limit and output bound. Saving, undoing, publishing and streaming these models use the existing immutable world/revision paths. Old engine bundles remain pinned to their old artifacts; format 7 requires this engine revision or later.
npm run bench:model-detail -- test-results/model-detail-preparation.json records source/artifact/index sizes and preparation timings for three bounded analytic models, including a 66,049-vertex / 391,680-index fixture near the index ceiling. It includes validation and performs one warmup plus three observations per mode. Fixed order and GC affect these observations. Recorded measurements show that removing runtime simplification does not yet reduce total preparation time: storing variants increases transfer and validation cost. This is portable precomputation, not a loading-speed claim. Artifact acceptance records compiler, editor, streaming and recovery checks.
Immutable model admission now removes repeated validation/copying of the exact admitted artifact within one worker. A matched before/after catalog benchmark shows lower fresh and repeated preparation cost. The standalone import-artifact measurements above remain historical; precomputed variants still add wire bytes and fresh inputs still require full validation.
The four-tile terrain fixture at High quality reduces visible triangles from 2,048 to 1,152. Physical-GPU main and Worker runs agree: RGB RMSE 0.0221 on the 0–255 scale, no pixels with a channel difference above 32, exact full-detail fallback for a deliberately broken boundary and exact recreation pixels. See terrain streaming evidence and remaining work. These are draw-work and image comparisons, not frame-rate claims.