







Bayer matrix + render-time dithering for authentic PSX-style
Greetings, everyone!
Sharing a technique my colleagues (rainlike, gurovsgames001) developed for their Unreal Engine 5 project MATCHLIGHT. They're going for authentic PSX-style visuals, but with a key constraint: no "pasted-on" post-process filter. The retro look is built into the render pipeline itself.
The main goal is to make the scene read correctly before the shader is applied. The level should still work with PSX-era constraints: big silhouettes, clear color blocks, intentional lighting. The shader enhances the vibe, but doesn't carry the design.
Here's the technical breakdown:
1. Pixelization via 4x Bayer matrix
- We sample the original scene color and use it as the basis for thresholding + blending against a 4x Bayer pattern.
- The result isn't just a lower-res frame: color, brightness, and the matrix pattern interact to form chunky, readable color blocks that behave like 3D pixel art.
- This happens during color sampling, not as a full-screen post-process.
2. Integrated dithering pass
- A second dithering pass adds the classic retro screen pattern.
- Critical detail: it lands *inside* the pixels created by the Bayer step, not on top as a separate overlay. This keeps the pattern coherent with the underlying grid instead of looking like random noise.
3. Object-aware jitter
- Global jitter pass for the classic PSX "unstable frame" feel.
- Separate, tuned jitter for small objects to prevent flicker/artifacts on props, distant silhouettes, and fine details.
- This lets us keep the low-poly shake without sacrificing readability.
4. Materials & textures
- Filtering disabled, native texture resolution reduced intentionally.
- Without filtering, edges stay harsh, pixels read "honestly", and the scene avoids modern smoothing that breaks the illusion.
The hardest part of this style isn't just the shader. It's resisting the temptation to fix the image later. If you design the scene assuming PS1 limitations from the start (less micro-noise, stronger composition, deliberate color blocking), the technical pass pushes it over the edge instead of doing all the heavy lifting.
Has anyone worked with similar Bayer-based approaches in UE5? Do you think this pipeline is sustainable for larger scenes, or would you optimize it differently?
Appreciate any thoughts or feedback!