Fog of war: unexplored is black, fades ease into it with no stepped rim (t17)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 12:59:00 -04:00
co-authored by Claude Opus 5.5
parent ab61d6b904
commit 841efd2546
8 changed files with 38 additions and 17 deletions
+11 -6
View File
@@ -23,7 +23,7 @@ function drawWorld() {
}
}
const useFog = SET.fog;
const OUT = sm ? 0x040a0a0c : 0xff0a0a0c;
const OUT = sm ? 0x04000000 : 0xff000000; // unexplored and off the map: black
const lighting = SET.lighting !== 'off' && !R.lens;
if (lighting && (R.frame % SET.lightEvery === 0 || !R.lw)) computeLight();
const grain = SET.grain, incand = SET.incandescence;
@@ -35,22 +35,27 @@ function drawWorld() {
for (let by = 0; by < bh; by++) {
const y = vy0 + by;
const row = by * bw;
if (y < 0 || y >= H) { for (let bx = 0; bx < bw; bx++) { px[row + bx] = OUT; if (sm) { bpx[row + bx] = 0x000a0a0c; tpx[row + bx] = 0; fpx[row + bx] = 0xff; } } continue; }
if (y < 0 || y >= H) { for (let bx = 0; bx < bw; bx++) { px[row + bx] = OUT; if (sm) { bpx[row + bx] = 0; tpx[row + bx] = 0; fpx[row + bx] = 0xff; } } continue; }
const fy = y / FOG, fj = Math.floor(fy), ft = fy - fj, fr = fj * FW, fn = Math.min(FH - 1, fj + 1) * FW;
const yw = y * W;
let skr = SKY_R[y], skg = SKY_G[y], skb = SKY_B[y];
if (rk > 0.01) { const gy = (skr + skg + skb) / 3 * 0.82; skr += (gy - skr) * rk * 0.7; skg += (gy - skg) * rk * 0.7; skb += (gy - skb) * rk * 0.65; }
for (let bx = 0; bx < bw; bx++) {
const x = vx0 + bx;
if (x < 0 || x >= W) { px[row + bx] = OUT; if (sm) { bpx[row + bx] = 0x000a0a0c; tpx[row + bx] = 0; fpx[row + bx] = 0xff; } continue; }
if (x < 0 || x >= W) { px[row + bx] = OUT; if (sm) { bpx[row + bx] = 0; tpx[row + bx] = 0; fpx[row + bx] = 0xff; } continue; }
let fv = 255;
if (useFog) {
const fx = x / FOG, j = Math.floor(fx), t = fx - j, j1 = Math.min(FW - 1, j + 1);
const a = fog[fr + j], b = fog[fr + j1], c = fog[fn + j], d = fog[fn + j1];
if ((a & b & c & d) !== 255) fv = (a + (b - a) * t) * (1 - ft) + (c + (d - c) * t) * ft;
if (!fv) { px[row + bx] = OUT; if (sm) { bpx[row + bx] = 0x000a0a0c; tpx[row + bx] = 0; fpx[row + bx] = 0xff; } continue; }
// Stable grain noise breaks up the half-resolution fog's stepped edges.
if (fv < 255) fv = Math.max(1, Math.min(255, fv + (noiseB[yw + x] - 128) * (40 / 128)));
if (!fv) { px[row + bx] = OUT; if (sm) { bpx[row + bx] = 0; tpx[row + bx] = 0; fpx[row + bx] = 0xff; } continue; }
// ease the fade into black (smoothstep) and break up the half-resolution steps with grain
// noise that is strongest mid-fade and nothing at either end, so the outer edge has no rim
if (fv < 255) {
let s = fv / 255;
s = Math.min(1, Math.max(0, s + (noiseB[yw + x] - 128) * (0.6 / 128) * s * (1 - s)));
fv = Math.max(1, 255 * s * s * (3 - 2 * s));
}
}
const i = yw + x, m = mat[i], nz = noiseB[i] - 128;
const T = temp[i];
+2 -1
View File
@@ -25,7 +25,8 @@ function fogLook(cx, cy) {
if (x < 0 || y < 0 || x >= W || y >= H) break;
const ph = PH[mat[y * W + x]];
if (hit < 0 && (ph === PH_SOLID || ph === PH_POWDER)) hit = d;
const v = Math.min(255, (48 - d) * 255 / 16, hit < 0 ? 255 : (8 - d + hit) * 255 / 8);
// into rock, sight fades out over 8 grains from however bright it arrived
const v = Math.min(255, (48 - d) * 255 / 16) * (hit < 0 ? 1 : (8 - d + hit) / 8);
if (v <= 0) break;
fogMark(x, y, v);
}