Skip to content

Tutorial Display Filters and Shaders

johnjohto edited this page Jul 25, 2026 · 1 revision

Tutorial: Display Filters and Project Shaders

Two separate layers share one render mechanism: filters belong to the player, post shaders belong to your project.

Player-side: display filters

While playing any project, press F10 to cycle the built-in filters:

  • lcd — a logical-pixel grid
  • crt — scanlines and a vignette
  • contrast — a maximum-contrast luminance quantize (hue-independent, composes with any palette; an accessibility mode)

The choice persists in the player's own config (user://display.cfg) — it is a user preference, never project data. A one-run override exists for launches: --filter=crt (an unknown name refuses loudly). Automated runs force filters off so test renders stay deterministic.

Creator-side: project post shaders

Your project can ship ordered GPU post-process passes. Declare them in presentation/version.json:

{"post_shaders": ["glow.gdshader"]}

…and put the file(s) in presentation/shaders/. Rules:

  • Godot canvas_item shaders only — a missing file or a non-canvas_item shader refuses at boot naming it.
  • Passes run in declared order, before the player's filter.
  • Shaders are GPU-only code: they cannot touch game state, files, or the network, so the sandbox model holds by construction.

The Vermilion overlay's vermilion_glow.gdshader (a ~3% warm center pool) is the shipped example of a full-frame mood pass.

The mechanism (for the curious)

The engine lazily builds a chain of back-buffer copies + full-frame passes above the effects layer, following the bounded-viewport frame wherever it goes. A project with no shaders and a player with no filter build zero extra nodes — the faithful default renders exactly as before.

Clone this wiki locally