Please show off what crt shaders can do!

Does anyone know why afterglow/phosphor persistence is so hard to pick up in screenshots? I’m seeing it in-game, but not in screenshots. I want to make pretty screenshots with afterglow.

3 Likes

If you are using snapshot from the menu and the game pauses while you are in the menu, that is why you aren’t seeing the Afterglow.

When you are in the menu even though the game is paused the shader keeps updating every frame…

If you use a windows screen grab utility that should do it

4 Likes

Still working on these. Getting the colors to look right with scanline type 2 is difficult.

6 Likes

Wowww!!! Second image is awesome!! Good work @Nesguy mate!!

1 Like

Thanks, although I’m still not happy with them, lol.

Colors still seem off with the second preset no matter what I do, might need to change scanline types or it could be the mask I’m using, although I checked and it’s the correct colors for the subpixels I have.

First preset… I dunno, it’s tough to dial in sharpness and convergence when the phosphors are this chunky, details like small text are still bothering me. I might need to remove the deconvergence.

I think these are better…? I removed horizontal deconvergence from the low TVL mask and reduced the beam dynamics a bit in both. This resulted in improved (IMO) color and contrast with the high TVL mask, and better sharpness/detail with the low TVL mask. Helps reduce curvature-related moire, too.

edit, playing around with halation/glow/bloom now.

4 Likes

One thing that can help a lot when deciding what shaders you want, is to actually check a real CRT in your house. I thought I would share these images for reference. All of these are actual photos that were taken from an actual NES cartridge ( Megaman 5 ) running on a Panasonic box style CRT.

From this you can clearly see a few things:

-Having no shader at all is definitely “wrong” ( I say “wrong” in quotes here since it’s all subjective to what people prefer anyways ) in at least it’s not an accurate depiction of how games looked. The base output of old games was specifically designed to work with CRT displays as a “real” shader effect if that makes any sense.

-A very slight glow effect can be accurate or not depending on scene.

-Zoom in on those mountains for a good look on how CRT displays aided pixel graphics rather than hindered them.

I’ve personally found that you have to fiddle with each display to get a CRT filter that looks accurate since not all HD-TVs are created equal. This is the annoying answer, but it’s kind of true. Easymode combined with a minor glow shader tends to come very close in most cases though.

3 Likes

slang_shaders/presets/crt-geom-ntsc-composite-sharp.slangp
ntsc colors 1 in the parameters, svideo parameter to avoid capturing just a part of the composite signal
fceumm using nescap palette

4 Likes

Would be nice to see some better closeups that show the phosphor mask.

Here’s an in-focus close-up of a Trinitron:

Current progress. Will post settings once I’m done.

6 Likes

Alright, that low TVL mask was just overdoing the black space between phosphors, and the TVL (270) is just really too low IMO. It might work with maybe a 40" display sitting 9 feet away, I dunno. It was too coarse on my 60" TV at that distance.

Here’s a 360 TVL mask, I just changed the “2” in the code under mask 7 to a “3”. I think this is much easier on the eyes while still looking very consumer-grade.

