Shadows occasionally failed to render on initial load and the Fabrik
doorway sometimes blocked the player. Both issues are tracked down to
geometry that mounts after Lighting:
- Shadows: GLTFs and the merged static map mount imperatively after
Lighting, so materials get compiled against a renderer state that
pre-dates the final scene and bake a 'no shadow map' permutation,
silently dropping shadows. A WebGL context-restore cycle fixes it,
but is too invasive. New 'useShadowMapWarmup' hook replays it
cheaply: once the scene mesh count has been stable for ~1s, it
disposes the directional shadow map (three.js reallocates it on
the next render) and marks every material 'needsUpdate' so shaders
rebind to the freshly created shadow sampler.
- Doorway: the door slab + its Solidify-modifier frame (children of
the 'Thicken' parent in the LaFabrik GLTF) sat inside the doorway
AABB and prevented the player from walking through. Stripped from
the collision octree alongside the existing 'porte' slab; visual
rendering is unaffected.
Also: extract sun-relative-to-camera placement into a small helper,
remove the temporary diagnostic logs, and document the shadow warmup
in three-debugging.md.
Update three-debugging.md to reflect that the shadow intermittence
is resolved by explicit sun.shadow.needsUpdate = true at mount and
in useFrame after updateMatrixWorld.
- Drop SceneShadowWarmup section, document centralized shadow config.
- Document the localized Suspense boundaries in World.tsx.
- Document the new player model and octree debug visualizations.
- Open note about intermittent first-load shadow rendering.