Add shoreline facility

This commit is contained in:
2026-04-07 21:26:37 -07:00
parent 7db6259b06
commit 5a7350dbae
20 changed files with 2022 additions and 240 deletions

View File

@@ -0,0 +1,20 @@
#version 330 core
// Feature 9: PPI Shoreline / Terrain — fragment stage
// Active points render in P7 blue; fading points render in P7 greenish-yellow
// with brightness proportional to vFade.
in float vFade;
in float vActive;
uniform vec3 uActiveColor; // P7A blue
uniform vec3 uPersistColor; // P7P greenish yellow
out vec4 fragColor;
void main()
{
if (vFade <= 0.01) discard;
vec3 col = (vActive > 0.5)
? uActiveColor
: uPersistColor * vFade;
fragColor = vec4(col, vFade);
}

View File

@@ -0,0 +1,49 @@
#version 330 core
// Feature 9: PPI Shoreline / Terrain
// Each vertex encodes (bearingDeg, rangeMiles) in polar radar coordinates.
// The vertex shader converts to NDC and computes sweep-based fade on the GPU,
// so the geometry buffer is static — only uniforms change each frame.
layout(location = 0) in vec2 aBearingRange; // x = bearing °CW-from-N, y = range miles
uniform vec2 uCenter; // NDC centre of PPI scope
uniform float uPpiRx; // ppiR * 2.0 / W (one full-radius in NDC, x axis)
uniform float uPpiRy; // ppiR * 2.0 / H (one full-radius in NDC, y axis)
uniform float uMaxRange; // current max range (miles)
uniform float uSweepAngle; // current sweep angle (degrees CW from N)
uniform float uSweepDegPS; // sweep speed (degrees / second)
uniform float uPersist; // phosphor persistence duration (seconds)
out float vFade; // 0..1 brightness multiplier
out float vActive; // 1.0 when sweep head is over this point
const float PI = 3.14159265358979;
const float THRESH = 3.5; // degrees — active window around sweep head
void main()
{
float bearDeg = aBearingRange.x;
float rangeMi = aBearingRange.y;
float rangeFrac = rangeMi / uMaxRange;
// Push out-of-range points outside the NDC clip volume
if (rangeFrac > 1.0) {
gl_Position = vec4(2.0, 2.0, 2.0, 1.0);
vFade = 0.0;
vActive = 0.0;
return;
}
// Convert polar radar coords → NDC
// North (0°) = +Y in NDC; East (90°) = +X in NDC
float bearRad = bearDeg * PI / 180.0;
float nx = uCenter.x + rangeFrac * uPpiRx * sin(bearRad);
float ny = uCenter.y + rangeFrac * uPpiRy * cos(bearRad);
gl_Position = vec4(nx, ny, 0.0, 1.0);
gl_PointSize = 2.0;
// Degrees the sweep has travelled past this point since last illumination
float angBehind = mod(uSweepAngle - bearDeg + 360.0, 360.0);
float timeSinceLit = angBehind / uSweepDegPS;
vFade = clamp(1.0 - timeSinceLit / uPersist, 0.0, 1.0);
vActive = (angBehind < THRESH) ? 1.0 : 0.0;
}