DIY Cheap Scanlines Effect for Video and Motion Graphics

Cheap Scanlines Effect Tutorial: Real-Time GPU Methods

What this tutorial covers

  • Goal: create a cheap, fast scanlines effect that runs in real time on the GPU for games, live visuals, or video playback.
  • Targets: fragment shader implementations (GLSL/HLSL), simple Unity and Unreal material setups, and performance tips.

Core approach (single-pass fragment shader)

  1. Sample the input texture (screen UVs).
  2. Compute a scanline modulation factor using the fragment’s screen Y coordinate.
  3. Blend the modulation with the sampled color (multiply or mix).
  4. Optionally add jitter, color bleed, and subpixel offsets for realism.

Example GLSL fragment shader (WebGL/OpenGL ES compatible):

glsl

precision mediump float; uniform sampler2D u_tex; uniform float u_scanlineWidth;// e.g., 2.0 uniform float u_intensity; // 0.0 - 1.0 uniform float u_time; // for optional jitter varying vec2 v_uv; void main() { vec4 color = texture2D(u_tex, v_uv); // Normalize screen Y to pixel rows float rows = float(u_scanlineWidth); float y = v_uv.y * rows; // Create repeating band pattern float band = fract(y); // Optional jitter per-row float jitter = 0.0; // jitter = 0.1 * sin(u_time + floor(y) * 0.7); // Compute modulation: darker on band < 0.5 float mod = smoothstep(0.0, 0.5, band + jitter) (1.0 - smoothstep(0.5, 1.0, band + jitter)); mod = 1.0 - mod; // invert so center of band is darker // Combine with intensity float factor = mix(1.0, mod, u_intensity); gl_FragColor = vec4(color.rgb factor, color.a); }

Unity (URP/HDRP) quick material setup

  • Create an Unlit shader with the fragment logic above or use Shader Graph:
    • Sample Screen Position or UV.
    • Use a Repeat/Modulo on Y to form bands.
    • Remap and smooth (SmoothStep).
    • Multiply color and expose Width and Intensity properties.
  • Apply as a full-screen post-process or as a UI overlay for minimal cost.

Unreal Engine (Material)

  • In a post-process material:
    • Use ScreenPosition node (use raw UV Y).
    • Multiply by a scalar “Scanline Density”.
    • Apply Fraction (Frac) and Smoothstep to shape bands.
    • Lerp between 1 and darkened factor using Intensity.
  • Use a single multiply with the scene color to keep it cheap.

Variations & realism tricks

  • Subpixel color offsets: shift R/G/B by small UV offsets per row for chromatic feel.
  • Horizontal noise/jitter: add a small per-row horizontal offset using a hash of floor(y).
  • Alpha blend overlay vs multiply: overlay preserves highlights; multiply is darker.
  • Vary density with resolution: scale density by screen height to keep look consistent.
  • Use a black/transparent texture (1D) if shader math isn’t available — sample and blend.

Performance tips

  • Keep it in a single fragment pass; avoid branching.
  • Use smoothstep and fract (GPU-friendly).
  • Compute per-pixel only simple math; avoid extra texture fetches.
  • For mobile, reduce precision and lower scanline density.
  • Apply as screen-space post-process; avoid per-object materials unless needed.

Parameters to expose

  • Scanline Density (rows per screen)
  • Intensity (0–1)
  • Width/Softness (smoothstep thresholds)
  • Chromatic Offset (R/G/B shift)
  • Jitter Amount and Speed

Quick recipe (three knobs)

  1. Set Density to screenHeight / 4 for obvious lines.
  2. Intensity = 0.4 for subtle effect.
  3. Width/Softness = 0.15 for smooth bands.

Date: February 7, 2026

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *