Shader Challenge: composite video on a PVM

Probably not, something broke me and I no longer have any patience for tweaking shaders. Hence this thread


I took a brief look at what you guys have been working on and it’s pretty good! At least in a screenshot. Things tend to fall apart in fullscreen, as we all know. I’ll be able to take a closer look some time today.


Well this has to be an honour! Everyone has to go through their own process of experimenting, learning and evolution over time.

I posted a couple screenshots over at r/crtgaming just to see people’s reactions and I would say that this preset either passed or almost passed the Pepsi challenge.

Most users were so fixated on the aspect ratio being incorrect or my speakers being too close to the monitor that they didn’t even notice that it was a CRT Shader they were looking at (at least at first glance)!

I did a second one of my work in progress shadow mask and a new NTSC preset but that one didn’t have the speakers in the Shadow Mask preset screenshots so it was much easier for people to tell it was a shader. Those were also deliberately dark becsuse I was initially trying to match a reference picture which was dark and while some couldn’t appreciate the beauty of the way the shader made the graphics look due to the darkness as well as whatever biases they might have had, the responses were generally favourable with a few people actually being fooled into not realizing it was a shader they were looking at at first glance!


How did you manage to deal with the ringing? Can you post the sharpness settings you used?


I had been avoiding the “sharpness definition” setting because it was producing really horrible artifacts in an earlier iteration. Looks like that’s no longer the case, I can see now that this is a pretty useful setting.


I really don’t know. I didn’t have any issues with ringing before. I actually deliberately cranked up Fast Sharpen in earlier presets because I felt the added ringing and other artifacts made things look more analog. I got these nice, thick clean lines by first disabling Fast Sharpen because it decreased the contrast of the edges, also adjusting my gamma, leaning more to the lower side. As for the sharpness, I just lowered the Horizontal Filter Range slightly and increased the Subtractive Sharpness slightly.

All of my settings are available in my latest preset pack.

These are actually my first presets using crt-guest-advance-NTSC (via HSM Mega Bezel Reflection Shader of course).

These require HSM Mega Bezel Reflection Shader version 1.7.0 currently, since v1.8.0, the NTSC Filtering settings have been broken. Your reaction to these presets is exactly the reason why I’ve been lamenting that they’ve been altered. My lamentations have not gone unnoticed though and fixes should arrive at some point. In the interim, I’ve been using a self patched version of the shader in order to have those working and still be able to work on the new Shadow Mask stuff at the same time while keeping up to date.

I haven’t touched Sharpness Definition yet but I did interfere with Adaptive Sharpness as well.

I also encountered some very wild artifacts depending on the combination of NTSC Horizontal Filter Range and NTSC Subtractive Sharpness used so I just adjusted things a little at a time to try to keep things “within range”.

Lots of trial and error involved. That’s how I get my results. I also do a lot of fine tuning from a distance in order to get rid of that last sometimes hidden bit of blur which makes everything unusable for me.

1 Like

I can’t actually extract the shader pack because I’m getting a “path too long” error.

Adaptive Sharpness has a tendency to break dithering, last time I checked. It’s been several months since I played with it, though.

Does adaptive sharpening still break dithering?

Personally, I’d like to see some different approaches to NTSC shading. It couldn’t hurt. It seems like with the current tools available to us, we can only make the image sharper at the expense of adding ringing, or by breaking dithering.

For example, if I increase sharpening using the custom fast sharpen, you get ringing to the left of the letters in the SMB logo. This isn’t present in the composite video photo of the PVM. Something similar happens with subtractive sharpness. In the real CRT photo, I see darker spots to the right of the white pixels, and bright spots to the right of some dark pixels.

Then again, Cyber seems to have found some kind of magic combination of settings that doesn’t show ringing while looking sharp. I’m wondering if the mask is doing a lot of work to disguise the ringing, or if the higher resolution is helping.

