Ride sky plays the viz so the paint mirrors something true
Shared sky dome gains an optional viz overlay (off by default; chamber/stage untouched): the running video mixed over the gradient, masked to the upper sky so the horizon stays fog-matched. Same mirrored-sphere projection as the bodywork reflection, so paint and sky agree. Ride binds its vizTarget and holds 0.55.
This commit is contained in:
@@ -44,8 +44,12 @@ function vizEnvMaterial(mat, instance, strength) {
|
||||
{
|
||||
vec3 vDir = normalize( vViewPosition );
|
||||
vec3 rDir = reflect( vDir, normalize( normal ) );
|
||||
// Mirrored azimuth shared with the sky dome (see sky.js):
|
||||
// folds ±π onto the same texel so neither surface shows a seam.
|
||||
float sU = atan( rDir.z, rDir.x ) * 0.15915494 + 0.5;
|
||||
sU = 1.0 - abs( 1.0 - 2.0 * sU );
|
||||
vec2 sUv = vec2(
|
||||
atan( rDir.z, rDir.x ) * 0.15915494 + 0.5,
|
||||
sU,
|
||||
asin( clamp( rDir.y, -1.0, 1.0 ) ) * 0.31830988 + 0.5 );
|
||||
totalEmissiveRadiance += texture2D( u_vizEnv, sUv ).rgb * u_vizEnvStrength;
|
||||
}`
|
||||
@@ -107,6 +111,16 @@ export const ride = {
|
||||
m.userData.vizEnv.value = texture;
|
||||
}
|
||||
}
|
||||
// The sky wears the same video, so the paint mirrors something true.
|
||||
// Same mirrored-sphere projection as the bodywork (see sky.js).
|
||||
if (instance.skyMat) {
|
||||
if (instance.skyMat.uniforms.u_viz.value !== texture) {
|
||||
instance.skyMat.uniforms.u_viz.value = texture;
|
||||
}
|
||||
if (instance.skyMat.uniforms.u_vizAmount.value <= 0) {
|
||||
instance.skyMat.uniforms.u_vizAmount.value = 0.55;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Radio-glow wash for the viz composite — arcs with venueState.light.
|
||||
|
||||
@@ -31,6 +31,11 @@ export function buildSky(THREE, { radius = 90 } = {}) {
|
||||
u_bot: { value: new T.Color(0.02, 0.02, 0.03) },
|
||||
u_bands: { value: 0.0 },
|
||||
u_seed: { value: 0.0 },
|
||||
// The running video, composited elsewhere, overlaid on the dome
|
||||
// so mirrored bodywork has something true to mirror. Off (0)
|
||||
// unless a venue binds a texture — chamber and stage never do.
|
||||
u_viz: { value: null },
|
||||
u_vizAmount: { value: 0.0 },
|
||||
},
|
||||
vertexShader: `
|
||||
varying vec3 vPos;
|
||||
@@ -45,7 +50,19 @@ export function buildSky(THREE, { radius = 90 } = {}) {
|
||||
uniform vec3 u_bot;
|
||||
uniform float u_bands;
|
||||
uniform float u_seed;
|
||||
uniform sampler2D u_viz;
|
||||
uniform float u_vizAmount;
|
||||
varying vec3 vPos;
|
||||
// Mirrored spherical projection shared with the ride's paint
|
||||
// (see vizEnvMaterial): direction to sphere UVs, with the azimuth
|
||||
// folded into a triangle so the ±π wrap lands on the same texel
|
||||
// instead of a visible seam.
|
||||
vec2 skyVizUv(vec3 dir) {
|
||||
float u = atan(dir.z, dir.x) * 0.15915494 + 0.5;
|
||||
u = 1.0 - abs(1.0 - 2.0 * u);
|
||||
float v = asin(clamp(dir.y, -1.0, 1.0)) * 0.31830988 + 0.5;
|
||||
return vec2(u, v);
|
||||
}
|
||||
void main() {
|
||||
float h = normalize(vPos).y; // -1 .. 1
|
||||
vec3 col = h > 0.0
|
||||
@@ -58,6 +75,15 @@ export function buildSky(THREE, { radius = 90 } = {}) {
|
||||
b = smoothstep(0.75, 0.95, b) * u_bands;
|
||||
col += u_top * b * 0.6;
|
||||
}
|
||||
// The viz as the sky itself, mixed over the gradient amount.
|
||||
// Masked to the upper sky: the horizon band stays gradient so
|
||||
// the ground keeps melting into it (fog-matched), while the
|
||||
// zenith plays the video.
|
||||
if (u_vizAmount > 0.001) {
|
||||
vec3 viz = texture2D(u_viz, skyVizUv(normalize(vPos))).rgb;
|
||||
float m = smoothstep(0.02, 0.5, h) * clamp(u_vizAmount, 0.0, 1.0);
|
||||
col = mix(col, viz, clamp(m, 0.0, 1.0));
|
||||
}
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
||||
`,
|
||||
|
||||
Reference in New Issue
Block a user