CRT-Yah! A new shader chain

Hi there and thanks for the offer to use your much more advanced version! I really appreciate it and keep it in mind. For now I’ll stick with the older, simpler version. It’s elegant and, in my humble opinion, still looks great.

2 Likes

@anikom15 what would be the difference between this more advanced method and older ones? I will add the shader to my chains to see for myself, but it would be cool to read about it.

Never too late, and your yah is too good to go unnoticed. In fact, I think it’s one of the best, and I’m not exactly new to the game either. I do not know about your history with MAME but I’m not surprised you have one. A shader like yours doesn’t come out of the proverbial blue. And yes, the autoscaling/rotation is a literal godsend, love it. I also really like your approach to manual vertical scaling by the way, I didn’t mention that in my “review”. You can definitely be more than proud of it. Listen, even I feel a bit proud about it myself and the only thing I’ve done is use it and try to give it some well deserved exposure.

Now @Jezze I have done my homework :slight_smile:

First gamma:

I see, it’s an interesting approach, actually! Thing is, maybe someone obsessed with blacks being black (namely myself lol) and who doesn’t mind totally black beams might want to push the CRT effect without seeing gamma shifts in dark areas. A pretty simple solution to make everyone happy could be a switch named “Black Levels”, where 0 = Traditional. 1 = Jezze. Setting it to 0 brings black level to absolute zero, unties it from other settings and enables a gamma slider. 1 obviously uses your method. Default value is 1 :wink:

Yeah I figured out that one of the reasons why the black levels were higher than expected is because noise has a default value of 0.25, and that messes up gamma quite a bit. The more general efffect you apply, the more noise is added, and of course the more black levels suffer. I would suggest leaving the noise feature in there, because it is a very cool effect for certain games, but setting a default value of 0 for it.

Ok, examples. First image is guest-adv in srgb mode, which is an excellent point of reference. Second is a quick gamma correction I applied using yah’s own settings and nothing else. Not perfect but good enough for demonstration purposes. Third is yah’s default values. As you can see midtones are noticeably darker on the third one. It will be even more apparent in a real world scenario as Sonic the Hedgehog will show next.

This time first image is raw, no shaders. Second is again guest-adv srgb. As you can see, colour and gamma are essentially identical. Third is the same gamma correction from before. Gamma is better but colours are off (in this particular case, noticeable mostly in the water). Fourth is yah’s default. Both colours and gamma are off. Strange artifacts show up in the water too.

Now I’m not a programmer so I can’t help with the code, but my background is photography and video, and I have quite a bit of experience when it comes to grading stuff, so I can probably lend a hand in finding out what’s going on.

And finally

Please do! And that’s correct, it doesn’t work with the multipass version. The setting only sort of deconverges the Y axis.

Regarding single pass, here’s a simple chain with color mangler prepended. Jitter not working, deconvergence again. Loss of vertical sharpness can be easily fixed with BEAM_FILTER = “0.000000”, but jitter is lost. (Edit: as stated earlier, this doesn’t happen in Vulkan),

shaders = "2"
feedback_pass = "0"
shader0 = "shaders_slang/misc/shaders/color-mangler.slang"
alias0 = ""
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
shader1 = "shaders_slang/crt/shaders/crt-yah/crt-yah.single-pass.slang"
alias1 = ""
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
filter_linear1 = "true"
float_framebuffer1 = "false"
srgb_framebuffer1 = "false"
gamma_boost_r = "0.200000"
gamma_boost_g = "-0.100000"
gamma_boost_b = "-0.100000"
r = "0.900000"
g = "1.050000"
b = "1.050000"
gb = "0.050000"
GLOBAL_MASTER = "1.750000"
COLOR_TEMPERATUE = "-0.200000"
COLOR_SATURATION = "1.400000"
COLOR_CONTRAST = "0.300000"
COLOR_BRIGHTNESS = "0.750000"
COLOR_OVERFLOW = "2.000000"
SCANLINES_STRENGTH = "1.000000"
BEAM_WIDTH_MIN = "0.000000"
BEAM_WIDTH_MAX = "1.500000"
BEAM_SHAPE = "0.750000"
BEAM_FILTER = "-0.250000"
MASK_BLEND = "0.250000"
MASK_COLOR_BLEED = "1.000000"
CRT_CURVATURE_AMOUNT = "0.050000"
CRT_CORNER_RAIDUS = "0.020000"
CRT_CORNER_SMOOTHNESS = "0.500000"

Phew that was quite the post wasn’t it.

1 Like

I recently discovered crt-yah too and I really like it. Just one question, is there a way to sharpen the composite look of the shader?

1 Like