The other thing I’m concerned with is the scanline taper where a bright pixel transitions to a darker pixel. There’s actually very little of this in the real CRT photo. It’s not a smooth taper, it’s a square edged taper with a sharp transition from one pixel to the next. That’s been very difficult to replicate.

1 Like

Instead of trying to Extract, you can open the archive using Windows Explorer or 7zip and copy then paste. You could also try copying the archive to a root drive or folder then copying and pasting the contents there.

1 Like

I took a quick look and I’m fairly sure that it’s a combination of the mask and resolution that’s making the artifacts less noticeable. How does it look when you remove the mask?

I haven’t noticed anything unusual here comparing with the standard settings, but with genesis etc. games negative values are to be used. Sometimes it looks like the blend isn’t 100% smooth, but this is mostly not an adaptive sharpening issue.

Standard ntsc:

Adaptive sharpening at -5.0:

I’ll also make a remark that NES/SNES games are triggering 3-phase filtering with ntsc shaders, which don’t fully blend dithering. You must force 2-phase mode for the full effect.


@Cyber I can’t actually get the presets to load although I’ve followed the installation instructions. Would you mind posting a shot of the NTSC preset from the screenshot above without the mask so we can really see what’s going on?

1 Like

Hmmm…this is strange. I wonder why.

I don’t mind but it might be a little later. I’m not even on Mega Bezel Reflection Shader v1.7.0 anymore so those presets may not look identical so I’ll have to revert first.

In the meantime, do the HSM Mega Bezel Reflection Shader base presets load fine for you? Especially the GDV-NTSC ones? You should be on version v1.7.0 if you would like to view these properly.

Just realized that I used the version without the graphics but the preset is supposed to be virtually identical apart from settings to fit the graphics and some slight curvature.

CyberLab_NES_Composite_Slot_Mask_IV_OLED_NTSC sans Mask

Slightly tweaked version of the same preset.

Further tweaked version of the same preset.

Varying levels of sharpness.

NES NTSC Artifacts still intact.

…and getting closer to this reference pic:

1 Like

I’m still seeing some very unpleasant edge artifacts, unfortunately. I think you’ve done about as good a job as possible with the tools that are available.

And yes, I’m using the most recent Mega Bezel, so that’s why the presets won’t load.

The first SMB shot under “varying levels of sharpness” is probably the best in terms of sharpness/artifacts.

My presets should load fine on the latest Mega Bezel but the NTSC ones just won’t look as they should. I was just trying to find out if the Megs Bezel default presets work for you to see if I might be able to better understand why my presets are not loading on your machine.

If your shader path is too deep (has too many characters in the path) that can cause an issue. Other than that, you can feel free to make a bug report and I’ll investigate further. Something like that not working would trigger my OCD.

I still think there might be room for further alteration and possibly improvement. I would say I’m still learning quite a bit about how different settings and values affect things.

It’s quite possible that those edge artifacts can be further manipulated using the Fringing, NTSC Artifacting and NTSC Scale controls among other settings.

1 Like

btw, this is another great reference image posted by Jamirus. This is not a high-quality TV.

1 Like

Thanks, besides the excessive saturation, this actually may not be that far off from my current NES Slot Mask NTSC presets.

There’s definitely some resemblance.

1 Like

Here’s a recent attempt. It’s not bright enough, but when I crank up the bright boosts the sharpness of the white text goes to hell.

