A Link to the Past: How To Add CRT Filters to 16-Bit Games on PC

By Wesley Fenlon

Fan-made graphics shaders and filters for Super Nintendo emulators recreate the colors, bloom, and scanlines of CRT televisions with glorious precision.

Almost 90 million people worldwide own Nintendo Wiis. Millions of those Wii owners spent money on retro games on Nintendo's Virtual Console to replay classics like Super Mario World. And millions of those people were in for an ugly surprise: old, low resolution games do not look good on LCD TVs. Between upscaling games designed for 224p output and inappropriately stretching them to 16:9, modern flatscreens do Virtual Console games no favors.

But the problem goes deeper than that: LCDs and plasmas simply look different than the cathode ray tube televisions old games were designed for. Emulators allow us to run games at their original resolutions or control image scaling more accurately, but that's only a partial solution. Here's where it gets cool: programmers with a passion for preservation have developed filters to bring the CRT look alive on modern displays. We're talking about manually introducing color bleed, scanlines and even the rounded corners and bulge of the CRT into perfectly emulated images.

The attention to detail may sound crazy, but comparisons will make you a believer. Read on to see the filters in action as we dig into the technology keeping the analog video look alive and flickering in the digital era.

Disclaimer: The classic games depicted in this article can easily be purchased on digital marketplaces like the Virtual Console or Xbox Live Arcade for five or 10 bucks. We will not be providing information about how to emulate games or where to acquire game ROMs.

Analog vs. Digital Video Technology

Before we can explain how programmers replicate the look of cathode ray tube televisions with graphical filters, we first have to understand why those TVs looked different in the first place. In CRT sets, pictures are created when electron "guns" inside the television are fired at a screen of red, green and blue phosphors and light them up.

Now here's where the differences between CRTs and LCDs start getting important. Pixels in CRTs are created by phosphors arranged in triads or stripes, but there's no set number of pixels in the display. LCDs, conversely, are called fixed pixel displays because they have an exact number of pixels. Because of this difference, the analog technology of the CRT is much better at rescaling images than the LCD:

The monitor then uses this analog information in the form of voltage variations, electron beams and magnetic fields to paint the picture on your monitor screen, resizing it as necessary to fit the display space...
At resolutions which are lower than its native resolution, the [LCD] monitor has to digitally rescale an image to fit into its fixed pixel structure....The end result is that typically when you use any resolution lower than the maximum (native) resolution, the image will show visual glitches and blurring. This is because the monitor has to Interpolate (recalculate with some guessing) the data to make it all fit into its fixed pixel structure...The bottom line is that digital information is discrete and precise, while analog information is continuous and imperfect.

Shades of the Past

Replicating the look of a tube monitor essentially requires introducing imperfections into the picture. Phosphors have a tendency to bleed outwards, creating a soft edge or glow around objects on the CRT screen. 240p images were displayed in 480i on NTSC TVs, creating alternating black scanlines with every video line. There are fascinating sites out there dedicated to properly handling video signals with scan converters and video processors, but those can cost hundreds or thousands of dollars. Our solution: fake it with software.

The easiest place to start is with bsnes, a Super Nintendo emulator we've written about before. One of the most popular filters available for the emulator is Blargg's NTSC library, which includes multiple color presets (composite, RGB, S-Video). In fact, Blargg's work comes bundled in bsnes' filters folder; the filter is also available for NES and Sega Master System. bsnes also offers scanline filters out of the box, but it only runs one filter at a time. To use Blargg's RGB color pallete and scanlines at the same time, we have to turn to a second graphical augmentaion: pixel shaders.

Pixel shaders rely on GPU computation rather than CPU computation, which does the bulk of the work in emulation. bsnes can run one filter and one pixel shader simultaneously, allowing us to pair a scanline shader with Blargg's RGB filter.

In bsnes, shaders and filters are available from the Settings menu. To use filters and shaders you download, simply put them in the appropriate folders within the bsnes folder. Filters should be immediately accessible, but you'll have to change one other setting to get shaders working properly. Most pixel shaders are designed for OpenGL; by default, bsnes on Windows uses Direct3D video drivers. Choose Configuration Settings from the same Settings menu, go to the Advanced page and switch from Direct3D to OpenGL. You should now be able to mix and match shaders and filters from the Settings menu and change your scaling factor from 1x to 5x under Video Mode.