shaders = "12"
shader0 = "shaders_slang/misc/grade.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 = "false"
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 = "false"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "true"
alias3 = "PrePass"
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/avg-lum.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "true"
alias4 = "AvgLumPass"
float_framebuffer4 = "false"
srgb_framebuffer4 = "false"
scale_type_x4 = "source"
scale_x4 = "1.000000"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "shaders_slang/crt/shaders/guest/advanced/linearize.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = "LinearizePass"
float_framebuffer5 = "true"
srgb_framebuffer5 = "false"
scale_type_x5 = "source"
scale_x5 = "1.000000"
scale_type_y5 = "source"
scale_y5 = "1.000000"
shader6 = "shaders_slang/crt/shaders/guest/advanced/gaussian_horizontal.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = ""
float_framebuffer6 = "true"
srgb_framebuffer6 = "false"
scale_type_x6 = "absolute"
scale_x6 = "800"
scale_type_y6 = "source"
scale_y6 = "1.000000"
shader7 = "shaders_slang/crt/shaders/guest/advanced/gaussian_vertical.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = "GlowPass"
float_framebuffer7 = "true"
srgb_framebuffer7 = "false"
scale_type_x7 = "absolute"
scale_x7 = "800"
scale_type_y7 = "absolute"
scale_y7 = "600"
shader8 = "shaders_slang/crt/shaders/guest/advanced/bloom_horizontal.slang"
filter_linear8 = "true"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "false"
alias8 = ""
float_framebuffer8 = "true"
srgb_framebuffer8 = "false"
scale_type_x8 = "absolute"
scale_x8 = "800"
scale_type_y8 = "absolute"
scale_y8 = "600"
shader9 = "shaders_slang/crt/shaders/guest/advanced/bloom_vertical.slang"
filter_linear9 = "true"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "false"
alias9 = "BloomPass"
float_framebuffer9 = "true"
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/crt-guest-advanced.slang"
filter_linear10 = "true"
wrap_mode10 = "clamp_to_border"
mipmap_input10 = "false"
alias10 = ""
float_framebuffer10 = "false"
srgb_framebuffer10 = "false"
scale_type_x10 = "viewport"
scale_x10 = "1.000000"
scale_type_y10 = "viewport"
scale_y10 = "1.000000"
shader11 = "shaders_slang/crt/shaders/guest/advanced/deconvergence.slang"
filter_linear11 = "true"
wrap_mode11 = "clamp_to_border"
mipmap_input11 = "false"
alias11 = ""
float_framebuffer11 = "false"
srgb_framebuffer11 = "false"
scale_type_x11 = "viewport"
scale_x11 = "1.000000"
scale_type_y11 = "viewport"
scale_y11 = "1.000000"
g_vignette = "0.000000"
wp_temperature = "8004.000000"
bogus_afterglow = "1.000000"
PR = "0.200000"
PG = "0.200000"
PB = "0.200000"
AS = "0.600000"
sat = "1.000000"
GAMMA_INPUT = "2.500000"
glow = "0.013000"
bloom = "0.050000"
halation = "0.200000"
brightboost = "1.000000"
brightboost1 = "3.000000"
beam_min = "1.000000"
beam_size = "0.000000"
vertmask = "1.000000"
scans = "1.000000"
spike = "0.000000"
h_sharp = "3.000000"
s_sharp = "0.000000"
warpX = "0.030000"
warpY = "0.040000"
shadowMask = "7.000000"
maskstr = "0.700000"
mcut = "0.300000"
mask_gamma = "2.500000"
slotwidth = "4.000000"
mclip = "0.000000"
gamma_out = "2.500000"
deconrr = "1.000000"
deconrb = "-1.000000"
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
SamplerLUT1 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron1.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron2.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "shaders_slang/crt/shaders/guest/lut/other1.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"
SamplerLUT4 = "shaders_slang/crt/shaders/guest/lut/custom_lut.png"
SamplerLUT4_linear = "true"
SamplerLUT4_wrap_mode = "clamp_to_border"
SamplerLUT4_mipmap = "false"
8 Likes

Don’t know if it was your purpose but looks more like S-Video or something. Probably need a bit more sharpness for that RGB look.

1 Like

Yeah, I’m definitely going for more of a consumer-grade feel with the above setup. I added deconvergence and a bit of glow/halation. None of it works when you scrutinize the image up close, of course.

I think it’s still cleaner than S-video, though. Maybe a TV that’s been modded for RGB.

Sharpness is a persistent issue, though. I don’t use smart edges or subtractive sharpness because both result in unwanted artifacts. I think maybe I need GTU but I’m not sure how to add it to GDV.

2 Likes

Looks like a standard arcade monitor to me, which would be: consumer-quality tube, RGB connection. :slight_smile:

3 Likes

