Soften UV edges + smaller refetch shifts
Two visual issues reported: stripes from sides at tilts of view, and tiles 'hopping' one tile per refetch. Stripes: caused by gUv.y going OOB at sideways rays where hitPoint.x is large; CLAMP_TO_EDGE returned the same edge colour across a wide band, looking like a stripe. Added shader edgeFade that fades OOB samples smoothly to uBg instead. Hopping: each refetch shifts centerTile by many tiles (depends on when in the cycle it fires). With BUFFER_LONG = 1 (refetch at projLong > halfLong - 1 = 11), the centerTile only ever shifts by about 1 tile per refetch. Refetches happen more often (~ every 8 sec instead of ~ every 96 sec) but each is tiny. reverted partial-refetch optimisation: causes ghosting because old tiles stay at old canvas positions but uGroundCenter moves, so the shader samples stale content. Better to clear canvas and rely on edgeFade to hide the brief fog state.
This commit is contained in:
1 parent
af5cda467f
commit
a3f5bf6084
1 file changed
+11
-5
Vendored
+11
-5
@@ -206,9 +206,15 @@ var FRAG_SRC = [
|
|||||||
'vec2 offset = vec2(hitPoint.x, hitPoint.z) - uGroundCenter;',
|
'vec2 offset = vec2(hitPoint.x, hitPoint.z) - uGroundCenter;',
|
||||||
'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;',
|
'vec2 gUv = rotated / uGroundSize + 0.5;',
|
||||||
|
// 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);',
|
||||||
|
'float longFade = smoothstep(-0.08, 0.05, gUv.x) * smoothstep(1.08, 0.95, gUv.x);',
|
||||||
|
'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);',
|
||||||
'groundCol = mix(groundCol, uBg, fogAmount);',
|
'groundCol = mix(groundCol, uBg, fogAmount);',
|
||||||
|
// Edge fade: ground smoothly disappears near canvas boundary.
|
||||||
|
'groundCol = mix(uBg, groundCol, edgeFade);',
|
||||||
// Ground mask: full ground when looking down, none when up.
|
// Ground mask: full ground when looking down, none when up.
|
||||||
'float gmask = (tGround > 0.0) ? smoothstep(0.0, -0.10, rd.y) : 0.0;',
|
'float gmask = (tGround > 0.0) ? smoothstep(0.0, -0.10, rd.y) : 0.0;',
|
||||||
'col = mix(col, groundCol, gmask);',
|
'col = mix(col, groundCol, gmask);',
|
||||||
@@ -277,7 +283,7 @@ var GROUND_TRAVEL_COS = 0.0; // cos(90 deg)
|
|||||||
var GROUND_TRAVEL_SIN = 1.0; // sin(90 deg)
|
var GROUND_TRAVEL_SIN = 1.0; // sin(90 deg)
|
||||||
var GROUND_CORRIDOR_LONG = 25; // tiles along travel direction (~3.5 min of flight at uSpeed=1)
|
var GROUND_CORRIDOR_LONG = 25; // tiles along travel direction (~3.5 min of flight at uSpeed=1)
|
||||||
var GROUND_CORRIDOR_PERP = 5; // tiles perpendicular to travel
|
var GROUND_CORRIDOR_PERP = 5; // tiles perpendicular to travel
|
||||||
var GROUND_BUFFER_LONG = 3; // refetch when this close to forward edge
|
var GROUND_BUFFER_LONG = 1; // refetch when this close to forward edge
|
||||||
var GROUND_BUFFER_PERP = 1; // refetch when this close to side edge
|
var GROUND_BUFFER_PERP = 1; // refetch when this close to side edge
|
||||||
// Passau tile at zoom 11
|
// Passau tile at zoom 11
|
||||||
var GROUND_BASE_X = 1099;
|
var GROUND_BASE_X = 1099;
|
||||||
@@ -336,13 +342,13 @@ function rebuildGroundMosaic(centerTileX, centerTileY) {
|
|||||||
groundCenterTile = { x: centerTileX, y: centerTileY };
|
groundCenterTile = { x: centerTileX, y: 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);
|
||||||
// Clear with fog colour so the texture is never undefined
|
// Clear with fog colour so we don't get ghosting from old tiles
|
||||||
|
// at wrong canvas positions. The shader's edgeFade makes OOB
|
||||||
|
// samples blend smoothly to uBg, so the brief fog state during
|
||||||
|
// tile fetch is invisible.
|
||||||
groundCtx.fillStyle = '#7c9aa1';
|
groundCtx.fillStyle = '#7c9aa1';
|
||||||
groundCtx.fillRect(0, 0, groundCanvas.width, groundCanvas.height);
|
groundCtx.fillRect(0, 0, groundCanvas.width, groundCanvas.height);
|
||||||
var promises = [];
|
var promises = [];
|
||||||
// Iterate the corridor in its own rotated frame (long, perp),
|
|
||||||
// then map each (long, perp) to a world tile via rotation and to
|
|
||||||
// a canvas pixel via the iteration indices.
|
|
||||||
for (var perp = -halfPerp; perp <= halfPerp; perp++) {
|
for (var perp = -halfPerp; perp <= halfPerp; perp++) {
|
||||||
for (var lng = -halfLong; lng <= halfLong; lng++) {
|
for (var lng = -halfLong; lng <= halfLong; lng++) {
|
||||||
// Tile offset from camera in world (tile) coords, rotated
|
// Tile offset from camera in world (tile) coords, rotated
|
||||||
|
|||||||
Reference in new issue
Block a user