Thursday, June 22, 2017

RetroArch Tone-mapping LUT Shader

Reshade has long had a shader, LUT.fx, that enables users/designers to do tonemapping and other color adjustments without touching any code. Instead, they can do all of their adjustments in an image editing program, such as Photoshop or GIMP, which many people are familiar with already. While my image-adjustment and color-mangler shaders can be used to accomplish those same tasks (Pokefan531 did a great job modifying them to produce his handheld color shaders, after all), they're awkward to work with, since an artist has to make all of his/her changes by twiddling esoteric values in the shader settings menu.

So, I decided to port the Reshade shader to RetroArch so our users could get in on the fun. I ran into some unexpected behavior with the direct port, though, and decided to adapt another similar shader instead. This one ended up having the same weird issue, which I think is related to undefined behavior, but I put a stupid workaround in the shader to mostly deal with it.

Anyway, here's how you use it:

First, take a screenshot that you want to use as your reference (I'm going to use the Sonic the Hedgehog title screen) and then take one of the passthrough palette textures that come with the shader (they're the png files located in reshade/shaders/LUT, named for their color depth). Then, in Photoshop or GIMP or Paint.NET or whatever, open your reference screenshot and paste the palette image down below it:
I find the easiest way to do this is to go to the image menu > canvas size and then anchor it from the top and increase the canvas Y-axis measurement by the height of the palette texture (in my example, I'm using the '16' texture, so I made the image 16 px taller). Paste the palette image in there, move it to the bottom-left corner and then merge the palette layer with the screenshot layer.

Next, do whatever it is you need to do to make the picture look like you want it. That includes brightness/contrast, hue/saturation, indexed color, different lossy colorspace conversions (such as by switching to CMYK colorspace and then back to RGB). I'm going to do a simple hue shift in my example because it's easy to spot:
Once you have it all set, we need to isolate the palette from the screenshot. I think the easiest way to do this is to go back to image > canvas size, anchor from the bottom left and enter the size of the palette (the width of the passthrough palettes is the height squared; I used the 16-bit palette, so it's 16 * 16 = 256 px). Save that image under a new name (I called mine 'hedgehog-palette.png'; if you're using a different palette depth from the default 16, it's probably a good idea to put that into the filename somewhere so you don't forget it) and then drop it into your reshade/shaders/LUT directory with the other palette images.

Now, open the LUT shader preset (cgp/glslp/slangp file) in a text editor and change the line that points to the palette (probably line 7, but YMMV):
SamplerLUT = shaders/LUT/16.png
becomes
SamplerLUT = shaders/LUT/hedgehog-palette.png
Save and exit and then fire up RetroArch, load a core and some content and then load up the shader. It should apply those same color transformations to the game image, like so:
If you used a different bit-depth palette from the default 16, your colors may look crazy and messed up at first, in which case you need to go back into the quick menu > preview shader changes and then change the "LUT Size" runtime parameter to match.

This shader is available from the online updater and/or git in GLSL, Cg and slang shader formats.

Monday, June 19, 2017

RetroArch shaders on Shovel Knight

I recently played through the awesome retro-styled platformer Shovel Knight for the first time and, while the pixel art is incredible, I kept thinking "I bet this would look even more amazing on a CRT." The game runs at a higher resolution on PC, so getting the low-res scanline-y look I crave wouldn't really be possible (or at least would be a significant hassle) through a 31 khz PC monitor. However, thanks to j_selby's out-of-the-blue Citra-libretro core, we can now run 3DS games via RetroArch--including Shovel Knight--and apply all sorts of fun shaders to the output!

Here are a couple of shots (click to embiggen):
The old favorite, cgwg's CRT-Geom
xBR-lvl2

artifact-colors; horizontal scaling is a little wonky

crtglow-gaussian

ntsc-320px-gaussian-scanlines

Thursday, June 1, 2017

New NTSC Shaders

NTSC simulation/emulation is a tough nut to crack. There's a lot of math involved, and the results are very dependent on games/content having the correct resolution or else the effect falls apart. Themaister's NTSC shader does a fantastic job with both 256- and 320-pixel-wide content, which covers most modern-ish retro consoles, including S/NES, Genesis, PS1 and N64, and it handles content of arbitrary resolutions pretty well. Nevertheless, it's always good to have variety, so I was excited to find some other shaders that included different takes on the NTSC signal problem.

Artifact Colors

This shader is based on Flyguy's awesome "Apple II-Like Artifact Colors" shadertoy and is the most impressive/magical of the shaders I'm going to cover here. Where this shader excels is in reproducing the NTSC "artifact colors" that certain old computers depended on before full-color interfaces were a thing. You can find some great explanations of the phenomenon at the 8088 mph demo writeup and this post at nerdlypleasures.

This splitscreen image demonstrates just how mind-boggling this effect can be, taking a 1-bit black and white image and ending up with bright colors:
RGB output on the left, composite artifact output on the right. Those colors are all generated by the signal modulation :O
And here's an animated gif that cycles between the typical limited-palette RGB output and the full-color artifact-color version (half RGB and half composite artifact back and forth):
Notice how the magenta and black stripes turn to a rich brown
In porting this shader, I tried to make runtime parameters out of as many variables as possible because it's such a cool thing to see how they affect the emergent colors in real-time. One such parameter is the F_COL variable, which can be used to basically have another color palette that you can switch to.

I also made a preset that pairs it with T. Lottes' CRT shader, which is perfectly suited to CGA content:
I called this one c64-monitor in the 'presets' subdirectory of the shader repos
I made the presets force a 640-pixel width, since that seems to be the sweet spot for this shader, which isn't surprising seeing as many of the games that relied on artifact coloring used a 640x200 mode. I'm not very familiar with any of the classic computer cores that could take advantage of this shader, but I'd love to hear comments from anyone who gives them a shot.

This preset also looks pretty darn good for general use, though it does a strange green/magenta strobe thing on Sonic's waterfalls and probably other pseudo-transparency:

CRTSim

This one from J. Kyle Pittman / PirateHearts is similar to the CRT effect in You Have To Win the Game:
It doesn't try to be accurate, it just looks nice and runs fast. While it does the whole bevy of old TV effects, including a really nice per-channel color persistence that can be used to reproduce the characteristic red smear of a failing CRT, my favorite part of it is the LUT-based NTSC effect. It uses a simple texture of diagonal colored lines:
This looks gray, but it's actually red, green and blue diagonal lines
and mixes it in with the main image based on differences in brightness between each pixel and its neighbors. For such a simple concept, the result is very convincing, and it even does a reasonable job of "passing" the NTSC crosstalk test-ROM (with certain settings):
Also of interest with this shader is the choice of permissive public domain licensing, so people can integrate it into their games and other programs without fear of licensing conflicts.

Both of these shaders are available in RetroArch's regular GLSL and slang/Vulkan formats. On-topic but not pictured are two NTSC shaders derived from MAME's NTSC shader implementation, one multipass and one single-pass. I haven't gotten them to work properly in GLSL format, only slang, and all of my Vulkan screenshots have their red and blue channels swapped for some reason right now, so I couldn't share any shots of them. You can get a taste from their shadertoy implementation, though.

Analytics Tracking Footer