feat: evolve portfolio into an authored midnight grand tour
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
||||
import grandTourerUrl from '@/assets/nightdrive-grand-tourer.glb?url';
|
||||
import grandTourerUrl from '@/assets/nightdrive-grand-tourer-evolution.glb?url';
|
||||
import type { SceneResourceBag } from '@/scene/resources';
|
||||
import type { SceneDetailMode } from '@/scene/types';
|
||||
|
||||
@@ -55,7 +55,7 @@ export async function loadGrandTourer(signal: AbortSignal): Promise<AuthoredCarG
|
||||
if (signal.aborted) throw new DOMException('Scene build aborted', 'AbortError');
|
||||
const gltf = await new GLTFLoader().parseAsync(bytes, GRAND_TOURER_URL);
|
||||
if (signal.aborted) throw new DOMException('Scene build aborted', 'AbortError');
|
||||
const authored = gltf.scene.getObjectByName('chase-car') ?? gltf.scene;
|
||||
const authored = gltf.scene.getObjectByName('evolution-chase-car') ?? gltf.scene.getObjectByName('chase-car') ?? gltf.scene;
|
||||
authored.removeFromParent();
|
||||
return authored as AuthoredCarGroup;
|
||||
}
|
||||
@@ -253,6 +253,8 @@ export function createCar(
|
||||
vec2 centered = (vGlowUv - 0.5) * vec2(1.55, 1.0);
|
||||
float glow = 1.0 - smoothstep(0.12, 0.72, length(centered));
|
||||
gl_FragColor = vec4(uColor, glow * uOpacity);
|
||||
#include <tonemapping_fragment>
|
||||
#include <colorspace_fragment>
|
||||
}
|
||||
`,
|
||||
transparent: true,
|
||||
@@ -355,7 +357,9 @@ function createAuthoredCar(
|
||||
const tailMaterials: AuthoredMaterial[] = [];
|
||||
const cyanMaterials: AuthoredMaterial[] = [];
|
||||
authoredModel.traverse((object) => {
|
||||
if (object.name.endsWith('.001')) object.name = object.name.slice(0, -4);
|
||||
if (object.name.startsWith('evolution-')) object.name = object.name.slice('evolution-'.length);
|
||||
// Three removes Blender's suffix dot when sanitizing imported node names.
|
||||
object.name = object.name.replace(/\.?\d{3}$/u, '');
|
||||
if (!object.isMesh || !object.geometry || !object.material) return;
|
||||
resources.own('geometry', object.geometry);
|
||||
const materials = Array.isArray(object.material) ? object.material : [object.material];
|
||||
@@ -367,7 +371,7 @@ function createAuthoredCar(
|
||||
&& (object.name === 'car-body' || object.name === 'body-haunches')
|
||||
) {
|
||||
material.emissive?.setHex(0x0b2738);
|
||||
material.emissiveIntensity = 0.58;
|
||||
material.emissiveIntensity = 0.26;
|
||||
}
|
||||
if (material.isMeshStandardMaterial && object.name === 'rear-glass') {
|
||||
material.emissive?.setHex(0x041725);
|
||||
@@ -405,6 +409,8 @@ function createAuthoredCar(
|
||||
vec2 centered = (vGlowUv - 0.5) * vec2(1.7, 1.0);
|
||||
float glow = 1.0 - smoothstep(0.08, 0.74, length(centered));
|
||||
gl_FragColor = vec4(uColor * 1.35, glow * uOpacity);
|
||||
#include <tonemapping_fragment>
|
||||
#include <colorspace_fragment>
|
||||
}
|
||||
`,
|
||||
transparent: true,
|
||||
@@ -464,7 +470,7 @@ function createAuthoredCar(
|
||||
group.position.y = baseY - squat + vibration;
|
||||
group.rotation.x = -squat * 0.035;
|
||||
group.rotation.z = Math.sin(elapsed * 0.8) * safeSpeed * 0.0018;
|
||||
for (const material of tailMaterials) material.emissiveIntensity = 4.4 + response * 3.2;
|
||||
for (const material of tailMaterials) material.emissiveIntensity = 2.2 + response * 1.2;
|
||||
for (const material of cyanMaterials) material.emissiveIntensity = 2.2 + response * 1.6;
|
||||
underglowUniforms.uOpacity.value = 0.09 + safeSpeed * 0.04 + response * 0.075;
|
||||
contact.uniforms.uOpacity.value = 0.21 + response * 0.055;
|
||||
@@ -497,6 +503,8 @@ function createContactShadow(
|
||||
vec2 centered = (vShadowUv - 0.5) * vec2(1.65, 1.0);
|
||||
float shadow = 1.0 - smoothstep(0.16, 0.72, length(centered));
|
||||
gl_FragColor = vec4(vec3(0.002, 0.004, 0.008), shadow * uOpacity);
|
||||
#include <tonemapping_fragment>
|
||||
#include <colorspace_fragment>
|
||||
}
|
||||
`,
|
||||
transparent: true,
|
||||
|
||||
Reference in New Issue
Block a user