feat: polish nightdrive road sun and signage

This commit is contained in:
2026-09-03 00:29:26 +03:00
parent bc18bc2043
commit a03d4d8dba
44 changed files with 1208 additions and 202 deletions

View File

@@ -11,6 +11,11 @@ import { createSign } from '@/scene/world/sign';
import { createAtmosphere } from '@/scene/world/atmosphere';
import { createPostProcessor } from '@/scene/post-processing';
import { createDriveDynamics } from '@/scene/drive-dynamics';
import {
HORIZON_FOG_END,
HORIZON_FOG_START,
} from '@/scene/world/metrics';
import { createTravelDistance } from '@/scene/world/travel-distance';
import {
createMutableChapterPalette,
writeChapterPalette,
@@ -22,12 +27,16 @@ declare const __PORTFOLIO_TEST_BUILD__: boolean;
const TEST_BUILD = typeof __PORTFOLIO_TEST_BUILD__ !== 'undefined' && __PORTFOLIO_TEST_BUILD__;
export function createChaseCamera(aspect = 1) {
const camera = new THREE.PerspectiveCamera(66, aspect, 0.1, 900);
const camera = new THREE.PerspectiveCamera(66, aspect, 0.1, 1_200);
camera.position.set(0, 8.6, 22);
camera.lookAt(0, 4.8, -128);
return camera;
}
export function createWorldFog(color: number) {
return new THREE.Fog(color, HORIZON_FOG_START, HORIZON_FOG_END);
}
export async function createProceduralSceneGeneration(
context: SceneBuildContext,
): Promise<SceneGeneration> {
@@ -65,7 +74,7 @@ export async function createProceduralSceneGeneration(
const targetPalette = createMutableChapterPalette('deep-night');
const background = currentPalette.sky.clone();
scene.background = background;
scene.fog = new THREE.FogExp2(currentPalette.fog.getHex(), 0.0024);
scene.fog = createWorldFog(currentPalette.fog.getHex());
const camera = createChaseCamera();
const ambient = new THREE.HemisphereLight(0x6aa9c5, 0x100812, 1.25);
@@ -115,7 +124,7 @@ export async function createProceduralSceneGeneration(
};
let width = 0;
let height = 0;
let driveDistance = 0;
const travelDistance = createTravelDistance();
let lastNow: number | null = null;
let disposed = false;
let renderedFrames = 0;
@@ -190,17 +199,17 @@ export async function createProceduralSceneGeneration(
const response = dynamics.snapshot();
writeChapterPalette(targetPalette, snapshot.chapter, snapshot.chapter, 0);
dampPalette(currentPalette, targetPalette, deltaSeconds);
driveDistance += deltaSeconds * (
18
+ snapshot.driveSpeed * 54
+ response.roadEnergy * 48
const driveDistance = travelDistance.advance(
deltaSeconds,
snapshot.driveSpeed,
response.roadEnergy,
);
const visualSpeed = THREE.MathUtils.clamp(
0.18 + response.roadEnergy * 0.82,
0.18,
1,
);
road.update(driveDistance, visualSpeed, response.roadEnergy);
road.update(driveDistance, visualSpeed, response.roadEnergy, currentPalette);
terrain.update(
driveDistance,
visualSpeed,
@@ -209,7 +218,12 @@ export async function createProceduralSceneGeneration(
currentPalette,
);
const elapsedSeconds = now / 1000;
sun.update(currentPalette, snapshot.routeProgress, elapsedSeconds);
sun.update(
currentPalette,
snapshot.routeProgress,
elapsedSeconds,
response.bloomEnergy,
);
car.update(visualSpeed, response.suspensionEnergy, elapsedSeconds);
sign.update(snapshot.sign);
atmosphere.update(
@@ -220,7 +234,6 @@ export async function createProceduralSceneGeneration(
);
background.copy(currentPalette.sky);
scene.fog.color.copy(currentPalette.fog);
scene.fog.density = 0.0019 + (1 - currentPalette.warmth) * 0.0008;
ambient.color.copy(currentPalette.haze).lerp(currentPalette.terrainHigh, 0.26);
ambient.groundColor.copy(currentPalette.fog);
ambient.intensity = 1.05 + currentPalette.warmth * 0.18;