One commited on
Commit
bccd59e
·
verified ·
1 Parent(s): 8b491b6

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +26 -9
index.html CHANGED
@@ -1489,8 +1489,8 @@ function stalkCurveX(w, f) {
1489
  // rigid sprite rotation. Far stalks get a soft low-alpha halo pass to keep their
1490
  // "far away" look without any runtime blur filters (no slowdown).
1491
  function drawBackSeaweeds(t) {
1492
- ctx.save();
1493
- ctx.filter = 'blur(2px)'; // v5.1: added softness to nearer background seaweed
1494
  for (const w of backSeaweeds) {
1495
  const baseY = sandAt(w.x) + 10;
1496
  const n = w.segs;
@@ -1503,8 +1503,9 @@ function drawBackSeaweeds(t) {
1503
  Math.sin(t * w.waveF2 + w.wavePh2 + f * 3.8) * w.waveA2 * f * f +
1504
  Math.sin(t * w.waveF3 + w.wavePh3 + f * 5.4) * w.waveA3 * f;
1505
 
1506
- for (let pass = 0; pass < (w.near ? 1 : 2); pass++) {
1507
- const isHalo = !w.near && pass === 0;
 
1508
  ctx.strokeStyle = isHalo ? haloStyle : coreStyle;
1509
  ctx.lineCap = 'round';
1510
  ctx.lineJoin = 'round';
@@ -1576,7 +1577,6 @@ function drawBackSeaweeds(t) {
1576
  }
1577
  }
1578
  }
1579
- ctx.restore();
1580
  }
1581
 
1582
  // v5: pre-render ultra-far seaweed sprites with heavy blur baked in at build time
@@ -2009,12 +2009,24 @@ function drawFgGrass(t) {
2009
  }
2010
  }
2011
 
2012
- function drawVignette() {
2013
- const g = ctx.createRadialGradient(W / 2, H * 0.45, Math.min(W, H) * 0.35, W / 2, H * 0.55, Math.max(W, H) * 0.78);
 
 
 
 
 
 
 
 
2014
  g.addColorStop(0, "rgba(0,0,0,0)");
2015
  g.addColorStop(1, "rgba(0,10,20,0.45)");
2016
- ctx.fillStyle = g;
2017
- ctx.fillRect(0, 0, W, H);
 
 
 
 
2018
  }
2019
 
2020
  // --- v8: mild film grain over the whole scene.
@@ -2047,7 +2059,9 @@ function drawGrain() {
2047
  grainOx = (Math.random() * GRAIN_TILE) | 0;
2048
  grainOy = (Math.random() * GRAIN_TILE) | 0;
2049
  lastGrainTime = now;
 
2050
  }
 
2051
  const ox = grainOx, oy = grainOy;
2052
  ctx.save();
2053
  ctx.globalCompositeOperation = "overlay";
@@ -2056,7 +2070,9 @@ function drawGrain() {
2056
  ctx.fillStyle = grainPattern;
2057
  ctx.fillRect(0, 0, W + GRAIN_TILE, H + GRAIN_TILE); // cover full screen even with offset
2058
  ctx.restore();
 
2059
  }
 
2060
 
2061
  // Precomputed static layers — the sand and rocks never move, so they are
2062
  // rendered once to an offscreen canvas and blitted each frame (v6) instead of
@@ -2163,6 +2179,7 @@ function doResize() {
2163
  resize();
2164
  buildRaySprites(); // v23: rebuild the pre-blurred beam sprites for the new size
2165
  buildFarSeaweedSprites(); // v5: rebuild ultra-far seaweed sprites for new size
 
2166
  buildStaticLayer();
2167
  if (!grainPattern) buildGrainTile(); // v8: grain tile is size-independent, build once
2168
  }
 
1489
  // rigid sprite rotation. Far stalks get a soft low-alpha halo pass to keep their
1490
  // "far away" look without any runtime blur filters (no slowdown).
1491
  function drawBackSeaweeds(t) {
1492
+ // v6: no runtime canvas filter — blur() forces a CPU re-rasterize every frame
1493
+ // and was the main FPS cost. Softness now comes from the halo pass below instead.
1494
  for (const w of backSeaweeds) {
1495
  const baseY = sandAt(w.x) + 10;
1496
  const n = w.segs;
 
1503
  Math.sin(t * w.waveF2 + w.wavePh2 + f * 3.8) * w.waveA2 * f * f +
1504
  Math.sin(t * w.waveF3 + w.wavePh3 + f * 5.4) * w.waveA3 * f;
1505
 
1506
+ // v6: near stalks also get a halo pass (replaces the old blur(2px) filter)
1507
+ for (let pass = 0; pass < 2; pass++) {
1508
+ const isHalo = pass === 0; // v6: every stalk gets a halo pass (replaces the old blur filter)
1509
  ctx.strokeStyle = isHalo ? haloStyle : coreStyle;
1510
  ctx.lineCap = 'round';
1511
  ctx.lineJoin = 'round';
 
1577
  }
1578
  }
1579
  }
 
1580
  }
