CRT-Yah! A new shader chain

Thanks! This is probably my favorite shader now.

1 Like

There’s a couple of other things I noticed.

When using higher res cores (ps2, gamecube, dreamcast), I set screen resolution to 1 for native since I don’t won’t those at 240p. This causes a pink tint on the screen as well as what looks like uneven scanlines. Setting retroarch to integer scale fixes both of those issues but I don’t want to use that. I was wondering if that could be fixed within the shader. I am on a 1440p screen. Maybe this isn’t an issue at 4k.

I also like using your LCD variant for handhelds, but one thing I don’t like is how the mask seems to move under the “pixels”. I wonder if that could be fixed.

I do believe 4K resolutions are the minimum requirement for 480p scanlines. @cyber may know more.

1440p could work for 480p scanlines. It actually divides perfectly to 3, which is the min. size of scanlines with this shader. However if the scanlines are not exactly 3 then at 1440p the size will look uneven. The interpolation is just not good enough and I don’t see how to fix that. Can you tell me what the render resolution of any of the cores you mentioned is?

The pink tint could be caused by the mask, which subpixel size is probably automatically set to 1 due to the 480p setting. Depending on the actual subpixel grid of the monitor a subpixel size of 1 can lead to various color tints. On my 4K TV for example, I see a green or red tint. You could try to select another subpixel color or manually increase the mask scale.

A screenshot might help to better understand the issue.

1 Like

Setting mask sub-pixel to 5 fixed the tint. The resolution is 640x528 for dolphin, which is where I noticed it.

Thanks for the screenshot.

The scanlines actually look quite good to me. However, I’m wondering: You said you have a 1440p monitor, but the screenshot is 2160p (4K). Is your RetroArch configured to output a higher resolution than your monitor can display? This can lead to artifacts when the image is down-scaled to your monitor resolution.

I’m not exactly sure what you mean by that. However, the LCD preset is really not sophisticated compare to actual LCD shaders. The RGB sub-pixel blocks are not (always) aligned to the pixels, which looks off upon closer look. But I thought is looks good enough to add the preset anyways.

Here in this screenshot you can see the misalignment, esp. in areas with high contrast between pixels.

Also using a custom mask scale is not recommended, the auto scale should already select the best fit.

And as you’ve probably noticed, the spacing between the scanlines is used to create a small gap between the rows of LCD pixels - something a real LCD shader wouldn’t do. The LCD preset isn’t actually designed to produce an authentic close-up LCD look.

It’s not the same resolution as 240p. You’re ignoring the temporal aspects including persistence of vision and phosphor decay, which is why interlacing works so well on a CRT. Remember an NTSC CRT’s TV’s standard resolution isn’t 240p but rather 480i. 240p is a trick.

All you need to do to capture the full frame of a 480i signal is to set your camera to 1/30 shutter speed. That will enable you to capture both fields of a 480i frame.

Another thing, vertical resolution doesn’t define or affect TVL in the way that you’re describing. TVL is strictly about horizontal resolution. i.e, the number of distinct vertical lines the display is capable of dispaying in a particular area of the screen.

TVL is affected by things like dot pitch, phosphor/mask size and in the realm of CRT Shaders Mask Layouts, so denser/finer phosphor layouts provide or enable higher TVLs.

In subpixel aware and also other types of CRT Shaders when we leave the Mask Layout constant, then increase Display Resolution (not emulated CRT Resolution), the result is an increase in TVL. Conversly, if we leave the Mask Layout constant, then decrease Display Resolution (not emulated CRT Resolution), the result is a decrease in TVL.

Yeah I’m an idiot. I had it at the 4k dldsr resolution. Those two problems are fixed at native 1440p. Thanks!

A new update is near.

The biggest change is a new experimental interlace option, that renders odd/even scanlines alternating at 60Hz. I’m unsure if the looks of it makes any sense, and awaiting your feedback. :wink:

Changes:

  • added experimental interlace option to render odd/even scanlines alternating at 60Hz

    The settings is not just limited to the high resolution profile.

  • changed auto up-scale to use half multiple increments (auto down-scale still uses full multiple)
  • changed high halation diffusion does not increase the intensity of the effect anymore

    Previously an Intensity of 1 and a Diffusion of 1 look overwhelmingly glowy, which was not the intention.

  • fixed auto phase option of the NTSC effect
  • fixed brightness influence on brightness compensation (default presets have been adjusted)

    Previously the manual Brightness had to less influence, when the Brightness Compensation was active. This change will affect your custom presets. To get a similar intensity as before lower you Brightness by a third (e.g. 0.3 to 0.2).

  • small performance improvements
3 Likes

Happy to report that at some point the Dreamcast issue was fixed.

I was wondering if it’s possible to make the Scanlines Min size get as thin as those in CRT-Royale??

On 1440p here in these screenshots (for space sake) Royale is about 2 pixels tall for the darker colors and sides of pixels. Yah is about 4 pixels tall with Min set to 0, and the thick ones at 1.25 are 6 pixels tall(ish).

Assuming scanlines is

scan = strength * sin(vtextcoord.y * Texturesize.y * PI * 2.0) + 1.0 - strength;

Will give half lines dark and half bright.

If we introduce a luma factor

l = dot(vec3(0.3,0.6,0.1), res);

We can manipulate strength like

strength = mix (0.5,0.3,l);

Then enter a factor to control beam width

width = mix(0.5, 2.0, l); // lower is stronger

And

scan = pow(scan, width); res *= scan;

Will alter the beam width to whatever we want.

The scanlines use the exp() function instead of sin() with the width already weighted based on the scanlines’ intensity.

The very core looks as follows (crt-yah.stage-f.core.h line 186):

vec3 factor = position / (width + EPSILON);
factor = exp(-10.0 * strength * pow(factor, vec3(slope)));

With that the scanlines actually can reach very small sizes, when the Min. Width is set to 0. However, this 0 is only affective when the scanlines Strength is set to 1.

E.g. if a full white scanline has a size of 10px and the mentioned settings are applied, then a 10% intense scanline will have a size of 1px. However, if the scanlines Strength is set to 0.5, that same scanline will have a size of 2px.

Here is a test pattern with different settings.

Strength = 1, Min. Width 0, Max. Width 1 (all other effects disabled)
image

Strength = 0.5, Min. Width 0, Max. Width 1 (all other effects disabled)
image

pure-scanlines preset (notice it has some back lighting, therefore no full black scanlines)
image

As the scanlines have a smooth shape, the actual size can not be exactly measured. Long story short, the Min. Width parameter is bound to the Strength parameter.

I can provide a tweak in the next version to allow a more aggressive Min. Width configuration.

p.s. I’m glad to hear that the recent fix actually solved the mask bug on your end.

1 Like

Ah very interesting to read! And you read that so on point I’d prefer to stick to 0.5 strength.

Hey this has become my favourite shader! It looks awesome and doesn’t require to tweak billions of settings. I have a couple of doubts:

  1. About pixel layout on my LG CX OLED TV, I tried BY which looks great but RGB(4) seems to have a more correct triad shape. Just a bit confused I am not entirely sure what the layout of the TV is, I have seen WRGB and RWBG on the internet.

  2. How do the 2 up/downscaling options work, I am interested to use these options to have proper 240p or 480p triads and scanlines reintroduced for upscaled 3d games while keeping the sharpness of the upscaled core resolution. Is there any easy calculation formula according to native res and upscaled res (or upscale factor)?

Happy to hear you like it so much. The overwhelming amount of parameters of other shaders also was one of the reasons I started this project. Although I try not to add more parameters, the number is increasing since the first release.

Regarding your questions:

  1. I actually don’t quite get what your question is. :sweat_smile:

    • 1-BY is a blue/yellow mask, that does not resemble any real sub-pixel mask, but it looks good on some displays
    • 2-MG is a magenta/green mask, also does not resemble a real sub-pixel mask, but is closer to a RGB mask than BY
    • 3-MGx is a magenta/green/black mask: at 1080p this results in a MGx pattern, at 2160p it becomes MMGGx (the black part is only on pixel)
    • 4-RGB and 5-RGBx, where the x part functions as above

    I would say use what looks best. In my opinion there is no perfect answer to it. The actual sub-pixel grid of your monitor will never perfectly align with the simulated sub-pixel mask.

  2. The main goal of the auto-scale is to deal with dynamic resolutions, like some SNES games that use the high-res mode when displaying text. In those cases the game switches between 224p and 448p, which would result in double scanlines as long the text is displayed.
    The options work a follows:

    • 1-Native: No auto-scale (it only enforces a min. scanlines height of 3px)
    • 2-Low: Tries to down-scale the image to about 240p by incrementally halving the resolution

      e.g. 448p to 224p, 480p to 240p

    • 4-High: Tries to down-scale the image to about 480p by incrementally halving the resolution

      e.g. 960p to 480p (usually no core renders 960p by default, and it is not recommended to configure a core rendering at another resolution than the system’s native)

    • 3/5 The + variant of Low/High also tries to up-scale the image to about 240p or 480p by incrementally doubling the resolution (the factor can be 1.5 or 2.0)

      e.g. Low: 144p to 216p (x1.5), High: 224p to 448p or 240p to 480 (x2.0)

    I explained the auto-scaling in more detail some posts above. However, as mentioned, I do not recommend to use a high resolution core output as you won’t keep the up-scaled details. The scanlines are not just an overlay. For each scanline a color-gradient is calculated, that blurs any high resolution detail.

Maybe, I can think of an option to re-introduce details of the original image. But currently I have no idea how that could work.

You could try to use the new Interlace option (0.5+), with the High profile (480p) and a low Frequency (30/40Hz). This will give you double scanlines where odd/even scanlines are rendered alternating. So, it kinda looks like 240p scanlines with 480p details. But the image will flicker due to the nature of the alternated rendering.

1 Like

The subpixel layout of all LG 4K WOLED TVs up to 2025 with the exception of RGB Tandem models is RWBG.

This is a cop out because the information is right here in these forums.

RRBBGGX subpixel mask layout aligns very well at 4K for around 300TVL.

Other variations of the RBG subpixel layout also work for example RBGX and RBG for 600 TVL+. For higher TVLs B/W Masks can work.

From 2026, LG has introduced changed the subpixel layout on even non Tandem RGB TVs to the new RBWG layout, which I’m still waiting on some data from @PU786 (or anyone else who has one of the new displays and is willing to help) to help determine what needs to be done to properly support this new layout.

Outside of RRBBGGX, RBGX, RBG there is no best because they all look horrible and mangled.

1 Like

This is why I’d love if you and Painless put on a panel at a convention. Because I am so in the dark about this and I think we, people, need to see some real world demonstrations.

How does this make an aperture grille mask look better than the default settings of CRT Hylian or something? Is horrible and mangled a huge exaggeration? It sucks not having a base of understanding to work with.

As a cinephile I can’t ever abide using an LCD. As a retro gamer, I’m really happy with shaders that make my games look close enough to how they did on my KV-32FV310 (correct me if I’m wrong but 600 TVL seems close to this and 800+ for an XBR960). Like if I need the actual TV next to me to be able to tell the difference…well…

1 Like

Thanks, it’s an honour.

To be so pedantic about Plasma and OLED and considing yourself a cinephile while bathing in ignorant bliss about the subpixel and phosphor level stuff is quite an interesting irony.

The history is all right here in these forums. Just go back through some of my posts and you’ll see that I was just like you at a certain point, then I eventually started noticing things and the more I saw, I couldn’t unsee.

Everything that could potentially go bad about OLED subpixel CRT rendering and everything that has been resolved can be viewed right in those links I shared above. Just read a little beyond the links and you’ll see what it took and what I did to get proper WOLED support in Sony Megatron Colour Video Monitor after discovering it was working purely by accident in CRT-Guest-Advanced.

In general though all you need to do is go close to the screen with a low enough TVL preset and you’ll see that with the wrong subpixel support the phosphors and subpixels look nothing like they do on a CRT.

You also have the opportunity to see this firsthand by participating in my little test. I have nothing to gain right now by doing this because I don’t own a new tandem OLED panel display with RGWB subpixel layout so I’m only spending time and energy on this for the wider community, yourself included.

It slightly irks me that others are not as enthusiastic and determined enough to make this a priority since it’s been over a year and still I can’t get 3 close up photos of a tandem WOLED screen showing 4K 300TVL RRGGBBX, RRBBGGX, BBGGRRX subpixel layouts in action and test new layouts if possible. Back in the day when I was wrecking my own OLED display, I was on it and wouldn’t relent until I got the results I wanted.

Now people are saying that OLED TVs are the best for gaming and the best for CRT emulation, however, they’re not saying this for the reasons I’m speaking about here though. More so for the motion clarity potential, pixel response times, black levels, viewing angles and other CRT like qualities. Very few people in the mainstream, the wider community or the RetroTinkers and FPGAers seem to care about or focus on accurate subpixel CRT emulation.

So many are it seems. There are many points of reference and demonstrations available online which I have pointed to in numerous posts over the years. A good place to start is the first post of the Sony Megatron Colour Video Monitor thread.

A few years ago, it was thought that subpixel level CRT emulation was impossible on OLED displays. Look at where we are now.

2 Likes

This is how we learn. It’s not bathing in ignorance, and I do all this reading but the results truly feel impossible to see through online research. Through videos. Through images.

I would happily drive a few hours somewhere to seek in person counsel. To see and hear someone explain. I’ve lived in ignorance plenty of times and I wish I understood far earlier about a great many things. I suspect this instance is a similar instance.

I’ll do what I can, not just because of this gnawing drive for fidelity, or artistic intent, but I’ve been in your shoes so many times. And I so often identify with your pursuit, your frustration, and even the analytical level of thought you put into your posts trying to communicate it all.

Lets hope MicroLED or QDEL or whatever gives us better than OLED and MiniLED currently do.

1 Like