Now, to the filters! From left to right: Nearest neighbor (upscaled, no filters), Blargg's RGB filter, RGB + caligari's shader, RGB + cgwg's CRT scanline shader, RGB + cgwg's curved CRT scanline shader

The fun of experimenting with shaders and filters is tweaking the visuals to match your childhood memories of playing on a bulky CRT. For example, scanlines dramatically darken the picture; slightly upping the brightness can compensate. Curved shaders are the ultimate in nostalgia--not only do they try to replicate how games were displayed on old TVs, they try to replicate the look of the TV itself. Blur, bloom and darkened colors are good for more than nostalgia, though: they cut down on the harsh edges of pixel art displayed on LCD monitors.

When we start getting into heavy duty upscaling and can clearly see individual pixels, pixel art starts to lose its cohesion. Filters like Blargg's minimize that effect. Here's an example, courtesy of poster The Exodu5 on gaming forum NeoGAF:

No single filter will look the best to all of us. Thankfully, we've got options. If scanlines make the picture too dark, adjust the brightness and gamma within the emulator. Reading about the development of these filters can be fascinating--hours and hours of math and programming went into bringing them to life. This thread on byuu's bsnes forum provides a detailed look at the development process of CRT filters. Now for the glorious results of those efforts.

Caligari's scanline shader, based on the code originally written in MATLab by xythen (see the thread linked above), doesn't work at 2x scaling but looks phenomenal at 3x and higher. It's similar to cgwg's flat scanline shader, but considerably brighter. Here's an untouched shot and a comparison of the two shaders (caligari on the left) with no other filters enabled. The fourth shot is a darker image of caligari's shader combined with Blargg's NTSC filter.

The Filthy Pants blog has more comparisons and links to other filters for bloom, CRT curvature, etc. Another blog entry catalogs shaders and filters for Sega Genesis and Game Boy emulation.

The Arcade Dream

A recent trip to San Francisco's Southtown Arcade drove home the fact that older 2D games just lose something on LCD displays. One glorious cabinet tucked into the arcade's cramped back corner was running Street Fighter III with stark scanlines shimmering across the 29-inch display. It looked phenomenal. Even the screens without visible scanlines looked miles better than anything upscaled on an LCD screen. If it's your dream to set up a home arcade with MAME but you lack the funds or space to buy a real cabinet, filters can get you close to the real thing with the HDTV you already own.

Getting a filter running in MAME takes a bit more tinkering than it does with bsnes, but the effort's worth it if you plan to set up your own arcade machine with an LCD. Start with MAMEUI, which adds a graphical front end to the core MAME emulator. The binary's a cinch to install and has a filter called HLSL already built in. Convenient, right? There are plenty of guides out there for configuring MAME the way you want it, but here's what you'll need to get HLSL running.

An "ini" folder inside MameUI should have a mame.ini file as well as individual .ini files for each game you run. Open the mame.ini and scroll down to the "# DIRECT3D POST-PROCESSING OPTIONS" section of the code and change "hlsl_ini_write" value from 0 to 1. That should allow you to tweak HLSL settings from the GUI under the Default Game Options menu. But for now, we'll actually do one better by pasting in a sweet configuration that adds scanlines, a tiny bit of color tinting and some screen curvature.

Paste this configuration from MAMEUI's official forum thread under the "# DIRECT3D POST-PROCESSING OPTIONS" bit of code to CRT-ify your games. You may have to do this for the individual game .ini files as well. This is what you'll end up with.

Tweak to suit your own preferences. Don't like screen curvature? Get rid of it. Want subtle scanlines? Lower the value. When it comes to video signals designed for interlaced displays, scanlines really do dramatically improve upscaled sprite art. Forget the smoothing filters on arcade ports like Marvel vs. Capcom 2 on XBL/PSN--this is the way classic games should look.

By this point, you're hopefully neck-deep in 16-bit nostalgia. You've got the tools to relive the 90s--now grab an emulator, pick up a USB gamepad and game on.