My Trinitron TV definitely looks sharper than this on all RGBs connected to it (PC-Wii-Amiga 500). But not much difference, probably only need a bit of sharpness more, something like 4.0 instead of 3.0

Looks really good with sharpness 4.0 and subtractive 0.20. Still halation/glow is a bit too much compared to a good CRT.

4 Likes

Yeah halation needs to come down, probably. Otherwise the highlights blob together a bit too much and it looks a bit like an overexposed photograph. I’m also trying to minimize curvature-related moire, so decreasing the bright beam width isn’t really an option.

Would be nice to get some comparison shots if/when you get some time. 4.00 is looking a bit too harsh with some content, but the problem is that gaussian blur by itself isn’t enough. It blends some things too much and other things not enough, so it never really looks right IMO. Once curved shapes start looking appropriately curved, small details get blurred out. We need GTU, I think.

4.00 with 0.20 subtractive sharpness is working pretty well, though. edit: 0.20 is so low that it’s probably not doing much, though.

Edit, also, here’s the bit you need to change in guest-dr-venom to make the mask darken every 3rd pixel, if you want to try it out. Look for the code for mask 7.

pos.x = fract(pos.x/3.0);

1 Like

Sharpness 4.00, no subtractive sharpness or smart sharpness, lowered halation to 0.10, scanline type 2

5 Likes

Yeah now it looks superb, but changing the scanline to 2 made it look better than most consumer TV’s if that was the purpose.

1 Like

Thanks. I think it’s close to a well-cared for Wega or other high-end consumer TV. Type 1 is probably better for a more midrange/low end TV.

Type 0 makes the highlights blob together completely, and decreasing the bright beam width introduces moire if using curvature. That’s because I have vertical deconvergence maxed out though, I think it gives extra pop to highlights.

I liked @guest.r shader settings so much I went and put my own twist to it and added grade to the mix. I like the new noise setting that gives the image a “static” look so I kind of cranked that up a bit, if it’s too much you can bring it down to -20 or off.

I was on a Castlevania marathon so this post is dedicated to one of my favorite franchise of all time:

