Self-feedback ghosts.
GLSL fragment shader
The effect's own code. The uniforms and helpers above it — uTex, uFeedback, the depth proxy, the frame ring, depthAt(), timeAt() — are the same header every Ether-MOSH shader opens with, and are documented once on the registry rather than reprinted on all 143 pages.
void main(){ // Phosphor persistence rather than a three-tap lighten. Bright areas burn a // decaying trail into the frame the way a CRT does, which is a different // idea from Echo Trails' rotating ghosts and no longer reads like haze. vec4 curTex = texture2D(uTex, vUv); vec3 cur = curTex.rgb; vec3 burn = vec3(0.0); float w = 0.0; vec2 drift = vec2(uOffset, uOffset * 0.45); for (int i = 1; i < 7; i++) { float t = float(i); vec3 s = texture2D(uTex, clamp(vUv - drift * t, 0.0, 1.0)).rgb; // Only what was bright leaves a trail — that is what makes it phosphor. float hot = max(0.0, dot(s, vec3(0.299, 0.587, 0.114)) - 0.34); float k = exp(-t * 0.55); burn += s * hot * k; w += k; } burn /= max(w, 0.001); // Trails skew green-white as real phosphor decay does. vec3 col = cur + burn * vec3(0.72, 1.0, 0.80) * uAmount * 4.5; // The burn is an additive glow within the current frame's own // silhouette, not a separate object, so alpha just follows the base // sample rather than blending in the trail taps' own alpha. gl_FragColor = vec4(col, curTex.a); }