chore(world): add temporary shadow pipeline diagnostics
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
Shadows still go missing intermittently despite the per-frame needsUpdate fix. Add temporary console logs to narrow down the cause: - [shadow:mount]: one-shot snapshot of renderer shadow flags and a scene.traverse count of meshes with castShadow / receiveShadow at Lighting mount time. - [shadow:tick]: every 2s during useFrame, log shadow map enabled flag, autoUpdate, sun.castShadow, sun intensity, shadow map texture presence, sun and target world positions, and renderer draw calls. To be removed once the root cause is identified.
This commit is contained in:
+54
-2
@@ -1,10 +1,12 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import {
|
||||
Mesh,
|
||||
PCFShadowMap,
|
||||
type AmbientLight,
|
||||
type DirectionalLight,
|
||||
type Object3D,
|
||||
type Scene,
|
||||
type WebGLRenderer,
|
||||
} from "three";
|
||||
import {
|
||||
@@ -51,12 +53,33 @@ function configureSunShadow(sun: DirectionalLight, sunTarget: Object3D): void {
|
||||
sun.shadow.camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// [diag] temporary helper: count shadow-casting/receiving meshes in the scene
|
||||
function snapshotShadowMeshes(scene: Scene): {
|
||||
meshCount: number;
|
||||
castShadowCount: number;
|
||||
receiveShadowCount: number;
|
||||
} {
|
||||
let meshCount = 0;
|
||||
let castShadowCount = 0;
|
||||
let receiveShadowCount = 0;
|
||||
scene.traverse((obj) => {
|
||||
if (obj instanceof Mesh) {
|
||||
meshCount += 1;
|
||||
if (obj.castShadow) castShadowCount += 1;
|
||||
if (obj.receiveShadow) receiveShadowCount += 1;
|
||||
}
|
||||
});
|
||||
return { meshCount, castShadowCount, receiveShadowCount };
|
||||
}
|
||||
|
||||
export function Lighting(): React.JSX.Element {
|
||||
const camera = useThree((state) => state.camera);
|
||||
const gl = useThree((state) => state.gl);
|
||||
const scene = useThree((state) => state.scene);
|
||||
const ambient = useRef<AmbientLight>(null);
|
||||
const sun = useRef<DirectionalLight>(null);
|
||||
const sunTarget = useRef<Object3D>(null);
|
||||
const lastDiagAtRef = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!sun.current || !sunTarget.current) return;
|
||||
@@ -64,7 +87,18 @@ export function Lighting(): React.JSX.Element {
|
||||
configureSunShadow(sun.current, sunTarget.current);
|
||||
configureRendererShadows(gl);
|
||||
sun.current.shadow.needsUpdate = true;
|
||||
}, [gl]);
|
||||
|
||||
// [diag] one-shot scene snapshot to count shadow casters/receivers
|
||||
const counts = snapshotShadowMeshes(scene);
|
||||
console.log("[shadow:mount]", {
|
||||
shadowMapEnabled: gl.shadowMap.enabled,
|
||||
shadowMapType: gl.shadowMap.type,
|
||||
shadowAutoUpdate: gl.shadowMap.autoUpdate,
|
||||
sunCastShadow: sun.current.castShadow,
|
||||
hasShadowMap: !!sun.current.shadow.map,
|
||||
...counts,
|
||||
});
|
||||
}, [gl, scene]);
|
||||
|
||||
useDebugFolder("Lighting", (folder) => {
|
||||
folder.addColor(LIGHTING_STATE, "ambientColor").name("Ambient Color");
|
||||
@@ -98,7 +132,7 @@ export function Lighting(): React.JSX.Element {
|
||||
.name("Sun Z");
|
||||
});
|
||||
|
||||
useFrame(() => {
|
||||
useFrame(({ clock }) => {
|
||||
if (ambient.current) {
|
||||
ambient.current.color.set(LIGHTING_STATE.ambientColor);
|
||||
ambient.current.intensity = LIGHTING_STATE.ambientIntensity;
|
||||
@@ -117,6 +151,24 @@ export function Lighting(): React.JSX.Element {
|
||||
sun.current.updateMatrixWorld();
|
||||
sun.current.shadow.needsUpdate = true;
|
||||
}
|
||||
|
||||
// [diag] periodic shadow pipeline check (every 2s)
|
||||
const now = clock.getElapsedTime();
|
||||
if (now - lastDiagAtRef.current > 2 && sun.current) {
|
||||
lastDiagAtRef.current = now;
|
||||
console.log("[shadow:tick]", {
|
||||
shadowMapEnabled: gl.shadowMap.enabled,
|
||||
shadowAutoUpdate: gl.shadowMap.autoUpdate,
|
||||
sunCastShadow: sun.current.castShadow,
|
||||
sunIntensity: sun.current.intensity,
|
||||
hasShadowMapTexture: !!sun.current.shadow.map?.texture,
|
||||
sunPos: sun.current.position.toArray().map((n) => Number(n.toFixed(2))),
|
||||
targetPos: sunTarget.current?.position
|
||||
.toArray()
|
||||
.map((n) => Number(n.toFixed(2))),
|
||||
renderCalls: gl.info.render.calls,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user