Wednesday, April 24, 2013

Customizing Harlequin's Gameboy Cg Pixel Shader

CRT shaders are great, but they're not always appropriate for every console, seeing as handhelds' tiny LCD screens have very different characteristics, which in turn shaped the way the games for those consoles were designed. The original Gameboy handheld had these characteristics in spades, including a slow response time (manifesting as motion blur), very low resolution and a distinctive 2-color palette that ranged from yellow to green. Emulators typically represent this color palette as black and white, which can be jarring for people who spent a lot of time with the system.

Thankfully, a nice fellow named Harlequin has come to the rescue with a really great pixel shader for RetroArch that does for Gameboy displays what cgwg's CRT shader did for those displays. Like cgwg's CRT shader, Harlequin's Gameboy shader reproduces a lot of different aspects of the Gameboy display and presents a number of options to the user that are easy to modify with just a simple text editor (I use/prefer Notepad++ but almost anything will work). Unlike cgwg's, though, the Gameboy shader also uses some lookup textures (LUT) that require no text editing and can be modified using an image editor such as Photoshop or GIMP. Harlequin has included several example LUTs and I'll cover a few in screenshots.

As usual, all shots are at 4x (which is a bit small for Gameboy resolution, but oh well) and you can click the thumbnails to embiggen. All shots were taken via RetroArch with the Gambatte core unless stated otherwise.

First, here's an unfiltered shot for comparison:
And here's one of Harlequin's Gameboy shader with default parameters:
First, I'll cover the LUTs, which can be edited with an image editor. The palette files are found in the 'resources' folder and they're just two 64x64 squares of color that the shader pulls from to get the appropriate colors (i.e., to replace white and black in the emulator). One of the included samples is yellower and resembles the display in strong light, such as daylight:
Another sample mimics the higher contrast of the Gameboy Pocket revision:
Also in the resources folder, you'll find some sample backgrounds, which apply a texture to the image. The default has some angled hatching, while the included samples show some different types of texture that are possible, like this noisy bit:
Next up, we have the shader variables that are easily modified by users with a simple text editor. These are enumerated in the shader's enclosed README file and I'll include some shots here for reference.

The first one is the 'alpha' setting, which determines how dark a 'white' pixel should be. If you raise the value,  everything becomes darker:
While lowering the value will make the pixel grid less visible in white areas:
The next option, response time, determines how long it takes a pixel to go from white to black and vice versa. It doesn't really translate very well into static screenshots so I didn't bother showing it here. The next option after that, though--blending mode--determines whether just the space between dots is blended (mode 0) or all texels (mode 1), which, in practical terms, is how sharp/blurry the edges of the individual pixels are:
The next option--texel alpha blending--effectively controls how defined the grid pattern is. Higher values result in round/fat-looking pixels:
While lower values give you a sharp, well-defined grid:
After that, we have 'contrast,' which works just like the slider on the side of the Gameboy. Lower values can simulate the look of low batteries:
'Background smoothing' lessens the effect of the background LUT. Higher values make the background less visible, lower values make it more visible:
'Shadow opacity' controls how dark the drop-shadows from the pixels are. Higher values mean darker shadows:
Finally, 'shadow offset' determines which direction the drop-shadows appear (i.e., for simulating a light source that isn't directly above the display). Setting both the X- and Y- values to 2.0 will offset it more:
While setting them both to 0 puts the shadows directly underneath the pixels:
Just so you know: you can use this shader with other RetroArch cores, as well, and see what your favorite games would look like in an alternate, Gameboy-centric universe:

Harlequin has made some major changes to the way the shader looks and works since he first started working on it. While the current iteration is extremely convincing, I also liked an earlier version that looked more stylized. Here's a couple of shots:

You can download it from my Mediafire.


jelbo said...

Wow, great implementation. Have you found parameters that work particularly well for your tastes?

Hunter K. said...

Hi jelbo,
I think the default settings are great, since they look just like the Gameboy I used to have. If someone had a later revision, though, they made need to do some tweaking.

Anonymous said...

this shader works on an android emulator¿

Hunter K. said...

It works with RetroArch on Android.

ArugulaZ said...

I have not had much luck with RetroArch, honestly. It asks me to download DLLs and put them in the same directory as the emulator, and when I do, it responds "Cannot find DLLs." Well golly, sure am glad I wasted the time downloading them!

This shader is pretty keen, though. Are there any other emulators that offer it?

Hunter K. said...

I definitely understand your frustration. I don't know of any other emulators that can use it, specifically, but higan has a very similar shader available in its 'quark' format (I have a github repo with most/all of the available shaders).

For RetroArch, go here:
and then go to the directory for your Windows bitness (x86 or x86_64). Hover your mouse over the folder icon labeled 'latest' until you see a box. Put a check in the box and a 'download' button will appear at the the top of the window. Once that's downloaded, scroll to the bottom of the page and get the one named latest_retroarch_full. Unzip all of the cores from the 'latest' archive and put them into the 'cores' directory from the latest_retroarch_full and you should be set.

If you have any problems, go register at the retroarch forums and we'll get you fixed up :)

Analytics Tracking Footer