shaders = "18"
shader0 = "shaders_slang/crt/shaders/guest/advanced/stock.slang"
filter_linear0 = "false"
wrap_mode0 = "clamp_to_border"
mipmap_input0 = "false"
alias0 = ""
float_framebuffer0 = "false"
srgb_framebuffer0 = "false"
scale_type_x0 = "source"
scale_x0 = "1.000000"
scale_type_y0 = "source"
scale_y0 = "1.000000"
shader1 = "shaders_slang/crt/shaders/guest/advanced/stock.slang"
filter_linear1 = "false"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = "StockPass"
float_framebuffer1 = "false"
srgb_framebuffer1 = "false"
scale_type_x1 = "source"
scale_x1 = "1.000000"
scale_type_y1 = "source"
scale_y1 = "1.000000"
shader2 = "shaders_slang/crt/shaders/guest/advanced/afterglow0.slang"
filter_linear2 = "true"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "false"
alias2 = "AfterglowPass"
float_framebuffer2 = "false"
srgb_framebuffer2 = "false"
scale_type_x2 = "source"
scale_x2 = "1.000000"
scale_type_y2 = "source"
scale_y2 = "1.000000"
shader3 = "shaders_slang/crt/shaders/guest/advanced/pre-shaders-afterglow.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = "PrePass0"
float_framebuffer3 = "false"
srgb_framebuffer3 = "false"
scale_type_x3 = "source"
scale_x3 = "1.000000"
scale_type_y3 = "source"
scale_y3 = "1.000000"
shader4 = "shaders_slang/crt/shaders/guest/advanced/ntsc/ntsc-pass1.slang"
filter_linear4 = "false"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "false"
alias4 = "NPass1"
float_framebuffer4 = "true"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "4.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "shaders_slang/crt/shaders/guest/advanced/ntsc/ntsc-pass2.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = ""
float_framebuffer5 = "true"
srgb_framebuffer5 = "false"
scale_type_x5 = "source"
scale_x5 = "0.500000"
scale_type_y5 = "source"
scale_y5 = "1.000000"
shader6 = "shaders_slang/crt/shaders/guest/advanced/ntsc/ntsc-pass3.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = ""
float_framebuffer6 = "false"
srgb_framebuffer6 = "false"
scale_type_x6 = "source"
scale_x6 = "1.000000"
scale_type_y6 = "source"
scale_y6 = "1.000000"
shader7 = "shaders_slang/crt/shaders/guest/advanced/custom-fast-sharpen.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = "NtscPass"
float_framebuffer7 = "false"
srgb_framebuffer7 = "false"
scale_type_x7 = "source"
scale_x7 = "1.000000"
scale_type_y7 = "source"
scale_y7 = "1.000000"
shader8 = "shaders_slang/crt/shaders/guest/advanced/stock.slang"
filter_linear8 = "true"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "true"
alias8 = "PrePass"
float_framebuffer8 = "false"
srgb_framebuffer8 = "false"
scale_type_x8 = "source"
scale_x8 = "1.000000"
scale_type_y8 = "source"
scale_y8 = "1.000000"
shader9 = "shaders_slang/crt/shaders/guest/advanced/avg-lum-ntsc.slang"
filter_linear9 = "true"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "true"
alias9 = "AvgLumPass"
float_framebuffer9 = "false"
srgb_framebuffer9 = "false"
scale_type_x9 = "source"
scale_x9 = "1.000000"
scale_type_y9 = "source"
scale_y9 = "1.000000"
shader10 = "shaders_slang/crt/shaders/guest/advanced/linearize-ntsc.slang"
filter_linear10 = "true"
wrap_mode10 = "clamp_to_border"
mipmap_input10 = "false"
alias10 = "LinearizePass"
float_framebuffer10 = "true"
srgb_framebuffer10 = "false"
scale_type_x10 = "source"
scale_x10 = "1.000000"
scale_type_y10 = "source"
scale_y10 = "1.000000"
shader11 = "shaders_slang/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass1.slang"
filter_linear11 = "true"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
alias11 = "Pass1"
float_framebuffer11 = "true"
srgb_framebuffer11 = "false"
scale_type_x11 = "viewport"
scale_x11 = "1.000000"
scale_type_y11 = "source"
scale_y11 = "1.000000"
shader12 = "shaders_slang/crt/shaders/guest/advanced/gaussian_horizontal.slang"
filter_linear12 = "true"
wrap_mode12 = "clamp_to_border"
mipmap_input12 = "false"
alias12 = ""
float_framebuffer12 = "true"
srgb_framebuffer12 = "false"
scale_type_x12 = "absolute"
scale_x12 = "800"
scale_type_y12 = "source"
scale_y12 = "1.000000"
shader13 = "shaders_slang/crt/shaders/guest/advanced/gaussian_vertical.slang"
filter_linear13 = "true"
wrap_mode13 = "clamp_to_border"
mipmap_input13 = "false"
alias13 = "GlowPass"
float_framebuffer13 = "true"
srgb_framebuffer13 = "false"
scale_type_x13 = "absolute"
scale_x13 = "800"
scale_type_y13 = "absolute"
scale_y13 = "600"
shader14 = "shaders_slang/crt/shaders/guest/advanced/bloom_horizontal.slang"
filter_linear14 = "true"
wrap_mode14 = "clamp_to_border"
mipmap_input14 = "false"
alias14 = ""
float_framebuffer14 = "true"
srgb_framebuffer14 = "false"
scale_type_x14 = "absolute"
scale_x14 = "800"
scale_type_y14 = "absolute"
scale_y14 = "600"
shader15 = "shaders_slang/crt/shaders/guest/advanced/bloom_vertical.slang"
filter_linear15 = "true"
wrap_mode15 = "clamp_to_border"
mipmap_input15 = "false"
alias15 = "BloomPass"
float_framebuffer15 = "true"
srgb_framebuffer15 = "false"
scale_type_x15 = "absolute"
scale_x15 = "800"
scale_type_y15 = "absolute"
scale_y15 = "600"
shader16 = "shaders_slang/crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass2.slang"
filter_linear16 = "true"
wrap_mode16 = "clamp_to_border"
mipmap_input16 = "false"
alias16 = ""
float_framebuffer16 = "true"
srgb_framebuffer16 = "false"
scale_type_x16 = "viewport"
scale_x16 = "1.000000"
scale_type_y16 = "viewport"
scale_y16 = "1.000000"
shader17 = "shaders_slang/crt/shaders/guest/advanced/deconvergence-ntsc.slang"
filter_linear17 = "true"
wrap_mode17 = "clamp_to_border"
mipmap_input17 = "false"
alias17 = ""
float_framebuffer17 = "false"
srgb_framebuffer17 = "false"
scale_type_x17 = "viewport"
scale_x17 = "1.000000"
scale_type_y17 = "viewport"
scale_y17 = "1.000000"
wp_saturation = "1.000000"
contr = "-0.000000"
ntsc_scale = "0.990000"
ntsc_shape = "1.000000"
CSHARPEN = "5.000000"
CCONTR = "0.250000"
CDETAILS = "0.000000"
GAMMA_INPUT = "2.400000"
gamma_out = "2.200000"
HSHARPNESS = "1.000000"
S_SHARP = "0.000000"
HSHARP = "0.000000"
HARNG = "0.000000"
spike = "2.000000"
m_glow = "1.000000"
glow = "0.020000"
brightboost = "1.600000"
brightboost1 = "1.300000"
gsl = "2.000000"
scanline1 = "5.000000"
scanline2 = "20.000000"
beam_max = "1.200000"
scans = "0.500000"
maskstr = "1.000000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
SamplerLUT1 = "shaders_slang/crt/shaders/guest/advanced/lut/trinitron-lut.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt/shaders/guest/advanced/lut/inv-trinitron-lut.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "shaders_slang/crt/shaders/guest/advanced/lut/nec-lut.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"
SamplerLUT4 = "shaders_slang/crt/shaders/guest/advanced/lut/ntsc-lut.png"
SamplerLUT4_linear = "true"
SamplerLUT4_wrap_mode = "clamp_to_border"
SamplerLUT4_mipmap = "false"
1 Like

The sharpness is pretty close, yeah. I really don’t like the bloom haze over highlights, but that’s my personal preference and I assume a necessary trade off if you want the image to be bright enough.

The PVM is a lot trickier.

1 Like

@guest.r Is there some kind of alteration to the code we can make to reduce the blurring/swelling of highlights that occurs when using high brightness settings?


You can also try lowering input/output gamma values to get a better transition. With modern versions they more or less affect horizontal filtering.