51 lines
1.7 KiB
JavaScript
51 lines
1.7 KiB
JavaScript
export const screenVertexShader = `
|
|
varying vec2 vUv;
|
|
|
|
void main() {
|
|
vUv = uv;
|
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
}
|
|
`;
|
|
|
|
export const screenFragmentShader = `
|
|
varying vec2 vUv;
|
|
uniform sampler2D videoTexture;
|
|
uniform float u_effect_type; // 0: none, 1: warmup, 2: powerdown
|
|
uniform float u_effect_strength; // 0.0 to 1.0
|
|
|
|
void main() {
|
|
vec2 centeredUv = vUv - 0.5;
|
|
vec4 finalColor;
|
|
|
|
if (u_effect_type < 0.5) { // No effect
|
|
finalColor = texture2D(videoTexture, vUv);
|
|
} else if (u_effect_type < 1.5) { // Warm-up effect
|
|
// A bright dot expands to reveal the screen content
|
|
float effectRadius = u_effect_strength * 0.75; // Max radius of 0.75 (sqrt(0.5*0.5 + 0.5*0.5))
|
|
float distanceToCenter = length(centeredUv);
|
|
|
|
// Smoothly transition the edge of the circle
|
|
float vignette = smoothstep(effectRadius, effectRadius - 0.1, distanceToCenter);
|
|
vec4 videoColor = texture2D(videoTexture, vUv);
|
|
|
|
finalColor = videoColor * vignette * u_effect_strength; // Fade in brightness
|
|
|
|
} else { // Power-down effect
|
|
// The image collapses into a bright horizontal line and fades
|
|
float collapseFactor = 1.0 - u_effect_strength;
|
|
|
|
// Squeeze the UVs vertically
|
|
vec2 squeezedUv = vec2(vUv.x, 0.5 + (vUv.y - 0.5) * collapseFactor);
|
|
vec4 videoColor = texture2D(videoTexture, squeezedUv);
|
|
|
|
// Create a bright glow where the line is
|
|
float lineGlow = pow(1.0 - abs(centeredUv.y) / (0.5 * collapseFactor + 0.01), 20.0);
|
|
|
|
finalColor = videoColor * collapseFactor + vec4(0.8, 0.9, 1.0, 1.0) * lineGlow * u_effect_strength;
|
|
|
|
}
|
|
|
|
gl_FragColor = finalColor;
|
|
}
|
|
`;
|