Lightweight CRT Effect
This shader is a lightweight and optimized CRT effect, designed to balance visual quality and performance. I originally created it for a mobile game, as most CRT shaders I tried were too resource-intensive and drained the battery too quickly.
This shader offers a subtle CRT look while remaining efficient, making it ideal for mobile devices or performance-sensitive projects. Several parameters allow you to fine-tune the effect to match your needs:
- scan_line_amount – Adjusts the intensity of scanlines.
- warp_amount – Controls screen curvature distortion.
- vignette_amount & vignette_intensity – Fine-tunes the vignette effect.
- grille_amount – Simulates a pixel grid for a retro feel.
- brightness_boost – Enhances screen brightness.
How to Apply the Shader:
- Create a CanvasLayer at the top of your scene to ensure the effect is applied globally.
- Add a ColorRect node as a child of the CanvasLayer.
- Set the ColorRect size to match the screen resolution.
- Apply the CRT shader to the ColorRect’s material.
- Enable “Expand” to ensure it covers the screen.
Shader code
shader_type canvas_item;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture;
uniform vec2 resolution = vec2(320.0, 180.0);
uniform float scan_line_amount : hint_range(0.0, 1.0) = 0.5;
uniform float warp_amount : hint_range(0.0, 1.0) = 0.05;
uniform float vignette_amount : hint_range(0.0, 1.0) = 0.5;
uniform float vignette_intensity : hint_range(0.0, 1.0) = 0.3;
uniform float grille_amount : hint_range(0.0, 1.0) = 0.05;
uniform float brightness_boost : hint_range(1.0, 2.0) = 1.2;
void fragment() {
vec2 uv = SCREEN_UV;
vec2 delta = uv - 0.5;
float warp_factor = dot(delta, delta) * warp_amount;
uv += delta * warp_factor;
float scanline = sin(uv.y * resolution.y * PI) * 0.5 + 0.5;
scanline = mix(1.0, scanline, scan_line_amount * 0.5); // Réduit l'impact
float grille = mod(uv.x * resolution.x, 3.0) < 1.5 ? 0.95 : 1.05;
grille = mix(1.0, grille, grille_amount * 0.5);
vec3 color = texture(SCREEN_TEXTURE, uv).rgb * scanline * grille;
vec2 v_uv = uv * (1.0 - uv.xy);
float vignette = v_uv.x * v_uv.y * 15.0;
vignette = mix(1.0, vignette, vignette_amount * 0.7);
color *= vignette * brightness_boost;
COLOR.rgb = color;
COLOR.a = 1.0;
}
amazing CRT shader, best one yet IMO. however, there does seem to be a bit of a blurry artifact due to the shader, which idk if thats changable but its nice none the less
also, would be nice to add a black border when you up the warp amount, so it doesnt stretch on the edges 🙂
8/10 😀