shaders = "10"
shader0 = "shaders_slang/crt/shaders/crtsim/composite.slang"
filter_linear0 = "true"
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/misc/grade.slang"
filter_linear1 = "true"
wrap_mode1 = "clamp_to_border"
mipmap_input1 = "false"
alias1 = "PrePass"
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/avg-lum.slang"
filter_linear2 = "true"
wrap_mode2 = "clamp_to_border"
mipmap_input2 = "true"
alias2 = "AvgLumPass"
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/linearize.slang"
filter_linear3 = "true"
wrap_mode3 = "clamp_to_border"
mipmap_input3 = "false"
alias3 = "LinearizePass"
float_framebuffer3 = "true"
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/gaussian_horizontal.slang"
filter_linear4 = "true"
wrap_mode4 = "clamp_to_border"
mipmap_input4 = "false"
alias4 = ""
float_framebuffer4 = "true"
srgb_framebuffer4 = "false"
scale_type_x4 = "absolute"
scale_x4 = "800"
scale_type_y4 = "source"
scale_y4 = "1.000000"
shader5 = "shaders_slang/crt/shaders/guest/advanced/gaussian_vertical.slang"
filter_linear5 = "true"
wrap_mode5 = "clamp_to_border"
mipmap_input5 = "false"
alias5 = "GlowPass"
float_framebuffer5 = "true"
srgb_framebuffer5 = "false"
scale_type_x5 = "absolute"
scale_x5 = "800"
scale_type_y5 = "absolute"
scale_y5 = "600"
shader6 = "shaders_slang/crt/shaders/guest/advanced/bloom_horizontal.slang"
filter_linear6 = "true"
wrap_mode6 = "clamp_to_border"
mipmap_input6 = "false"
alias6 = ""
float_framebuffer6 = "true"
srgb_framebuffer6 = "false"
scale_type_x6 = "absolute"
scale_x6 = "800"
scale_type_y6 = "absolute"
scale_y6 = "600"
shader7 = "shaders_slang/crt/shaders/guest/advanced/bloom_vertical.slang"
filter_linear7 = "true"
wrap_mode7 = "clamp_to_border"
mipmap_input7 = "false"
alias7 = "BloomPass"
float_framebuffer7 = "true"
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/crt-guest-advanced.slang"
filter_linear8 = "true"
wrap_mode8 = "clamp_to_border"
mipmap_input8 = "false"
alias8 = ""
float_framebuffer8 = "false"
srgb_framebuffer8 = "false"
scale_type_x8 = "viewport"
scale_x8 = "1.000000"
scale_type_y8 = "viewport"
scale_y8 = "1.000000"
shader9 = "shaders_slang/crt/shaders/guest/advanced/deconvergence.slang"
filter_linear9 = "true"
wrap_mode9 = "clamp_to_border"
mipmap_input9 = "false"
alias9 = ""
float_framebuffer9 = "false"
srgb_framebuffer9 = "false"
scale_type_x9 = "viewport"
scale_x9 = "1.000000"
scale_type_y9 = "viewport"
scale_y9 = "1.000000"
Tuning_Sharp = "0.300000"
NTSCArtifactScale = "0.000000"
g_space_out = "3.000000"
wp_temperature = "8004.000000"
g_sat = "0.400000"
g_lift = "-0.040000"
interm = "5.000000"
bloom = "0.900000"
halation = "0.500000"
gamma_c = "1.400000"
gsl = "-1.000000"
h_sharp = "2.000000"
s_sharp = "0.000000"
BLOOM = "1.000000"
csize = "0.030000"
barspeed = "200.000000"
barintensity = "0.010000"
warpX = "0.030000"
warpY = "0.040000"
c_shape = "0.600000"
shadowMask = "7.000000"
maskstr = "0.750000"
maskDark = "0.000000"
maskLight = "1.000000"
mask_gamma = "1.600001"
slotmask = "0.750000"
slotwidth = "1.000000"
slotms = "2.000000"
deconrr = "0.750000"
deconrb = "-0.750000"
deconrry = "1.500000"
deconrby = "-1.500000"
decons = "-2.000002"
addnoised = "-0.300000"
textures = "MaskTexture;NTSCArtifactSampler;shadowMaskSampler;SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
MaskTexture = "shaders_slang/crt/shaders/mame_hlsl/resources/aperture-grille.png"
MaskTexture_wrap_mode = "clamp_to_border"
MaskTexture_mipmap = "false"
NTSCArtifactSampler = "shaders_slang/crt/shaders/crtsim/artifacts.png"
NTSCArtifactSampler_linear = "true"
NTSCArtifactSampler_wrap_mode = "clamp_to_border"
NTSCArtifactSampler_mipmap = "false"
shadowMaskSampler = "shaders_slang/crt/shaders/crtsim/mask.png"
shadowMaskSampler_linear = "true"
shadowMaskSampler_wrap_mode = "clamp_to_border"
shadowMaskSampler_mipmap = "false"
SamplerLUT1 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron1.png"
SamplerLUT1_linear = "true"
SamplerLUT1_wrap_mode = "clamp_to_border"
SamplerLUT1_mipmap = "false"
SamplerLUT2 = "shaders_slang/crt/shaders/guest/lut/sony_trinitron2.png"
SamplerLUT2_linear = "true"
SamplerLUT2_wrap_mode = "clamp_to_border"
SamplerLUT2_mipmap = "false"
SamplerLUT3 = "shaders_slang/crt/shaders/guest/lut/other1.png"
SamplerLUT3_linear = "true"
SamplerLUT3_wrap_mode = "clamp_to_border"
SamplerLUT3_mipmap = "false"
SamplerLUT4 = "shaders_slang/crt/shaders/guest/lut/custom_lut.png"
SamplerLUT4_linear = "true"
SamplerLUT4_wrap_mode = "clamp_to_border"
SamplerLUT4_mipmap = "false"
7 Likes