How some old games are meant to be played
For 400p and 480p, (which is what 200p and 240p is getting pixel-doubled to with VGA) you need a 1440p monitor. To get a correct looking mask, you need 3 LCD pixels per CRT “pixel”. 400x3 = 1200, and 480x3 = 1440. So both 400p and 480p won’t ever look right on a 1080p display (unless you do integer scaling and overscale it, losing content on the outer edges.)
As for which shaders look good, most actually do. Easymode, hyliian, lottes, the guest ones… This is a photo of an actual CRT monitor:
Most shaders can replicate that look very well. However, as mentioned, you either need a 1440p display (or higher), or you need to overscale, which for PC games is unfortunately not an option, since “TV overscan” is not a thing with VGA. Games usually utilize the full resolution and there’s no empty overscan areas.
5x scale would be ok. You get 1600*1000, with cgwg mask you have 800 “CRT” pixels and a scanline every 4 bright lines in the middle of the pixel (and darken a bit the last line). That would be pretty accurate. Of course 6x would be perfect, with 1 dark line-2 bright
5x scale would be 3200x2000
You can even fake the look with crt-nes-mini, thickness 4.0 and intensity 0.66 at 1280*800. If you add cgwg mask and a subtle filter would be even more convincing.
(crt-guest-advanced-ntsc-fast
from https://forums.libretro.com/t/new-crt-shader-from-guest-crt-guest-advanced-updates/25444)
Uploaded a tweak of crt-nes-mini that does that here.
Dreamcast with the above shader and a small edit in glslp, scale_y0=480. That looks pretty good, much better than displaying it in 480i or 240p IMO.
Guest’s utterly sublime ‘Advanced Shader’ So many configurable options, that even good results on 1080p displays can be had.
![retroarch_2022_01_23_17_12_50_546|690x388] (upload://nS0KVCOuvZtALUZHH8q9wE7DSVP.jpeg)
Shouldn’t a VGA connection at 480p be super sharp and not like s-video? (i guess it would be blurry if you connect it to an LCD non native resolution and not a CRT monitor).
Depends on the CRT you connect it to. If it’s a TV, it won’t be sharp. If it’s a high resolution CRT monitor, it will be very sharp. I did that in the past. My CRT TV could take input from my PC through RGB, and my video card (and old ATI Radeon 7500) had RGB output for TVs. It wasn’t nearly as sharp as on my PCs CRT monitor.
The best thing I’ve ever seen in 10+ years of playing with shaders. Indistinguishable from the real thing.
Thread:
This is the crt-guest-advanced-hd
preset from New CRT shader from Guest + CRT Guest Advanced updates, tweaked for VGA and SVGA DOS games on a 1440p monitor:
interm = "0.000000"
bloom = "0.100000"
halation = "0.025000"
brightboost = "1.100000"
shadowMask = "3.000000"
maskDark = "0.800000"
maskLight = "1.200000"
(The CRT mask will probably look like complete crap on 1080p… A 1440p display is probably required.)
The above shader i am working (geared torwards a Trinitron TV) has adjustable scanlines so it can do 400/480p too.
It can look like a crap TV or a monitor. Still testing though. But i consider it almost finished.
Looks way too blurry for a monitor. Someone on discord made a close-up photo of their CRT monitor:
(The second screenshot is SMW line-doubled on their CRT.)
So CRT monitors in the 90’s DOS era were very sharp.Even 1440p is too low to represent the very fine-grained mask (these monitors were made for high resolutions.) It almost looks like a canvas that’s being painted on. You’d need 4K to get a really accurate representation.
But whatever you can do to somehow make it look as nice as possible on 1080p is of course extremely helpful!
Glad to see VGA and PC CRT emulation finally getting some love! I agree, though, that at 1080p, our options are likely going to be quite limited, even more so if we’re trying to emulate a shadow mask. Aperture grilles are, as usual, easier to emulate, but there’s still the matter of the much thinner 400p/480p scanlines. There’s only enough room for one pixel-thick lines at that resolution, so only enough for very basic scanline emulation, with little to no room for things like scanline blooming. 4K gets us much closer in that regard, though only to a point. I’d say 400p/480p emulation at 4K would be roughly analogous to what you can do for 240p content at 1080p.
On another note, I’ve been toying with a Magenta-Green-Black mask pattern (subpixel structure is |RxB|xGx|xxx|), and it seems like a decent alternative to the Red-Green-Blue pattern masks used by several shaders for emulating lower TVL at 1080p, while still retaining a higher TVL count than Red-Green-Blue-Black. While Red-Green-Blue runs into subpixel issues due to the blue subpixel ending up right next to the red one to form magenta (a fact pointed out several times in this thread), this one at least avoids that, and it does not appear to be any darker.
Admittedly, it’s not as accurate as Magenta-Green or Red-Green-Blue-Black, as there’s a wider black gap between each triad than there is between each emulated phosphor (four subpixels between triads versus one between phosphors), but neither is the White-Black pattern in Mask 7, and in practice it looks pretty good.
If anyone wants to try it out, I achieved it in a crude manner (I can’t into shader code beyond a certain point ) by changing the following in crt-guest-advanced:
// BW Trinitron mask 7 - 9
else if (shadowMask > 6.5 && shadowMask < 9.5)
{
float fdivid = 0.49; if (shadowMask == 9.0) fdivid = 0.70;
float mdivid = 2.00; if (shadowMask > 7.5) mdivid = 3.00;
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
mask = vec3(maskTmp);
pos.x = fract(pos.x/mdivid);
if (pos.x < fdivid) mask = vec3(1.0);
}
Into the following:
// BW Trinitron mask 7 - 9
else if (shadowMask > 6.5 && shadowMask < 9.5)
{
float fdivid = 0.3; if (shadowMask == 9.0) fdivid = 0.70;
float mdivid = 2.00; if (shadowMask > 7.5) mdivid = 3.00;
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
mask = vec3(maskTmp);
pos.x = fract(pos.x/mdivid);
if (pos.x < 0.3) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
else if (pos.x < 0.6) { mask.r = mc; mask.g = 1.0; mask.b = mc; }
}
Mask 8 should give the desired result.
There’s probably a better way to do this, of course, as this change outright replaces the BW mask.
Actually with 1440p you would be pretty close with a 3 pixel aperture grille RGB and scanlines 2:1 pixels (2 bright-1 black). With 1080p you only have an option for 1:1 thick scanline and 2 pixel aperture grille (magenta-green).
You COULD maybe forego the scanlines at 1080p altogether and just throw a mask on top with just the tiniest bit of blur to maybe simulate a monitor with a high dot pitch or something like that. Might be worth messing around with.