Simple spatial CRT effect
Simple spatial shaders for a fake CRT effect, useful for in-game screens, e.g. security cameras, when paired with a ViewportTexture
. It provides:
- an overlaid hue (green-ish by default)
- scanlines
- uv distortion with each scanline
Every parameter can be customized through uniforms
.
Shader code
shader_type spatial;
render_mode blend_mix,unshaded;
uniform sampler2D base_texture : hint_albedo;
uniform vec4 hue: hint_color;
uniform bool flip = false;
uniform bool run = true;
uniform float uv_mult : hint_range(1.0, 50.0, .5) = 6.5;
uniform float lines_speed : hint_range(.1, 2.0, .01) = .4;
uniform float line_alpha : hint_range(0.0, 1.0, .01) = .5;
uniform float distortion : hint_range(-1.0, 1.0, .01) = 1.0;
uniform float intensity : hint_range(0.0, 2.0, .01) = 2.0;
uniform float line_definition : hint_range(0.0, 1.0, .01) = .98;
uniform float min_thickness : hint_range(0.0, 1.0, .01) = .03;
float map(float val, float min1, float max1, float min2, float max2)
{
if (val < min1)
{
return min2;
}
if (val > max1)
{
return max2;
}
float delta1 = (max1-min1);
float delta2 = (max2-min2);
float scale = delta2/delta1;
float offset = -min1*scale + min2;
return val*scale + offset;
}
float smooth_compare(float val, float ref, float delta, float harhsness)
{
float diff = abs(val-ref);
return map(diff, harhsness/2.0, delta/2.0, 0.0, 1.0);
}
void fragment() {
float coord = fract(UV.y*uv_mult + TIME*lines_speed*float(run));
float mask = smooth_compare(coord, .5, 1.0 - line_definition, min_thickness);
if (flip)
{
mask = 1.0 - mask;
}
float lines_mult = mask + (1.0 - mask)*(1.0 - line_alpha);
vec2 base_uv = UV;
base_uv.x += (distortion / 100.0)*lines_mult;
vec4 albedo_tex = texture(base_texture,base_uv);
ALBEDO = albedo_tex.rgb * hue.rgb * lines_mult * intensity;
}