Ride: play the viz on the windshield
The dash radio (0.6x0.35) and lucky billboards were the only viz surfaces, so pinned viz never read on Ride cards. A raked windshield plane across the cabin front carries the same viz texture feed at 4x the area, front-hemisphere only like real glass, with A-pillars seating it. Verified front/rear/side in the orientation rig and viz-bound in full composite.
This commit is contained in:
@@ -42,13 +42,18 @@ export const ride = {
|
|||||||
// Venue RTT: the compositor calls this with the finished viz texture after
|
// Venue RTT: the compositor calls this with the finished viz texture after
|
||||||
// compositing the viz stack into vizTarget. The radio screen samples it,
|
// compositing the viz stack into vizTarget. The radio screen samples it,
|
||||||
// so the viz plays ON the dash rather than composited over the venue —
|
// so the viz plays ON the dash rather than composited over the venue —
|
||||||
// and so does the roadside billboard when the seed placed one.
|
// and so does the windshield below and the roadside billboard when the
|
||||||
|
// seed placed one.
|
||||||
bindVizTexture(instance, texture) {
|
bindVizTexture(instance, texture) {
|
||||||
if (!instance || !texture) return;
|
if (!instance || !texture) return;
|
||||||
if (instance.radioMat && instance.radioMat.emissiveMap !== texture) {
|
if (instance.radioMat && instance.radioMat.emissiveMap !== texture) {
|
||||||
instance.radioMat.emissiveMap = texture;
|
instance.radioMat.emissiveMap = texture;
|
||||||
instance.radioMat.needsUpdate = true;
|
instance.radioMat.needsUpdate = true;
|
||||||
}
|
}
|
||||||
|
if (instance.shieldMat && instance.shieldMat.emissiveMap !== texture) {
|
||||||
|
instance.shieldMat.emissiveMap = texture;
|
||||||
|
instance.shieldMat.needsUpdate = true;
|
||||||
|
}
|
||||||
if (instance.billMat && instance.billMat.emissiveMap !== texture) {
|
if (instance.billMat && instance.billMat.emissiveMap !== texture) {
|
||||||
instance.billMat.emissiveMap = texture;
|
instance.billMat.emissiveMap = texture;
|
||||||
instance.billMat.needsUpdate = true;
|
instance.billMat.needsUpdate = true;
|
||||||
@@ -339,7 +344,7 @@ export const ride = {
|
|||||||
skyMesh: sky.mesh, skyMat: sky.mat,
|
skyMesh: sky.mesh, skyMat: sky.mat,
|
||||||
crew,
|
crew,
|
||||||
ambient, key, tail,
|
ambient, key, tail,
|
||||||
radioMat: null, radioMesh: null, billPanel: null,
|
radioMat: null, radioMesh: null, shieldMat: null, shieldMesh: null, billPanel: null,
|
||||||
bodyMeshes: [],
|
bodyMeshes: [],
|
||||||
seed,
|
seed,
|
||||||
venueSpec: venueSpec || null,
|
venueSpec: venueSpec || null,
|
||||||
@@ -527,6 +532,43 @@ export const ride = {
|
|||||||
instance.radioMesh = radio;
|
instance.radioMesh = radio;
|
||||||
instance.bodyMeshes.push(radio);
|
instance.bodyMeshes.push(radio);
|
||||||
|
|
||||||
|
// Windshield: the viz at a size worth looking at. A raked plane
|
||||||
|
// across the cabin front, same emissiveMap feed as the radio —
|
||||||
|
// the dash screen is for the crew, this is the one the chase
|
||||||
|
// camera actually sees. Front hemisphere only (single-sided):
|
||||||
|
// from behind it reads as dark glass, like a real windshield.
|
||||||
|
// Clears the dash (top 0.87 at z ≥ -1.09) and the crew (z ≥ -0.4).
|
||||||
|
const shieldMat = new T.MeshStandardMaterial({
|
||||||
|
color: new T.Color(0.02, 0.02, 0.02),
|
||||||
|
emissive: new T.Color(1, 1, 1),
|
||||||
|
emissiveIntensity: 1.0,
|
||||||
|
roughness: 0.4, metalness: 0.2,
|
||||||
|
});
|
||||||
|
const shield = new T.Mesh(new T.PlaneGeometry(1.44, 0.44), shieldMat);
|
||||||
|
shield.position.set(0, 0.8, -1.14);
|
||||||
|
// Face up-forward: lookAt aims +z at the target, so the normal
|
||||||
|
// lands ~23° off vertical — a raked windshield, not a billboard.
|
||||||
|
// Car group is at identity in build, so local == world here.
|
||||||
|
shield.lookAt(0, 3.0, -6.0);
|
||||||
|
shield.name = 'windshield';
|
||||||
|
instance.car.add(shield);
|
||||||
|
instance.shieldMat = shieldMat;
|
||||||
|
instance.shieldMesh = shield;
|
||||||
|
instance.bodyMeshes.push(shield);
|
||||||
|
// A-pillars so the glass sits in the car instead of hovering over
|
||||||
|
// it: thin struts from the cabin top to the glass top corners.
|
||||||
|
const pillarMat = new T.MeshStandardMaterial({
|
||||||
|
color: new T.Color(0.05, 0.05, 0.06), roughness: 0.6, metalness: 0.3,
|
||||||
|
});
|
||||||
|
for (const side of [-1, 1]) {
|
||||||
|
const pillar = new T.Mesh(new T.BoxGeometry(0.05, 0.37, 0.05), pillarMat);
|
||||||
|
pillar.position.set(side * 0.7, 0.83, -1.1);
|
||||||
|
pillar.rotation.x = 0.31;
|
||||||
|
pillar.name = 'pillar';
|
||||||
|
instance.car.add(pillar);
|
||||||
|
instance.bodyMeshes.push(pillar);
|
||||||
|
}
|
||||||
|
|
||||||
// Headlight cones: two small translucent wedges so chase mode
|
// Headlight cones: two small translucent wedges so chase mode
|
||||||
// reads. Kept short and faint — long cones filled the frame.
|
// reads. Kept short and faint — long cones filled the frame.
|
||||||
const beamMat = new T.MeshBasicMaterial({
|
const beamMat = new T.MeshBasicMaterial({
|
||||||
@@ -791,6 +833,13 @@ export const ride = {
|
|||||||
instance.radioMat.emissive.setRGB(1, 1, 1);
|
instance.radioMat.emissive.setRGB(1, 1, 1);
|
||||||
instance.radioMat.emissiveIntensity = (params.light || 0.85) * (0.7 + l * 0.7);
|
instance.radioMat.emissiveIntensity = (params.light || 0.85) * (0.7 + l * 0.7);
|
||||||
}
|
}
|
||||||
|
// Windshield glow, same feed, slightly restrained — it is 4x the
|
||||||
|
// radio's area and would blow out at the same intensity.
|
||||||
|
if (instance.shieldMat) {
|
||||||
|
const l = vState ? vState.light : 1;
|
||||||
|
instance.shieldMat.emissive.setRGB(1, 1, 1);
|
||||||
|
instance.shieldMat.emissiveIntensity = (params.light || 0.85) * (0.55 + l * 0.55);
|
||||||
|
}
|
||||||
// Ground follows horizon like the stage field.
|
// Ground follows horizon like the stage field.
|
||||||
instance.road.position.y = -1.15 + (spaceHorizon - 0.5) * 0.6;
|
instance.road.position.y = -1.15 + (spaceHorizon - 0.5) * 0.6;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user