Friday, January 20, 2017

Pixel Art Upscaling Test Image

At the RetroArch/libretro forums, we get a lot of requests for shader previews because there are a lot of them and many people--particularly new users--get overwhelmed and don't know where to even start. So, we've batted around the idea for a while but there were some complications, namely that it's hard to get a good representative preview without managing giant, full-res images, and it's difficult to show off the effects of some shaders while still making the previews directly comparable to one another.

To handle these issues, I decided to make a small test image that contains many of the important features for a retro-focused upscaling algorithm to handle (this is enlarged; it's actually 64x64):
It was a fun exercise trying to pack as many tests as possible into this small canvas. There are two gradients--red-to-green and black-to-white--to test banding, several styles of text, some space invaders to test effects on isolated pixels surrounded by another color, the blended/antialiased doom-guy head, a variety of slopes that go from 1:1 up to 6 pixels of run to a single pixel of rise, the pesky circle-C copyright symbol, some parallel lines and a checkerboard to test de/dithering response/false-positives and a multicolored square that turns into a green-and-beige checkerboard in the presence of NTSC signal modeling, like this:
For the preview repo, I ran the test image through each shader preset at 8x integer scale (or slightly above that for the sharp-antialiased shaders). I don't have previews available for all of the presets yet at the time of this writing, but most of the popular ones are covered. These previews will hopefully make their way into RetroArch at some point, but in the meantime you can browse them at the repo.

Thursday, January 19, 2017

Shaders for Sharpest Pixels

As readers of my blog can probably guess, I usually favor scanline and CRT effects on my retro games but there are a lot of folks who prefer sharp-edged pixels. For many of these folks, integer scaling on the Y-axis and 1:1 pixel aspect ratio (PAR) with nearest neighbor (NN) sampling is gospel, but that can lead to weird display aspect ratios (DAR) on many systems, including S/NES, where the PAR is naturally non-square*. This issue is further exacerbated if you want to run your games at 4:3, which is the nominal aspect ratio of CRT displays and is probably most like what people saw playing retro games in their natural habitat.

If you get away from 1:1 PAR/integer with NN sampling, you end up with a lot of problems caused by uncertainty regarding where in the texel (that is, the texture's pixel) the upscaled pixel is actually coming from. This manifests as "shimmering" during what should be smooth scrolling and ugly, uneven pixel sizes on what should be smooth slopes:
The solution for this is to anti-alias the pixel edges, weighting the resulting pixels against their neighbors, and there are a handful of shaders that do precisely this. For my comparison shots, I've zoomed in much further than I usually do and I'm using an NES shot to accentuate the effects. I also limited the interpolation to the X-axis to make it easier to see the effect.

PIXELLATE

Originally written by Fes, this is the OG sharp anti-aliasing shader and has been ported everywhere. It takes four texture samples a small distance from the current pixel and averages them together.
Since the averaging is happening in gamma-adjusted colorspace, it favors dark pixels just a bit, so I added a runtime option to the slang port to do the interpolation in linear colorspace instead:
This avoids the darkening but also leads to "floating" pixels sometimes when an upscaled pixel is flanked by light pixels, as occurs behind/below Mario's ear. So, pros and cons /shrug.

AANN

jimbo1qaz took another stab at the same concept and wareya added some bits to allow for interpolating in "pseudo-perceptual" colorspace. It ends up being slightly darker than pixellate via gamma curve, surprisingly enough:

SHARP-BILINEAR

Themaister took a different approach with this one. It prescales the image to a desired integer scale (I added a default option to automatically choose the largest integer that would fit on the screen) using NN scaling and then use bilinear scaling to go the rest of the fractional scale factor. In this shader, there's no averaging of multiple samples, so the gamma status doesn't matter. It ends up landing somewhere between AANN and pixellate via gamma curve:
This shader is very lightweight because it only samples the texture once and then leverages the GPU's own scaling hardware, which works essentially for free. Note: this effect is the exact same concept as the "prescale" option that appears in a variety of emulators.

There are a few other shaders worth mentioning that I didn't include here, like Inigo Quilez' "improved texture filtering" (we just call it 'quilez' in the repos), which is significantly sharper than plain bilinear scaling while still providing evenly sized pixels, and aliaspider's scaling swiss army knife, GTU, which can produce a similar anti-aliasing effect when pushed to a very high internal resolution.

These shaders are available in Cg, GLSL/slang and quark/GLSL formats.

*This statement is hilariously contentious and causes some people to flip their shit.

Sunday, January 1, 2017

Tung-Sol KT66 Replace 6L6 for HiFi

Size comparison of Tung-Sol KT66s vs a Svetlana 6L6
I've tried a few different varieties of 6L6 power tubes in my Dared VP-20 amplifier, which has been interesting but not particularly exciting. The preamp tubes makes a bigger impact on the sound, in general, and 6L6s all have the same basic sound signature, which is warm and mild, so swapping among the different brands has been more of a null-finding (i.e., still informative, just not much to write/rave about).

I wanted to try some different families of power tubes but hifi amps tend to be less forgiving than guitar amplifiers when it comes to voltage and power-draw changes, so my options were quite limited. Some guitarists replace 6L6s with KT66s, but KT66s pull 1.3 amps of current, which is roughly half-again as much current as a 6L6. However, while researching the KT66 varieties, I found this article which mentioned that Tung-Sol's KT66 happens to pull 0.9A, just like a 6L6!

According to several places online, the Tung-Sol KT66 is so similar to a 6L6 in performance and characteristics as to be "not a real KT66" or "just a 6L6 in a different bottle." However, I found it to sound significantly different from the Svetlana 6L6s I had in my amp before. The KT66s are much brighter, with crisper highs and punchier lows, at the cost of reduced midrange response.

Once I used my preamp's EQ to crank up the mids to be more balanced, I liked the sound signature of the KT66s better than the 6L6s. Comparatively, I would say the difference is akin to toggling an amplifier's "loudness" button on/off. That is, the frequencies that are accentuated by the KT66 sound more lively and the crisp high-end really made my ears perk up. On the other hand, the sub-bass suffered to the extent that I needed to add my long-dormant subwoofer back into the mix to get audible/tactile sub-bass at reasonable volumes.

So, pros and cons, overall. I'm currently digging the change and having fun listening to my favorite albums with the KT66's different coloration but I'm definitely keeping my 6L6s close by for if/when I want to switch back to their warm, balanced tone.

Some other things to keep in mind if you want to try the Tung-Sol KT66 in the place of 6L6s:
1.) Pin 1 of these tubes is tied to the metal base, so be sure to remove any tube clamps that would come in contact with the base to avoid ruining your tubes and/or amp.

2.) These bottles are big af, and so is the base. The glass is about 2" in diameter, so make sure you have enough space between tube sockets to hold them, and if your sockets are recessed, make sure you either have enough clearance for the base or pick up some 8-pin "socket savers" (available for about $10 for 4x from Chinese sellers on eBay), which is what I did.

By the way, you may notice in my pic above that I also picked up some "tube stabilizers" (aka silicone o-rings), which, for the record, made absolutely zero difference in sound quality. They may do something at very high volumes (i.e., when the tubes are getting physically affected by vibrations), but at normal listening volumes, the rings do nothing. Don't bother.