-
-
Notifications
You must be signed in to change notification settings - Fork 113
Shaders
Amiberry supports GPU shaders for post-processing the emulated Amiga output. In addition to the built-in CRT shaders, you can use external GLSL shader files and multi-pass shader presets (.glslp). This allows you to use shaders from the libretro/glsl-shaders repository and other sources.
-
Create the shaders directory (if it doesn't exist):
<xdg_config_home>/shaders/ -
Copy shader files into this directory:
shaders/crt-pi.glsl shaders/crt-aperture.glsl shaders/zfast_crt.glslFor multi-pass presets, place them in subdirectories:
shaders/crt/crt-aperture.glslp shaders/crt/crt-aperture.glsl shaders/bloom/bloom.glslp shaders/bloom/bloom-pass1.glsl shaders/bloom/bloom-pass2.glsl -
Configure Amiberry to use a shader: Edit
amiberry.confand set:shader=crt-pi.glslFor a multi-pass preset:
shader=crt/crt-aperture.glslpOr for RTG mode:
shader_rtg=crt-pi.glsl -
Launch Amiberry - the shader will be loaded automatically!
These are the original crtemu shaders, specified by name:
-
tv- TV CRT effect with heavy scanlines and curvature -
pc- PC monitor effect with lighter scanlines -
lite- Lightweight CRT effect -
1084- Commodore 1084 monitor emulation -
none- No shader (fastest)
Built-in shaders support an optional CRT bezel frame overlay. For custom bezels that work with all shader types, see Custom Bezel Overlays below.
Any .glsl file placed at the top level of the shaders/ directory can be used. Simply specify the filename:
shader=crt-pi.glslshader=crt-aperture.glslshader=zfast_crt.glsl
Note: .glsl files inside subdirectories are treated as shader components (used by presets) and are not listed as standalone shaders.
Amiberry supports .glslp shader preset files, which define multi-pass rendering pipelines. These are compatible with the RetroArch/Libretro .glslp preset format and allow complex effects that chain multiple shader passes together.
Preset files and their associated shader components should be placed in subdirectories under the shaders/ directory:
shaders/
├── my-shader.glsl (single-pass, listed directly)
├── crt/
│ ├── crt-aperture.glslp (preset, listed as "crt/crt-aperture.glslp")
│ └── crt-aperture.glsl (component, not listed separately)
└── bloom/
├── bloom.glslp
├── bloom-pass1.glsl
└── bloom-pass2.glsl
- Multiple shader passes with configurable scale type and factor per pass
-
Scale types:
source(relative to input),viewport(relative to output),absolute(fixed pixel size) - LUT textures: look-up table textures referenced by sampler name (e.g., for color grading)
- Texture filtering: linear or nearest-neighbor per pass
-
Wrap modes:
clamp_to_edge,repeat,clamp_to_border,mirrored_repeat - sRGB and float framebuffers for HDR-capable pipelines
- Mipmap generation on pass inputs
- Frame count modulo for animated effects
- Pass aliases for cross-referencing between passes
-
#referencedirective for inheriting values from a base preset -
#pragma parameterdirectives for runtime-adjustable uniforms
shaders = 2
shader0 = shaders/crt/phosphor.glsl
filter_linear0 = true
scale_type0 = source
scale0 = 2.0
shader1 = shaders/crt/scanlines.glsl
filter_linear1 = true
scale_type1 = viewport
scale1 = 1.0
textures = SamplerLUT1
SamplerLUT1 = shaders/crt/lut.png
SamplerLUT1_linear = trueExternal shaders must be single-pass GLSL shaders compatible with the RetroArch/libretro format.
Fully Compatible (tested and working):
-
crt-pi.glsl- Raspberry Pi optimized CRT shader -
crt-aperture.glsl- CRT with aperture grille -
crt-easymode.glsl- Easy-to-configure CRT -
zfast_crt.glsl- Fast CRT shader
May Need Adaptation:
-
crt-geom.glsl- Geometric CRT (complex) -
crt-lottes.glsl- Lottes CRT (advanced)
Most RetroArch .glslp presets should work, including complex multi-pass pipelines like CRT-Royale. Presets that rely on Cg or Slang shader formats are not supported — only GLSL presets (.glslp referencing .glsl files) are compatible.
Many external shaders define runtime-adjustable parameters via #pragma parameter directives. These allow you to customize the shader's appearance without editing the source.
#pragma parameter CURVATURE_X "Screen curvature - horizontal" 0.10 0.0 1.0 0.01
#pragma parameter SCANLINE_WEIGHT "Scanline weight" 4.0 0.0 15.0 0.1
#pragma parameter MASK_BRIGHTNESS "Mask brightness" 0.70 0.0 1.0 0.05Parameters are exposed in the GUI via the Shader Parameters button in the Filter panel. Each parameter appears as a labeled slider with its valid range, and changes take effect immediately in real time. Click Reset to Defaults to restore all parameters to the values defined in the shader source.
Parameters are supported for both single-pass .glsl shaders and multi-pass .glslp presets. For presets, parameters from all passes are collected and shown together.
If your shader fails to load, check the Amiberry log for error messages:
Loading external shader: crt-pi.glsl
Shader file not found: /path/to/shaders/crt-pi.glsl
Failed to load external shader, falling back to no shader
Solutions:
- Verify the shader file exists in the
shaders/directory - Check the filename spelling in
amiberry.conf - Ensure the file has
.glslor.glslpextension - Check file permissions
For .glslp presets, common issues include:
Loading shader preset: crt/crt-royale.glslp
Failed to load shader preset, falling back to built-in shaders
Solutions:
- Verify all shader files referenced in the preset exist at the expected relative paths
- Check that LUT texture images referenced in the preset are present
- Look at the log for specific pass compilation errors
If the shader compiles but doesn't work correctly:
Shader compilation failed:
ERROR: 0:42: 'unknown_uniform' : undeclared identifier
Solutions:
- The shader may not be compatible with Amiberry's uniform naming
- Try a different shader from the recommended list
- Check the shader's requirements (some need specific uniforms)
macOS uses an OpenGL 3.3 Core Profile with the forward-compatible flag, which strictly requires a #version directive in all GLSL shaders. Many libretro shaders omit #version, relying on the compatibility profile default of GLSL 1.10 (which works on Linux and Windows).
Amiberry automatically detects shaders without a #version directive and injects the appropriate preamble:
-
macOS (Core 3.3+):
#version 330 corewith#definemacros mapping legacy syntax (attribute,varying,texture2D,gl_FragColor) to modern equivalents -
GLES 3.0+ (Android/KMSDRM):
#version 300 eswith precision qualifiers and the same legacy-to-modern mappings -
GL 2.x (compatibility):
#version 120
If you see this error in older versions, update Amiberry. If you're writing custom shaders, include an explicit #version directive to bypass automatic detection.
If you see a black screen after loading a shader:
- The shader may have crashed - check the log
- Try setting
shader=noneto disable shaders - Verify the shader works with other emulators first
Shaders that omit a #version directive will have one injected automatically based on the current GL context. However, for maximum portability, include an explicit #version line and use the appropriate GLSL syntax for your target version. Shaders using legacy syntax (attribute, varying, texture2D, gl_FragColor) without a #version line are automatically adapted for Core Profile and GLES 3.0 contexts via #define macros.
External shaders must follow this structure:
#pragma parameter PARAM_NAME "Description" default min max step
// Uniforms
uniform vec2 TextureSize;
uniform vec2 InputSize;
uniform vec2 OutputSize;
uniform int FrameCount;
uniform mat4 MVPMatrix;
uniform sampler2D Texture;
#if defined(VERTEX)
attribute vec4 VertexCoord;
attribute vec2 TexCoord;
varying vec2 TEX0;
void main() {
gl_Position = MVPMatrix * VertexCoord;
TEX0 = TexCoord;
}
#elif defined(FRAGMENT)
varying vec2 TEX0;
void main() {
vec4 color = texture2D(Texture, TEX0);
gl_FragColor = color;
}
#endifSingle-pass shaders:
-
TextureSize- Size of the input texture (vec2) -
InputSize- Size of the emulated screen (vec2) -
OutputSize- Size of the output window (vec2) -
FrameCount- Current frame number (int) -
MVPMatrix- Model-View-Projection matrix (mat4) -
Texture- Input texture sampler (sampler2D)
Multi-pass presets additionally provide per-pass uniforms:
-
PassPrevN.texture/PassPrevN.video_size/PassPrevN.texture_size- Previous pass outputs -
OriginalHistory.texture/OriginalHistory.video_size- Original unprocessed input - Aliased pass references (e.g.,
BloomPass.textureif a pass hasalias = BloomPass) - LUT sampler uniforms by name (e.g.,
SamplerLUT1)
In addition to shaders, Amiberry supports custom bezel overlays -- PNG images of CRT monitor frames (or any decorative border) that are drawn over the emulator output. Unlike the built-in CRT bezel (which only works with built-in shaders), custom bezels work with all shader types: built-in, external GLSL, and multi-pass presets.
-
Place bezel images in the
Bezels/directory (created automatically):- macOS:
~/Documents/Amiberry/Bezels/ - Linux:
~/.config/amiberry/bezels/ - Windows:
<amiberry_dir>\Bezels\
- macOS:
-
Image requirements:
- Format: PNG or JPEG (PNG recommended for transparency)
- The image should have a transparent area where the emulator screen shows through (the "screen hole")
- Common resolutions: 1920x1080, 2560x1440, or higher
- The bezel is stretched to fill the entire window; the emulator output is automatically fitted within the transparent region
-
Enable in the GUI:
- Go to Filter panel
- In the Bezel Overlay section, select a bezel from the Custom bezel dropdown
- The bezel is applied immediately
Amiberry scans the bezel image's alpha channel to detect the transparent "screen hole" bounding box. The emulator output is then rendered to fill that region exactly, and the bezel is drawn on top as a full-window overlay with alpha blending. This means:
- The screen hole shape is determined by the bezel image itself
- No manual configuration of screen coordinates is needed
- Window resizing automatically scales both the bezel and the screen area
The built-in CRT bezel and custom bezels are mutually exclusive. Selecting a custom bezel disables the built-in one, and vice versa.
Custom bezel settings are saved in amiberry.conf:
use_custom_bezel=yes
custom_bezel=my_monitor.png
bezels_path=/path/to/bezels/
- For best results, use bezel images at your display's native resolution
- Bezels with anti-aliased edges around the screen hole work well -- the alpha detection uses a threshold of 50% opacity
- Subdirectories inside the
Bezels/folder are scanned recursively, so you can organize bezels by category
-
Use simple shaders on low-end hardware (Raspberry Pi 3/4)
-
zfast_crt.glslis the fastest -
crt-pi.glslis optimized for Pi
-
-
Multi-pass presets are more demanding - each pass adds GPU work. On low-end devices, prefer single-pass shaders.
-
Disable shaders for maximum performance
- Set
shader=nonein amiberry.conf
- Set
-
Test different shaders to find the best balance of quality and performance.
If you encounter issues with shaders:
- Check the Amiberry log file
- Try a different shader from the recommended list
- Report issues on the Amiberry GitHub
- Home
- Quick Start
- Troubleshooting
- Frequently Asked Questions
- Paths and Files
- Kickstart ROMs (BIOS)
- Amiberry Directories
- Compile from Source
- Using Amiberry with RetroPie
- How to Enable Integer Scaling
- About
- Paths
- Quickstart
- Configurations
- CPU and FPU
- Chipset
- Adv. Chipset
- ROM
- RAM
- Floppy Drives
- Hard Drives/CD
- Expansions
- RTG Board
- Hardware Info
- Display
- Filter
- Sound
- Input
- I/O Ports
- Custom Controls
- Disk Swapper
- Miscellaneous
- Priority
- Savestates
- Virtual Keyboard
- WHDLoad
- Input Mapping Guide
- Setting up Input Controllers
- Setting up Keyboard Controllers
- Custom Events
- RetroArch Commands
- Mouse/Joystick Autoswitching