feat: couple terrain surge and sun bloom to the soundtrack's low end

This commit is contained in:
2026-10-10 17:46:17 +03:00
parent 416b930523
commit 0821b542b5
5 changed files with 93 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
import * as THREE from 'three';
import type { JourneySnapshot } from '@/journey/types';
import { readMusicPulse } from '@/audio/music-pulse';
import type { SceneResourceBag } from '@/scene/resources';
import type { SceneBuildContext, SceneGeneration } from '@/scene/types';
import { renderQualityFor } from '@/scene/render-quality';
@@ -165,6 +166,7 @@ export async function createProceduralSceneGeneration(
let signCameraWeight = 0;
let overdrive = 0;
let terrainSurge = 0;
let musicPulse = 0;
let terrainSpectrumPhase = 0;
let firstFrameSuppressionRecorded = false;
@@ -264,10 +266,17 @@ export async function createProceduralSceneGeneration(
const surgeTarget = Math.sqrt(
THREE.MathUtils.clamp(snapshot.acceleration, 0, 1),
);
// Soundtrack coupling: the bass the visitor hears lifts the terrain and
// the sun. One analyser read per frame; zero when nothing is audible.
const pulseTarget = readMusicPulse();
musicPulse +=
(pulseTarget - musicPulse) *
(1 - Math.exp(-deltaSeconds / (pulseTarget > musicPulse ? 0.05 : 0.32)));
const beat = THREE.MathUtils.smoothstep(musicPulse, 0.42, 0.92);
terrainSurge +=
(surgeTarget - terrainSurge) *
(Math.max(surgeTarget, beat * 0.55) - terrainSurge) *
(1 -
Math.exp(-deltaSeconds / (surgeTarget > terrainSurge ? 0.11 : 1.15)));
Math.exp(-deltaSeconds / (Math.max(surgeTarget, beat * 0.55) > terrainSurge ? 0.11 : 1.15)));
// Integrate color travel instead of multiplying elapsed time by speed:
// lifting off slows the spectrum to rest without rewinding its phase.
terrainSpectrumPhase =
@@ -314,7 +323,7 @@ export async function createProceduralSceneGeneration(
currentPalette,
snapshot.routeProgress,
elapsedSeconds,
response.bloomEnergy,
Math.min(1, response.bloomEnergy + beat * 0.35),
snapshot.arrived,
);
car.update(