1581
 
1582
  // v5: pre-render ultra-far seaweed sprites with heavy blur baked in at build time
 
2009
  }
2010
  }
2011
 
2012
+ // v6: vignette is static -> pre-render once per resize, blit each frame
2013
+ // (cheaper than recreating the radial gradient + full-screen fill every frame)
2014
+ let vignetteLayer = null;
2015
+ function buildVignette() {
2016
+ vignetteLayer = document.createElement("canvas");
2017
+ vignetteLayer.width = canvas.width;
2018
+ vignetteLayer.height = canvas.height;
2019
+ const c2 = vignetteLayer.getContext("2d");
2020
+ c2.setTransform(ctx.getTransform());
2021
+ const g = c2.createRadialGradient(W / 2, H * 0.45, Math.min(W, H) * 0.35, W / 2, H * 0.55, Math.max(W, H) * 0.78);
2022
  g.addColorStop(0, "rgba(0,0,0,0)");
2023
  g.addColorStop(1, "rgba(0,10,20,0.45)");
2024
+ c2.fillStyle = g;
2025
+ c2.fillRect(0, 0, W, H);
2026
+ }
2027
+ function drawVignette() {
2028
+ if (!vignetteLayer) return;
2029
+ ctx.drawImage(vignetteLayer, 0, 0, W, H);
2030
  }
2031
 
2032
  // --- v8: mild film grain over the whole scene.
 
2059
  grainOx = (Math.random() * GRAIN_TILE) | 0;
2060
  grainOy = (Math.random() * GRAIN_TILE) | 0;
2061
  lastGrainTime = now;
2062
+ lastGrainDrawn = false; // offset changed -> must repaint
2063
  }
2064
+ if (lastGrainDrawn) return; // v6: skip the full-screen overlay blend when nothing changed
2065
  const ox = grainOx, oy = grainOy;
2066
  ctx.save();
2067
  ctx.globalCompositeOperation = "overlay";
 
2070
  ctx.fillStyle = grainPattern;
2071
  ctx.fillRect(0, 0, W + GRAIN_TILE, H + GRAIN_TILE); // cover full screen even with offset
2072
  ctx.restore();
2073
+ lastGrainDrawn = true;
2074
  }
2075
+ let lastGrainDrawn = false;
2076
 
2077
  // Precomputed static layers — the sand and rocks never move, so they are
2078
  // rendered once to an offscreen canvas and blitted each frame (v6) instead of
 
2179
  resize();
2180
  buildRaySprites(); // v23: rebuild the pre-blurred beam sprites for the new size
2181
  buildFarSeaweedSprites(); // v5: rebuild ultra-far seaweed sprites for new size
2182
+ buildVignette(); // v6: rebuild the static vignette layer
2183
  buildStaticLayer();
2184
  if (!grainPattern) buildGrainTile(); // v8: grain tile is size-independent, build once
2185
  }