Make attack ring size tunable and increase it to 30px

The transport-target ring size was hardcoded as RING_SCREEN_PX in
attack-ring.vert.glsl. Promote it to a uRingScreenPx uniform fed from
a new fx.attackRingScreenPx entry in render-settings.json, with an
"Attack Ring Size (px)" slider in the debug GUI's FX folder.

Also bump the size from 20 to 30 screen px so the ring is easier
to spot. The inner/outer ring fractions (0.5/0.8 of the quad) stay
shader constants.
This commit is contained in:
evanpelle
2026-06-12 15:41:03 -07:00
parent 03b405eea7
commit ac6d8d739a
5 changed files with 18 additions and 4 deletions
+1
View File
@@ -257,6 +257,7 @@ export interface RenderSettings {
};
fx: {
shockwaveRingWidth: number;
attackRingScreenPx: number; // screen px — attack ring quad half-size (visible outer ring = 0.8×)
nukeShockwaveDurationMs: number;
nukeShockwaveRadiusFactor: number;
samShockwaveDurationMs: number;
+9
View File
@@ -332,6 +332,15 @@ export function buildTree(s: RenderSettings, d: RenderSettings): DebugNode[] {
folder("FX", [
slider(s.fx, "shockwaveRingWidth", d.fx, 0.01, 0.2, 0.005),
slider(
s.fx,
"attackRingScreenPx",
d.fx,
5,
60,
1,
"Attack Ring Size (px)",
),
slider(
s.fx,
"nukeShockwaveDurationMs",
@@ -50,6 +50,7 @@ export class FxAttackRingPass {
private uTilesPerPx: WebGLUniformLocation;
private uTime: WebGLUniformLocation;
private uRingWidth: WebGLUniformLocation;
private uRingScreenPx: WebGLUniformLocation;
private vao: WebGLVertexArrayObject;
private instanceBuf: DynamicInstanceBuffer;
private ringCount = 0;
@@ -65,6 +66,7 @@ export class FxAttackRingPass {
this.uTilesPerPx = gl.getUniformLocation(this.program, "uTilesPerPx")!;
this.uTime = gl.getUniformLocation(this.program, "uTime")!;
this.uRingWidth = gl.getUniformLocation(this.program, "uRingWidth")!;
this.uRingScreenPx = gl.getUniformLocation(this.program, "uRingScreenPx")!;
const glBuf = gl.createBuffer()!;
this.instanceBuf = new DynamicInstanceBuffer(
@@ -182,6 +184,7 @@ export class FxAttackRingPass {
gl.uniform1f(this.uTilesPerPx, 1 / zoom);
gl.uniform1f(this.uTime, performance.now() / 1000);
gl.uniform1f(this.uRingWidth, this.settings.fx.shockwaveRingWidth);
gl.uniform1f(this.uRingScreenPx, this.settings.fx.attackRingScreenPx);
gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuf.buffer);
gl.bufferSubData(
gl.ARRAY_BUFFER,
@@ -216,6 +216,7 @@
},
"fx": {
"shockwaveRingWidth": 0.04,
"attackRingScreenPx": 30,
"nukeShockwaveDurationMs": 1500,
"nukeShockwaveRadiusFactor": 1.5,
"samShockwaveDurationMs": 800,
@@ -6,18 +6,18 @@ layout(location = 1) in vec3 aInstData; // x, y, alpha
uniform mat3 uCamera;
uniform float uTilesPerPx;
// Quad half-size in screen px; visible outer ring = 0.8× (frag OUTER_R),
// the rest is headroom for SDF AA.
uniform float uRingScreenPx;
out vec2 vLocalPos;
flat out float vAlpha;
// Upstream outer ring = 16 screen-px; quad needs headroom for SDF AA.
const float RING_SCREEN_PX = 20.0;
void main() {
vec2 center = vec2(aInstData.x + 0.5, aInstData.y + 0.5);
vAlpha = aInstData.z;
float worldRadius = RING_SCREEN_PX * uTilesPerPx;
float worldRadius = uRingScreenPx * uTilesPerPx;
vec2 worldPos = center + (aPos - 0.5) * worldRadius * 2.0;
vec3 clip = uCamera * vec3(worldPos, 1.0);