restore spawn-phase glow with a true breathing animation

SpawnOverlayPass had everything wired except a caller. WebGLFrameBuilder
now collects spawned human players each tick during spawn phase and
pushes their territory centroid + color through view.updateSpawnOverlay.
myPlayer reads as white so the local-player ring stands out.

Reshaped the shader animation: dropped the growing-disc effect, gave
the ring a true breath — radius scales 0.5×→1.15× while opacity pulses
35%→100% in phase. Replaced the sharp inner-edge ramp with a smooth
center-to-boundary fill so there's no hard cutoff or empty hole in
the middle. animSpeed bumped to 0.0035 (~1 breath/sec).
This commit is contained in:
evanpelle
2026-05-18 09:43:14 -07:00
parent 61f6d2fdd4
commit 4936ae3d59
3 changed files with 70 additions and 27 deletions
+1 -1
View File
@@ -245,7 +245,7 @@
"selfMaxRad": 24,
"mateMinRad": 5,
"mateMaxRad": 14,
"animSpeed": 0.005,
"animSpeed": 0.0035,
"gradientInnerEdge": 0.01,
"gradientSolidEnd": 0.1
},
@@ -67,34 +67,32 @@ void main() {
continue;
}
// Static outer ring: radial gradient from minR to maxR
float range = maxR - minR;
float t = (dist - minR) / range;
if (t > 0.0 && t <= 1.0) {
float innerEdge = uGradientStops.x;
float solidEnd = uGradientStops.y;
float alpha;
if (t < innerEdge) {
alpha = t / innerEdge;
} else if (t < solidEnd) {
alpha = 1.0;
} else {
alpha = 1.0 - (t - solidEnd) / (1.0 - solidEnd);
}
// Breathing ring: the gradient halo shrinks/expands in radius AND its
// opacity pulses in phase with the breath — both driven by uBreathRadius.
// Smooth bell shape: glow ramps up from center to the inner edge, stays
// solid through the ring's body, then fades out past solidEnd. No hard
// cutoffs at either side.
float scale = 0.5 + 0.65 * uBreathRadius; // 0.5 → 1.15 of base radius
float bMinR = minR * scale;
float bMaxR = maxR * scale;
float range = bMaxR - bMinR;
float t = (dist - bMinR) / range;
float solidEnd = uGradientStops.y;
float alpha = 0.0;
if (dist < bMinR) {
// Inner glow: linear ramp from 0 at center to 1 at the ring's inner edge.
alpha = dist / max(bMinR, 0.001);
} else if (t < solidEnd) {
alpha = 1.0;
} else if (t < 1.0) {
alpha = 1.0 - (t - solidEnd) / (1.0 - solidEnd);
}
if (alpha > 0.0) {
// Opacity pulses 35% → 100% in phase with the radius.
alpha *= 0.35 + 0.65 * uBreathRadius;
result.rgb = mix(result.rgb, color, alpha * (1.0 - result.a));
result.a = result.a + alpha * (1.0 - result.a);
}
// Breathing ring: solid colored disc from minR to breathR
float breathR = minR + range * uBreathRadius;
if (breathR > minR + 0.01) {
if (dist >= minR && dist <= breathR) {
float edge = smoothstep(minR, minR + 0.1, dist);
result.rgb = color;
result.a = max(result.a, edge);
}
}
}
if (result.a < 0.001) discard;