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.