diff --git a/HANDOFF.md b/HANDOFF.md index 1c7a367..c4fb54a 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -443,6 +443,11 @@ that holds that height all the way out instead of sloping to the ground — that makes the rest possible. Sloping, it lay flat on the grass across the whole far half, so there was nothing for it to cut exactly where the crowd stands. +- **The cone's opacity and the over/under read are the SAME dial, and they pull against each other.** + The plane is flat: a body above it is drawn clean on top, a body below is seen THROUGH it — so how + clearly you can tell the two apart just is how opaque the cone is. Oliver asked for a fainter, + bluer cone AND a clearer split; the first wins, and the CUT LINE carries the signal instead. Do not + try to "fix" the split by raising the cone alpha again — that is the thing he asked to come down. - **The fill is TWO gradients**, matching the reference Oliver sent: a horizontal one across the width (near-white down the centre line, falling to the weapon's blue at the edges) and a depth one along the length. Canvas has no 2D gradient, so the wedge is filled in eight slices along its diff --git a/index.html b/index.html index dafc902..8dd8279 100644 --- a/index.html +++ b/index.html @@ -179,6 +179,6 @@ - + diff --git a/render.js b/render.js index 4d7b9e5..ca25911 100644 --- a/render.js +++ b/render.js @@ -631,13 +631,16 @@ function drawBeamWedge(dirX, dirZ, ox, oy, oz, alpha, from) { const wa = wAt(ua), wb = wAt(ub), wm = wAt(um); const a1 = corner(ua, -wa), a2 = corner(ua, wa), b2 = corner(ub, wb), b1 = corner(ub, -wb); const el = corner(um, -wm), er = corner(um, wm); // the across axis, at this slice's width - const k = (0.34 - 0.24 * um) * alpha; // depth: strongest at the strings + // Lower opacity and BLUER. It was near-white down the core at almost double this alpha, which + // veiled the whole cone evenly — and once everything under it is equally washed out, the split + // stops reading: you cannot tell the part above the plane from the part below. + const k = (0.19 - 0.13 * um) * alpha; // depth: strongest at the strings const g = ctx.createLinearGradient(el.x, el.y, er.x, er.y); - g.addColorStop(0, `rgba(${r},${g_},${b},${k * 0.55})`); // edge: the weapon's blue + g.addColorStop(0, `rgba(${r},${g_},${b},${k * 0.5})`); // edge: the weapon's blue g.addColorStop(0.34, `rgba(${r},${g_},${b},${k})`); - g.addColorStop(0.5, `rgba(215,238,255,${k * 1.5})`); // core: near-white, the hot line + g.addColorStop(0.5, `rgba(118,188,255,${k * 1.35})`); // core: a LIT blue, not white g.addColorStop(0.66, `rgba(${r},${g_},${b},${k})`); - g.addColorStop(1, `rgba(${r},${g_},${b},${k * 0.55})`); + g.addColorStop(1, `rgba(${r},${g_},${b},${k * 0.5})`); ctx.fillStyle = g; ctx.beginPath(); ctx.moveTo(a1.x, a1.y); ctx.lineTo(a2.x, a2.y); ctx.lineTo(b2.x, b2.y); ctx.lineTo(b1.x, b1.y); ctx.closePath(); ctx.fill(); @@ -645,7 +648,7 @@ function drawBeamWedge(dirX, dirZ, ox, oy, oz, alpha, from) { // ...and the OUTER LINES. The reference reads as a plane because its edges are drawn, not just // implied by where the fill stops. const c1 = corner(u0, -w0), c2 = corner(u0, w0), c3 = corner(1, w1), c4 = corner(1, -w1); - ctx.strokeStyle = `rgba(190,225,255,${0.5 * alpha})`; + ctx.strokeStyle = `rgba(120,190,255,${0.45 * alpha})`; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(c2.x, c2.y); ctx.lineTo(c3.x, c3.y);