fix(scene): land the opening crane on scroll or stutter and prewarm cut shaders
This commit is contained in:
@@ -187,6 +187,9 @@ export async function createProceduralSceneGeneration(
|
||||
// Opening shot: a crane down from the sun to the chase position. It plays
|
||||
// once, only when the visit starts at the top, and a scroll hurries it.
|
||||
let introProgress: number | null = null;
|
||||
let introHurried = false;
|
||||
let introFrames = 0;
|
||||
let introSlowFrames = 0;
|
||||
|
||||
const resize = (): void => {
|
||||
const nextWidth = Math.max(1, canvas.clientWidth || canvas.width || 1);
|
||||
@@ -261,10 +264,8 @@ export async function createProceduralSceneGeneration(
|
||||
throw new Error('Injected post-first-frame exception');
|
||||
}
|
||||
resize();
|
||||
const deltaSeconds =
|
||||
lastNow === null
|
||||
? 0
|
||||
: Math.min(0.1, Math.max(0, (now - lastNow) / 1000));
|
||||
const wallSeconds = lastNow === null ? 0 : Math.max(0, (now - lastNow) / 1000);
|
||||
const deltaSeconds = Math.min(0.1, wallSeconds);
|
||||
lastNow = now;
|
||||
dynamics.update(snapshot.acceleration, snapshot.direction, deltaSeconds);
|
||||
const response = dynamics.snapshot();
|
||||
@@ -514,10 +515,25 @@ export async function createProceduralSceneGeneration(
|
||||
if (introProgress === null) {
|
||||
introProgress =
|
||||
snapshot.activeSectionId === 'start' && snapshot.scrollY < 40 ? 0 : 1;
|
||||
// The crane opens on the sky, so the road, car and roadside would
|
||||
// otherwise compile their shaders mid-drive when they first enter the
|
||||
// frame. Compile every visible object now, as the chase framing would.
|
||||
if (introProgress === 0) renderer.compile(scene, camera);
|
||||
}
|
||||
if (introProgress < 1) {
|
||||
const hurry = snapshot.scrollY > 40 ? 5 : 1;
|
||||
introProgress = Math.min(1, introProgress + (deltaSeconds * hurry) / INTRO_SECONDS);
|
||||
// The shot belongs to a visitor who waits at the top. Once they scroll
|
||||
// or navigate it lands within about 0.4 s of wall time, so the chase
|
||||
// framing (and every sign placed against it) is back before arrival.
|
||||
if (snapshot.scrollY > 40 || snapshot.activeSectionId !== 'start') introHurried = true;
|
||||
// A crane that stutters is worse than none: on a device that cannot
|
||||
// hold the shot smoothly, land it straight away.
|
||||
// The first frames carry shader compilation and a lone hitch (a late
|
||||
// texture upload) is forgiven; three slow frames end the shot.
|
||||
introFrames += 1;
|
||||
if (introFrames > 3 && wallSeconds > 0.1) introSlowFrames += 1;
|
||||
if (introSlowFrames >= 3) introHurried = true;
|
||||
const step = introHurried ? Math.min(0.5, wallSeconds) / 0.4 : deltaSeconds / INTRO_SECONDS;
|
||||
introProgress = Math.min(1, introProgress + step);
|
||||
}
|
||||
const crane = easeInOutCubic(
|
||||
THREE.MathUtils.clamp((introProgress - 0.06) / 0.94, 0, 1),
|
||||
|
||||
Reference in New Issue
Block a user