Asteroids-2026/js/pipelines/CRTPipeline.js

56 lines
1.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// CRTPipeline PostFX pipeline that simulates a classic CRT monitor:
// - Barrel distortion (curved screen edges)
// - Scanlines (every other row darkened)
// - Vignette (edge darkening)
const fragShader = `
precision mediump float;
uniform sampler2D uMainSampler;
uniform vec2 uResolution;
varying vec2 outTexCoord;
void main (void) {
// --- Screen curvature (barrel distortion) ---
// Remap UV from [0,1] to centred [-0.5,0.5], distort, remap back
vec2 uv = outTexCoord;
vec2 dc = uv - 0.5;
float strength = 0.18;
uv = uv + dc * dot(dc, dc) * strength;
// Pixels pushed outside [0,1] become black (the CRT bezel)
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
return;
}
// --- Base colour ---
vec4 color = texture2D(uMainSampler, uv);
// --- Scanlines ---
// Every other screen-pixel row is darkened by ~28%
float lineY = uv.y * uResolution.y;
float scanline = mod(floor(lineY), 2.0);
color.rgb *= mix(1.0, 0.72, scanline);
// --- Vignette ---
float vig = 1.4 - dot(dc * 1.8, dc * 1.8);
vig = clamp(vig, 0.0, 1.0);
vig = pow(vig, 0.45);
color.rgb *= vig;
gl_FragColor = color;
}
`;
export default class CRTPipeline extends Phaser.Renderer.WebGL.Pipelines.PostFXPipeline {
constructor(game) {
super({ game, name: 'CRTPipeline', fragShader });
}
onPreRender() {
this.set2f('uResolution', this.game.scale.width, this.game.scale.height);
}
}