Alright figured it out (single pass). It was much simpler than I thought it would be. The following values, with everything else at yah’s defaults

COLOR_CONTRAST = "-0.250000"
COLOR_BRIGHTNESS = "0.400000"
CRT_NOISE_AMOUNT = "0.000000"

Gave me this image

Which is nearly indistinguishable from the raw reference I posted before in terms of gamma/colour. It was mostly the contrast setting (defaults at 0.50) that was giving me issues.

Now I’m not saying this should be anyone’s final target, by any means! My settings for actually playing will be much more aggressive than that (see second image on this post for reference), and everyone will of course have their own. What I’m trying to provide here (first image) is a natural looking starting point that matches the original characteristics of the source :slight_smile:

My personal preferences hover around something like this (I actually modified the shader parameter file itself a little bit to achieve them, for more mask and more scanlines)

Looks absolutely stunning to me. Yah is a beast

3 Likes

@Dante There is no sharpness setting for the NTSC pass yet.

@Squalo I looked into the jitter issue, but I have to say that it works for me. However, the -0.25 setting is very subtle. Another factor that could contribute to the phenomenon you observed is the frequency of 60 Hz, which maybe too high

Can you check crt-yah.fs.h in line 249 and change the following:

GetUniformFrameCount(60) to GetUniformFrameCount(30)

Hope this gives you better results.

There could also be a bug in GetUniformFrameCount, because I only test it on 60 Hz monitors. GetUniformFrameCount tries to normalize refresh rates, so that the effect always has the same speed regardless of the used monitor. Internally it tries to estimate the frame rate by looking at the FrameTimeDelta, which is error prone. Unfortunately libretro does not provide a global uniform for the monitor refresh rate. (Btw. what is your refresh rate?)

I also looked at the gamma issue. And as you just mentioned it’s the contrast setting that is messing around. I’ll probably expose the gamma setting for the user.

However, I don’t think the noise has too much of an impact on the black level. The Scanlines Strength and Mask Intensity contribute much more. That’s also the reason why you still see the mask in the black parts of Sonic, his pupils and nose.

1 Like

The main difference is that the old method operates in RGB space with one dimension for each phosphor, so the red phosphor can only change color in the red scale, etc.

The new method treats each phosphor in its own 3-dimensional color space, using xy chromaticity to define each phosphor. So as the phosphor decays, it can shift color. This gives us color correction of the raw RGB input to sRGB (or BT.2020 or whatever) for free, in addition to the phosphor effect.

In addition, you can specify single-phosphor and two-phosphor mode. The single-phosphor mode is especially useful for simulating monochrome displays (a simple linear matrix conversion will not give the correct colors across grayscale). The two-phosphor mode allows for some cool effects (e.g. start purple then fade to yellow) but AFAIK was only ever used for industrial applications. There are also more parameters to control the decay time more finely.

2 Likes

@Jezze I promise you, as soon as I prepend something else to the shader, jitter stops working completely and the only effect I get from changing the setting is that Y “deconvergence” I mentioned earlier. My refresh is Free-Sync 100hz, but if that were a factor I wouldn’t be able to see the effect at all right? And it works perfectly fine when yah is doing its thing alone. It only stops when I prepend more stuff. Could it be a driver issue? I will test dx, glcore and vulkan and report back. I will try the GetUniformFrameCount thing right away too.

Could anyone else please give it a go? Lend us a hand here! @Nesguy I’m looking at you, I see you out there haha

As for the gamma, here’s a request that you might not expect: please do not remove your method from the chain. It’s really ingenious and out-of-the-box-cool and the more I understand how it functions the more I like it, especially now that I can make shadows darker by turning noise off. If that switch between traditional/Jezze I suggested earlier is not a possibility, then leave it as it is currently :slight_smile:

Also please bear in mind that my “gamma complaints” have a lot to do with the default settings but very little with the actual black level method itself, as all the images that I posted clearly demonstrate. Particularly the last one, which is extremely faithful to the raw reference and the only really meaningful change is the default contrast value. My point was to change those defaults so that people who start using yah get a more faithful-to-source image right off the bat, and can start tweaking from there.

@anikom15 wow cool stuff :open_mouth: Can it simply be added to a chain so that any crt shader will take advantage or does it need to be implemented by the dev?

1 Like

Currently in bed recovering from ankle surgery, going nuts not able to use my computer. You’ve been busy! Enjoying the posts. I’ve got a few things to test once I’m moving around again.

5 Likes

Aw shit. Wish you a quick, full recovery my man. Yeah been busy indeed, it’s the least that we the powertweakers can do isn’t it. I’m going through all the shaders again at 4K and 1440P (happy to finally leave 720p behind), really enjoying the new computer. And discovering fresh (for me at least) ones like @DariusG 's consumer, @beans 's beans, @Jezze 's yah, @Hyllian 's hyllian 2.0 or that weirdo whkrmrgks0 (which is actually quite interesting). So many toys to play with!

