Rotate corridor axes: long axis on canvas Y (vertical)
Previous mapping placed the corridor's long axis (flight direction
+Z) on canvas X (horizontal). User observed this as '90deg to
flight direction' because the tiles appeared to scroll sideways on
screen instead of along depth.
Swap so the long axis is on canvas Y (vertical on canvas):
- drawTileAt: canvasX = (perp + halfPerp + 0.5) * TILE_SIZE,
canvasY = (lng + halfLong + 0.5) * TILE_SIZE
- shader gUv: gUv.x = rotated.y / uGroundSize.x + 0.5 (perp axis),
gUv.y = rotated.x / uGroundSize.y + 0.5 (long axis)
- uGroundSize call: (PERP, LONG) instead of (LONG, PERP)
Now the corridor's long axis runs vertically on canvas. The screen
mapping (uv.y -> forward distance) reads the long axis as a vertical
strip, matching user expectation that 'forward' tiles scroll top-
to-bottom (or bottom-to-top) as the camera flies.
This commit is contained in:
1 parent
faabb44cdb
commit
8a9fbd3956
1 file changed
+14
-12
Vendored
+14
-12
@@ -204,11 +204,15 @@ var FRAG_SRC = [
|
|||||||
'vec3 hitPoint = ro + rd * tGround;',
|
'vec3 hitPoint = ro + rd * tGround;',
|
||||||
// Project hitPoint onto the corridor rotated axes (travel ~35 deg). Then divide by per-axis extent so the corridor maps to UV 0..1. The mosaic canvas is drawn in this rotated frame, so the satellite image comes out oriented correctly.
|
// Project hitPoint onto the corridor rotated axes (travel ~35 deg). Then divide by per-axis extent so the corridor maps to UV 0..1. The mosaic canvas is drawn in this rotated frame, so the satellite image comes out oriented correctly.
|
||||||
'vec2 offset = vec2(hitPoint.x, hitPoint.z) - uGroundCenter;',
|
'vec2 offset = vec2(hitPoint.x, hitPoint.z) - uGroundCenter;',
|
||||||
|
// rotated.x = world Z (corridor long axis, mapped to canvas Y),
|
||||||
|
// rotated.y = -world X (corridor perp, mapped to canvas X).
|
||||||
'vec2 rotated = vec2(offset.x * 0.0 + offset.y * 1.0, -offset.x * 1.0 + offset.y * 0.0);',
|
'vec2 rotated = vec2(offset.x * 0.0 + offset.y * 1.0, -offset.x * 1.0 + offset.y * 0.0);',
|
||||||
'vec2 gUv = rotated / uGroundSize + 0.5;',
|
// Swap components so canvas X = perp direction, canvas Y = long direction
|
||||||
|
'vec2 gUv = vec2(rotated.y / uGroundSize.x + 0.5, rotated.x / uGroundSize.y + 0.5);',
|
||||||
// Soft fade at UV edges so OOB samples blend to fog instead of producing a hard stripe.
|
// Soft fade at UV edges so OOB samples blend to fog instead of producing a hard stripe.
|
||||||
'float perpFade = smoothstep(-0.08, 0.05, gUv.y) * smoothstep(1.08, 0.95, gUv.y);',
|
// After swapping gUv axes, perpFade operates on gUv.x and longFade on gUv.y
|
||||||
'float longFade = smoothstep(-0.08, 0.05, gUv.x) * smoothstep(1.08, 0.95, gUv.x);',
|
'float perpFade = smoothstep(-0.08, 0.05, gUv.x) * smoothstep(1.08, 0.95, gUv.x);',
|
||||||
|
'float longFade = smoothstep(-0.08, 0.05, gUv.y) * smoothstep(1.08, 0.95, gUv.y);',
|
||||||
'float edgeFade = perpFade * longFade;',
|
'float edgeFade = perpFade * longFade;',
|
||||||
'vec3 groundCol = texture2D(uGround, gUv).rgb;',
|
'vec3 groundCol = texture2D(uGround, gUv).rgb;',
|
||||||
'float fogAmount = clamp(tGround / 14.0, 0.0, 1.0);',
|
'float fogAmount = clamp(tGround / 14.0, 0.0, 1.0);',
|
||||||
@@ -315,14 +319,12 @@ function drawTileAt(lng, perp, dx, dz, centerTileX, centerTileY) {
|
|||||||
var halfLong = Math.floor(GROUND_CORRIDOR_LONG / 2);
|
var halfLong = Math.floor(GROUND_CORRIDOR_LONG / 2);
|
||||||
var halfPerp = Math.floor(GROUND_CORRIDOR_PERP / 2);
|
var halfPerp = Math.floor(GROUND_CORRIDOR_PERP / 2);
|
||||||
// Canvas position: place each tile so its CENTRE sits at the
|
// Canvas position: place each tile so its CENTRE sits at the
|
||||||
// rotated-frame coordinate (lng, perp). The shader maps
|
// rotated-frame coordinate (lng, perp), but with lng along canvas Y
|
||||||
// gUv = rotated / uGroundSize + 0.5, so rotated = 0 is at the
|
// (vertical) and perp along canvas X (horizontal). This way the
|
||||||
// canvas centre (canvas_width/2, canvas_height/2). Iterating
|
// corridor's long axis (flight direction +Z) appears as a vertical
|
||||||
// (lng, perp) over [-halfLong..halfLong] means tile centres at
|
// strip on canvas, matching the way depth maps on screen.
|
||||||
// halfLong + 0.5 etc. Without the +0.5 the canvas would be
|
var canvasX = (perp + halfPerp + 0.5) * GROUND_TILE_SIZE;
|
||||||
// half a tile off from the shader's expectation.
|
var canvasY = (lng + halfLong + 0.5) * GROUND_TILE_SIZE;
|
||||||
var canvasX = (lng + halfLong + 0.5) * GROUND_TILE_SIZE;
|
|
||||||
var canvasY = (perp + halfPerp + 0.5) * GROUND_TILE_SIZE;
|
|
||||||
if (canvasX < 0 || canvasX >= groundCanvas.width || canvasY < 0 || canvasY >= groundCanvas.height) {
|
if (canvasX < 0 || canvasX >= groundCanvas.width || canvasY < 0 || canvasY >= groundCanvas.height) {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
@@ -529,7 +531,7 @@ window.clouds3dRender = function(target) {
|
|||||||
y: groundCenterTile.y - GROUND_BASE_Y
|
y: groundCenterTile.y - GROUND_BASE_Y
|
||||||
};
|
};
|
||||||
gl.uniform2f(s.uGroundCenter, centerWorld.x, centerWorld.y);
|
gl.uniform2f(s.uGroundCenter, centerWorld.x, centerWorld.y);
|
||||||
gl.uniform2f(s.uGroundSize, GROUND_CORRIDOR_LONG, GROUND_CORRIDOR_PERP);
|
gl.uniform2f(s.uGroundSize, GROUND_CORRIDOR_PERP, GROUND_CORRIDOR_LONG);
|
||||||
|
|
||||||
var drift = now * speed * 0.12;
|
var drift = now * speed * 0.12;
|
||||||
if (performance.now() - groundLastCheck > 1500) {
|
if (performance.now() - groundLastCheck > 1500) {
|
||||||
|
|||||||
Reference in new issue
Block a user