RetroArch GLSL shader for 240p CRT output
This is a RetroArch
GLSL shader for scaling a wide
range of emulated consoles, handhelds and arcade systems to look high-quality and
authentic on a standard definition, horizontal, 4:3, CRT TV through a single 240p super
resolution.
I’m using the shader with a customized RetroPie installation on a
Raspberry Pi 3B with a
PI2SCART hat, but it should
work fine with different 240p RGB output solutions or software setups.
While I cannot claim the results to be absolutely perfect, it has certainly satisfied me,
somebody deeply familiar with how most of the systems in RetroPie look as original hardware on
a CRT or through an OSSC. I went from constantly tweaking my RetroArch scaling
options to simply playing games.
If you’ve ever tried to get a number of RetroArch cores emulating dozens of consoles,
handhelds and arcade systems to look correct on your CRT, you don’t need to read this.
You know what a glitchy mess the Settings->Video->Scaling menu is and how ill-equipped
RetroArch scaling is to deal with things like non-square pixel super wide resolutions.
But if you need a reason why this shader exists, let’s see what you’d have to do
without it.
We want want to use a standard definition 4:3 CRT and have configured our system to output
at a reasonable 320x240 resolution. We’ll now go through a few typical game resolutions
and see what we have to do to convince RA to output in a matter that looks authentic and
high quality.
runcommand-onstart.sh
script and chose a different output resolution for each console.CRT Super Resolution?
The idea behind resolutions like 1920x240 is that it allows quality scaling for a range of
horizontal resolutions used by different systems. Vertical resolution mismatches like 224
or 192 lines in a 240 output are resolved by centering, but horizontal resolution
mismatches have to be resolved by stretching / scaling. Stretching 256 to 320 pixels will
always look bad, but 352/320/256 pixels can be quite easily stretched to 1920 or 2048
pixels with minimal scaling artifacts, invisible on a typical consumer CRT display. Since
CRTs do not have a fixed horizontal resolution or any hard upper limit it is possible to
drive even standard definition TVs with 1920, 2048, 3840 etc. horizontal pixels.
Unfortunately, this means our output display will have a non-square pixel aspect ratio,
something RA is not specifically equipped to handle. We’ll need to use the ‘custom’
scaling mode and do all of the aspect ratio and centering computation ourselves.
runcommand-onstart.sh
script. Or manually create a customA typical user trying to figure out the correct width of the image of a 3:4 game
running on a 4:3 TV with a 6:1 pixel aspect ratio
At this point it should be abundantly clear how tedious and complicated configuring
all of this manually is. Thankfully, this shader handles all of the above without any
manual tweaking required or you ever having to get out the calculator to figure out the
correct settings.
These are the setup instructions for RetroPie 4.7.1 running on a series 3 Raspberry Pi.
First, we have to setup super resolution output for all emulators. Since EmulationStation
can’t deal with these we want to use a standard square pixel resolution for it and only
switch to our super resolution for the actual emulators.
A good place to do so are the onstart / onend scripts.
/opt/retropie/configs/all/runcommand-onstart.sh
:
vcgencmd hdmi_timings 1920 1 79 208 241 240 1 6 10 6 0 0 0 60 0 38400000 1 > /dev/null
tvservice -e "DMT 87" > /dev/null
fbset -depth 8 && fbset -depth 16 -xres 1920 -yres 240 > /dev/null
/opt/retropie/configs/all/runcommand-onend.sh
:
vcgencmd hdmi_timings 320 1 11 30 38 240 1 8 3 16 0 0 0 60 0 6400000 1 > /dev/null
tvservice -e "DMT 87" > /dev/null
fbset -depth 8 && fbset -depth 16 -xres 320 -yres 240 > /dev/null
You’ll have to adjust your TV’s service menu and / or the display
timings
used here to center and size the image correctly.
Next we have to configure RetroArch scaling. Specifically, we want RA to do as little as
possible, fill out the entire screen and not filter anything. We want all the work to
be done by the shader. Here are settings that can be written to the global RA configuration.
/opt/retropie/configs/all/retroarch.cfg
:
aspect_ratio_index = "23"
custom_viewport_width = "1920"
custom_viewport_height = "240"
custom_viewport_x = "0"
custom_viewport_y = "0"
video_smooth = "false"
video_scale_integer = "false"
You can of course also do that manually in the RGUI Settings->Video->… menus by setting
the aspect ratio to ‘Custom’, dialing in your chosen super resolution and disabling
integer scaling and bilinear filtering.
By default RGUI doesn’t cope well with our super resolution, but we can addrgui_aspect_ratio_lock = "3"
or manually change
Settings->User Interface->Appearance->Lock Menu Aspect Ratio->Stretch to fix this.
Keep in mind that any per-system settings, core or game overrides might overwrite the
global settings. Please read
this guide
if you’re confused about how to get your settings used everywhere.
Now all that is left is to configure RA to use the shader. Clone the repository on your
Pi and use RGUI to load the shader with Quick Menu->Shaders->Load Shader Preset.
Finally, save it as a preset to be used by all systems with Save->Save Global Preset
from the same menu.
That’s it, now nearly all your games should display properly without any further tweaking.
If you need help setting up your RetroPie CRT system in general, please see my extensive
notes.
They cover not only CRT and scaling specific issues but also more general things like
input lag, overclocking, USB sound cards, turbo fire, BIOS files, backups, etc.
You are encouraged to have a look at the shader source code. It
has less than 100 lines of actual code and is well-documented and easy to understand.
Customizing it should be very simple.
I didn’t end up using either of these in my personal setup, but both the
CRTPi Project
and
Snap-Shader
were hugely helpful when figuring out how build my own custom setup.
This program is published under the MIT License.
Developed by Tim C. Schroeder, visit my website to learn more.