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:

  1. Create a CanvasLayer at the top of your scene to ensure the effect is applied globally.
  2. Add a ColorRect node as a child of the CanvasLayer.
  3. Set the ColorRect size to match the screen resolution.
  4. Apply the CRT shader to the ColorRect’s material.
  5. 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;
}
Tags
2d, CRT, mobile
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Simple spatial CRT effect

VHS and CRT monitor effect

CRT shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Frogman
Frogman
2 days ago

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 😀