Front-load post-processing compile into the loader
primeSceneForLoader() compiled scene materials and rendered the shadow/reflection passes once, but never ran the full composer pipeline — so the SSAO and output passes compiled their programs and allocated their render targets on the first live frame after the loader faded, tanking FPS for ~1-2s before it climbed to full. Now the loader runs composer.render() twice during prime, and precompiles the flip page materials (created lazily on first flip, so previously missed by renderer.compile) via a throwaway probe mesh. The heavy first-frame work is paid behind the loader overlay instead. Verified live: loader timings show composerWarmup taking ~1499ms during load (exactly the cost that used to hit the first frame); after fade-out there are no over-budget tank frames in the slow-frame log and idle settles at ~72fps. Static suite passes (165). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4317,12 +4317,39 @@ function primeSceneForLoader() {
|
||||
updateTableReflection();
|
||||
markLoaderTiming('tableReflection:end');
|
||||
markLoaderTiming('shaderCompile:start');
|
||||
renderer.compile(scene, camera);
|
||||
compileFlipMaterialsForLoader();
|
||||
markLoaderTiming('shaderCompile:end');
|
||||
// Run the full post-processing pipeline now so the SSAO and output passes compile their
|
||||
// programs and allocate their render targets during the loader, instead of stalling the
|
||||
// first live frames after the loader fades out.
|
||||
markLoaderTiming('composerWarmup:start');
|
||||
if (composer) {
|
||||
composer.render();
|
||||
composer.render();
|
||||
}
|
||||
markLoaderTiming('composerWarmup:end');
|
||||
staticSceneBuffersDirty = false;
|
||||
markLoaderTiming('primeSceneForLoader:end');
|
||||
}
|
||||
|
||||
// The flipping page mesh is only created on the first page flip, so its materials are not in
|
||||
// the scene graph that renderer.compile walks. Compile them now via a throwaway probe mesh so
|
||||
// the first flip does not stutter while the GPU compiles the flip page program.
|
||||
function compileFlipMaterialsForLoader() {
|
||||
const probeGeometry = new THREE.PlaneGeometry(0.001, 0.001);
|
||||
const probes = [materials.flipPageSurface, materials.flipPageBackSurface, materials.flipPageEdge]
|
||||
.map((material) => {
|
||||
const probe = new THREE.Mesh(probeGeometry, material);
|
||||
probe.position.copy(book.position);
|
||||
probe.visible = true;
|
||||
book.add(probe);
|
||||
return probe;
|
||||
});
|
||||
renderer.compile(scene, camera);
|
||||
probes.forEach((probe) => book.remove(probe));
|
||||
probeGeometry.dispose();
|
||||
}
|
||||
|
||||
function tintAmbientFromCanvas(canvas) {
|
||||
if (!canvas || !candleBounceLight) return;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
Reference in New Issue
Block a user