How to Configure CRT Shaders for an Authentic Retro Look
Configure RetroArch CRT shaders from an official preset, then calibrate geometry, scanlines, mask, brightness, scaling, performance, and preset scope.
A CRT shader is a model, not a time machine. It can simulate scanline structure, phosphor masks, beam spread, bloom, curvature, halation, and analog softness, but the result depends on source resolution, region, display resolution, subpixel layout, brightness, viewing distance, and the reference CRT being approximated.
Build from a known preset, preserve the original, tune with test material, and save changes through RetroArch’s shader-preset system. “Authentic” should name a target—consumer television, professional video monitor, arcade tube, or computer monitor—rather than one universal look.
Step 1: establish correct geometry before styling
Disable shaders and overlays. Set the core’s intended aspect ratio, crop/overscan policy, output resolution, and refresh synchronization. Verify circles are round and edges are not double-cropped. A shader cannot repair a stretched viewport; curvature can make the error harder to notice.
Use a game you legally own plus non-copyrighted test patterns where available. Capture the baseline and record RetroArch/core versions, region, video driver, fullscreen resolution, integer-scaling state, and display picture mode.
Step 2: install shaders from the supported source
RetroArch can update shader packs through Main Menu → Online Updater. Available types depend on the active video driver: Slang presets are used with several modern backends, GLSL with compatible OpenGL paths, and older Cg support is platform-limited/deprecated.
Do not download an executable “shader installer” or overwrite the full configuration directory with a pack from a video description. Shader presets and textures are data files; use Libretro’s updater or the shader project’s official repository and retain its license/attribution.
Step 3: load a preset from the Quick Menu
Load content, open:
Quick Menu → Shaders → Load Shader Preset
Choose a preset compatible with the active backend. crt-easymode and crt-royale are common Libretro families, but exact filenames and variants depend on the installed pack. Begin with a lighter preset to validate the pipeline, then compare a more complex one.
If the preset fails, check the log for an unsupported shader type, missing texture, invalid path, or framebuffer capability. Do not switch random GPU drivers until the preset’s documented requirements are known.
Step 4: learn what the preset actually exposes
Open Quick Menu → Shaders → Shader Parameters. Parameter names are preset-specific; not every shader has identical “scanline,” “mask,” or “curvature” controls. Change one value, preview it live, and return it before moving to another.
Common groups include:
- beam or scanline width and darkness;
- shadow-mask or aperture-grille pattern and strength;
- horizontal filtering, signal blur, or convergence;
- bloom, halation, glow, and gamma;
- curvature, corner, border, and vignette controls;
- output or mask brightness compensation.
Write down defaults. Extreme values can clip highlights, crush shadow detail, create moiré, or hide UI edges even when the screenshot looks dramatic.
Step 5: calibrate scanlines against source resolution
Test 224/240-line content, any 239-line or high-resolution mode, and interlaced screens separately. Even scanlines require a sensible relationship between source and output pixels. Integer scaling can make that relationship predictable, but it is not mandatory for every advanced shader; some presets implement their own resampling or support non-integer scaling.
Settings → Video → Scaling → Integer Scale
Compare it on and off at the target resolution. At 1080p, 240 does not divide evenly, while higher-resolution panels offer more room for masks and beam profiles. Do not crop essential lines merely to obtain a whole-number scale without documenting the trade-off.
Step 6: select and evaluate the phosphor mask
Mask patterns interact with the physical display’s RGB subpixels. A pattern that looks convincing on one LCD may produce color cast or moiré on OLED, rotated panels, unusual subpixel layouts, projectors, or scaled capture output.
Use neutral gray, white, saturated colors, fine text, and moving content. View at normal distance as well as close-up. Reduce mask strength if color separation dominates the image. Do not copy a mask-size value from a 4K profile into 1080p and assume equivalent behavior.
Step 7: tune brightness and gamma conservatively
Scanlines and masks discard light, so many presets compensate. Set the display to a stable, non-dynamic picture mode and disable automatic contrast during comparison. Adjust shader brightness without clipping a white ramp or erasing dark steps.
Avoid using maximum panel brightness to overcome an excessively dark preset. Long sessions with static borders and high luminance can be undesirable for some display technologies. Follow the display manufacturer’s care guidance and solve darkness in the preset first.
HDR shader workflows require an HDR-capable display, operating-system path, video driver, and preset designed for that output. Do not enable HDR merely because a parameter contains “nits.”
Step 8: decide how much geometry simulation is wanted
Curvature, corner rounding, reflection, and vignette imitate a physical tube and enclosure. They also warp pixels and can conceal edge information. Start at zero, then add a small amount only if it serves the selected reference.
For gameplay or pixel-art analysis, leaving curvature off can be the more honest choice. A flat professional monitor, curved consumer set, and arcade cabinet do not share one geometry. Save separate named presets instead of turning every core into the same television.
Step 9: measure performance and compilation behavior
Record frame time with the preset off, on, and after a restart. Multi-pass presets allocate intermediate framebuffers and can be expensive at 4K. If performance drops below real time, reduce pass complexity or use a lighter official preset before lowering emulation accuracy.
Do not confuse frontend CRT-pass compilation with the core generating host shaders for an emulated 3D GPU. Disable the RetroArch preset and replay the same scene to isolate the layer. Never clear healthy driver caches as routine maintenance.
Step 10: save a shader preset, not merely an override
Libretro documents automatic shader presets under:
Quick Menu → Shaders → Save
Choose Global, Core, Content Directory, or Game scope. The most specific applicable shader preset wins. A Simple Preset can reference the maintained base preset and store parameter differences, making future pack updates easier to audit; changing the pass chain requires a full preset.
Use Core scope for a shared hardware target and Game scope for resolution or artwork exceptions. Do not overwrite the shipped preset. Name the custom file with target display and resolution, and back it up with any referenced textures.
Step 11: validate across content and after restart
Test a second game, menus, dark scenes, bright flashes, scrolling, high-resolution text, PAL/NTSC modes, and rotated content. Restart RetroArch and confirm the automatic preset path resolves. Take lossless screenshots, but remember screenshots cannot reproduce the viewer’s physical subpixel layout or panel response.
Retain a small manifest: base preset path/hash, custom parameter values, video driver, output resolution, scaling, display model/mode, core/content region, and date. The result is successful when geometry remains correct, tones are not clipped, motion is stable, performance stays real time, and the chosen visual target is stated honestly.
Related:
- CRT Shaders and Integer Scaling: Making Old Pixels Look Right on New Screens
- Fixing Shader Compilation Stutter in Emulators and RetroArch
Sources: