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)
Strength = 0.5, Min. Width 0, Max. Width 1 (all other effects disabled)
pure-scanlines preset (notice it has some back lighting, therefore no full black scanlines)
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.
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:
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.
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:
I actually don’t quite get what your question is.
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.
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.
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.
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…
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.
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.
A new version will arrive soon, with some improvements and additions based on your feedback.
Changed “Scanlines > Min. Width” parameter allowing -1 value for even thinner scanlines
(requested by @PU786)
Inverted “Scanlines > Offset” parameter range to align with other offset parameters, where the Jitter variant is on the right/positive side (presets have been adjusted)
Improved automatic down-scale to better align scanlines with high-res details like text
Added “Sharpen > Amount” parameter to sharpen the general output
(suggested by @Dante and others long ago )
Also preserves some details of down-scaled images (requested by @Kefka2b)
Here are some examples for the new “Sharpen” parameter:
Hi - I love this shader. I have tweaked it to my liking and really enjoy it. Can I ask, is there a way to make it lighterweight when emulating PS2, Dreamcast, GameCube etc. For instance, are there parameters I could turn to 0 or remove from the chain but keep the mask and such to get a CRT look without over-processing the rest of it?
A few days ago, I silently release a new version, which brings a small performance boost (5-10%) across the board. When you update the slang shader in RetroArch, you should get the new version automatically. I’m still looking into more potential improvements.
In the meantime you can deactivate some effects, like the Halation effect by setting Intensity to 0. This effect uses a blurring filter that is applied to the source texture with a potentially large blurring kernel, depending on the Diffusion setting. For the mentioned systems and depending on the core settings the source texture size can be quite large: 1x native resolution is 480p, which could still be performant, but if you use 2x native resolution or higher, the performance will decrease quickly. Another potential performance killer is the NTSC effect, which is deactivate by default, though.
You can also try the crt-yah-single-pass variant, which misses some effects entirely (Halation, NTSC, Deconverge, Phosphor Burn-in, Color Profile, Scanlines Offset, Brightness Flicker, Sharpen).
That’s great, thanks for the reply! I’ve repurposed my old Mac Pro and have a 1060 with 3GB of RAM so it’s not exactly a powerhouse but I’ve not asked for more than 2.5/3x resolution boost of anything PS2-era. I did try turning off Halation, and it did help, for sure. The single-pass variant, does it use the same masks? I really like the look of the slot mask mask.
I haven’t applied anything else, so I don’t think I would have the NTSC effect running, no?
The single pass variant looks exactly the same incl. the mask, only the mentioned effects are missing. It’s in fact the same code base. Even though you can disable all these effects in the multi pass variant as well, there is still some overhead running though all the passes without applying the effects.
Yes, the default preset has the NTSC effect disabled (Profile set to 0).
It mainly focus on improving the performance of the NTSC and Halation effect, but don’t expect miracles.
Add “NTSC > Chroma Samples” parameter to reduce the number of samples, sacrificing some quality of the effect for higher FPS
Value can be set between 0.25 an 1.0, with 1.0 (default) representing the original sample count. Each step of 0.25 reduces the sample count by a quarter.
For Two-Phase the max. sample count is 32, lowering will result in a reduced color “smear”.
For Three-Phase the max. sample count is 24, lowering will be less noticeable.
Add “Halation > Influence” parameter to select between Scalines, Mask and Both
Previously the halation effect only made the scanlines glow. Now the mask intensity can be lifted as well.
The following example shows the differences.
left: only mask is affected
right: only scanlines are affected (previous behavior)
middle: both are affected
Improved performance of the blur passes used for the halation effect, esp. for higher source resolutions
Changed “NTSC > Chroma Phase” parameter range to align auto value (0) with other auto parameters
This is a breaking change and you have to adjust your own presets. 0 is auto, 1 is two-phase, 2 is three-phase
Fixed glitch of vertical scanlines, when output resolution is smaller than the screen resolution (e.g. 1080p output on 2160p screen)
It refines how the automatic screen scaling works and adds a new options to select the mask’s sub-pixel order.
Added “Mask > Sub-Pixel Order” parameter to switch between RGB and BGR.
When a MG mask is selected not the order is changed but the colors to BY.
Renamed “Screen > Scale” parameter to “Scanlines > Scale” as this is what it mainly does.
The implicit mask scaling has been removed to make this setting independent from the actual “Mask > Scale” parameter.
Changed “Native” option of “Screen > Resolution” parameter to not scale the mask when internal resolution changes dynamically.
This means the number of scanlines always matches the internal vertical resolution, like before. But the mask size - which is a physical property of the CRT - stays the same and is not scaled anymore.
I have no idea. Is there already another shader that supports this? If so, I could take a look at its implementation and maybe adapt my code accordingly.