Well you have one more now. Come back soon! :slight_smile:

2 Likes

@Squalo I’m not sure how familiar you are with Git, but I added a “Black Lightening” parameter, with a default value of 1, which maintains the previous behavior. However, it can be lowered to 0 to disable the black level lightening effect caused by scanlines, mask and noise.

Here is the branch with the changes: https://github.com/ImJezze/slang-shaders/tree/crt-yah

Let me know if this is what you had in mind.

1 Like

It can but you need to do it in this order:

  1. Any chain of shaders as long as the final output is gamma corrected
  2. phosphor-luma.slang
  3. phosphor-chroma.slang
  4. A linearization shader that applies a 2.4 power gamma correction, because the output from phosphor-chroma is in linear space
  5. Any chain of shaders

This is because these shaders are part of Scanline Classic and there is a shader called scanline-advance that comes after it (does interlacing, geometry, and upscaling) and it requires a linearized input and does the gamma correction as the last step.

You also need to use float_framebuffer = true for both shaders.

@Jezze it was a driver issue after all. Tried them all and under d3d/glcore jitter breaks when prepending shaders, at least on my AMD-based computer. Works perfectly fine in vulkan. I hope some nVidia/Intel users will report their experience. I also updated my review. It’s now more accurate, in accord with our findings :slight_smile:

Wow that was quick, appreciate it. I will try the new version today when I get home, but yeah it sounds exactly like what I had in mind. Edit: you actually made it a slider, instead of a simple switch like I had proposed. That way we get the best of both worlds. This is perfect.

I have a quick question regarding brightness compensation. I configured a chain for a really bright game and when I apply it to different ones I notice that they still look great. Your implementation is adaptive, right? If I understand it correctly, it’s in fact more than just compensation, and can be used (to a certain extent) as an automatic brightness control. Kind of like a compressor-limiter in audio terms, if you know what I mean.

@anikom15 cool, will try that too. What kind of visually perceptible changes should I be looking for?

1 Like

Good to know the jitter problem is only caused by certain video drivers. I usually only use Vulkan, because it compiles 10 times faster than others, at least on my machine. I will keep looking into this problem with the other drivers, maybe I find a solution, but I cannot promise.

I’m glad you like the new parameter for the Black Lightening. I’ll raise a pull request in the upcoming days.

In regards to the brightness compensation: It’s mainly influenced by the shaders own settings for scanlines and mask. However when using the “additive” mask blend mode, the brightness of the current pixel is also taken into account.

1 Like

I’m actually switching to vulkan for all the cores that get along with it. I had been thinking about it for a while anyway. Your shader (which I will be using a lot) is the straw that broke the camel’s back, so it’s perfectly fine by me if scanline jitter stays as a vulkan exclusive, and I can’t see anyone complaining about it :slight_smile:

Nice. It does an excellent job.

Just a little update. Scanline jitter is fixed in glcore with latest AMD drivers.

1 Like

Just raised a PR with the new “Black Lightening” parameter. The default setting of 1.0 keeps the original appearance.

@Squalo That’s interesting and confusing at the same time. Because the only thing the jitter code does is alternating the texture coordinate over time depending on the frame rate. But good to know that it now works, at least for the glcore (and vulkan) renderer.

1 Like

Yes it is. I’ve been testing things thoroughly to be sure that my analysis/review was fair and consistent. Another weird little spin is that the effect is less obvious in glcore than vulkan. I. E. you have to lower the beam filter parameter to achieve the same “jitter intensity”. It’s working great nonetheless with the new drivers. Again, it would be nice if more users tested it, but the forum seems a little quiet these days.

hi, i’ve looked and its nice.

do you think is possible to incorporate ntsc rainbow effect on future ?

i mean for megadrive or nes/snes

I’m not exactly sure how the “rainbow” effect is defined. But you can set the following parameters and get something similar; the rainbow lines go diagonal though.

NTSC_PROFILE = 5.0
NTSC_QUALITY = 3.0

NTSC_PROFILE = 5.0 increases the fringing and artifacting (the slider only allows a maximum of 3.0) and NTSC_QUALITY = 3.0 makes use of 3-phase modulation with field merge (which basically deactivates the flickering).

1 Like

I checked but didnt give something remotely close. Diagonal rainbow is for NES, though.

That’s a small text file where i saved several original Genesis Rainbow records, in case can be useful to see how the effect does.

Unless you referred to something else as “not sure how rainbow is defined”.

Still, look very good with dithering alone