A new little shader i did (glsl)

Kinda amazing how much variance exists with border emulation in the first place still today, sizes differ substantially between emulators for the same system or authors don’t bother with implementing them at all. I guess this is the result of different approaches/goals.

1 Like

Because not needed, borders are time actually, like ~1/4 of visible area to have some time space to create signal sync, pulse, burst etc. NES in example has 341 pixels with borders but only displays 256, not needed to display all and they are not in real hardware too as they are in non visible time space.

I was thinking about the borders you can actually see, e.g. not bother with emulating beyond active 256x192 pixels for TMS graphic based systems, or in the NES example you’d just show 256x224 for NTSC I guess. Im not sure there are still emulators around for that nowadys which don’t allow to show 240 vertical res.

You can handle borders, overscan cropping, and the different Genesis modes in the shader if you want to. See the following function, where t is equivalent to vTexCoord.x. This returns the chroma subcarrier value at t.

float chroma_carrier_genesis(float t, vec4 original_size) {
    // The Genesis master clock (MCLK) is 53693175 Hz, and the chroma clock is
    // MCLK/15 (3579545 Hz). In H40 mode (320 pixel width), each pixel in the
    // active area is 8 cycles long[1]. In H32 mode (256 pixel width), each
    // pixel is 10 cycles long.
    //
    // In both modes, a full line is 3420 cycles long. Because 3420 % 15 == 0,
    // there is no phase offset between lines. With 262 lines per field[2],
    // there is also no phase offset between fields. When interlacing, there
    // are 262.5 lines per field. (3420 / 2) % 15 == 0, so there is no phase
    // offset between fields when interlacing, either.
    //
    // [1] Note that in the blanking area, some pixels in H40 mode are
    // different sizes. We can ignore that for our purposes.
    // [2] There are some half lines in the blanking area which add to full
    // lines.
    //
    // See: http://gendev.spritesmind.net/forum/viewtopic.php?f=2&t=3221

    float carrier_normalized;
    // TODO handle upscaled input and interlacing
    if (original_size.x > 300) { // H40
        carrier_normalized = 8.0 / 15.0 * original_size.x;
    } else { // H32
        carrier_normalized = 10.0 / 15.0 * original_size.x;
    }
    return PI * 2.0 * carrier_normalized * t;
}

Edit: Just to clarify, chroma_subcarrier * number_input_pixels / pixel_rate will give you the number of chroma periods across your input, whatever actual size it is. That’s all I am doing.

3 Likes

Yeah that’s the proper approach, i was just trying to keep it simple and possibly more performant without many branches (if / else).

This is after switching to NTSC 3.579 Mhz / pixel_clock on Genesis Plus GX, as i said it depends on a stable pixel clock so it won’t ever change.

3 Likes

sorry my ignorance, is there some way I can apply it?

I already did a PR, but if you want it right now enter here, download (presh CTRL-SHIFT-S) and replace the old ones with them in folder crt/shaders/crt-consumer

2 Likes

thank you once again for your amazing work, bud.

In BlastEm standalone, I saw there is a NTSC filter as well and in its Text-shader file there’s a parameter called the same as CombFilter such as you have been talking about in these threads. But in there, combFilter works to give more or less intensity to rainbow. Here from you, it seem like a dithering filter. Nothing wrong with it, just as a curiosity.

Amazing work in the name of nostalgia!

2 Likes

The closer we get to accurate composite the more I just want to use RGB, lol.

Took consumer-1w for a spin, it’s looking really “good” :smiley:

2 Likes

already works. Thank you bud.

2 Likes

Added two extra color modes to slang (keep glsl minimal as is, as slang will run to faster devices anyway), US SMPTE 7500K (probably a more realistic real value) and Japan NTSC 9300K according to this.

I believe ntsc module is pretty accurate as is and quite realistic already, both in system specific artifacts and Y/C bandwidth.

4 Likes

@DariusG wow your “Frankenstein” shader is coming out great. Shaping up to be the most complete fast one, isn’t it? It runs pretty quick indeed, especially considering all the things it does already. Well done! Is it part of the official collection yet?

3 Likes

It’s already on SLANG as “crt-consumer-1w-ntsc” (if you mean that).

Well i learned a lot in the last 2-3 years by studying established shaders like Guest.r / crt-geom / blargg’s filter, reading about ntsc, creating my own excel documents to convert srgb->smpte (reading hell of a lot before how it’s done) etc, then writing my own shaders, pushing things more and more squeezing the last ounce out of it lol. I always aim shader to be ready to load and play without much tweaking and include the things i consider they should be there to recreate the nostalgia look. Having original hardware and a CRT helps too.

All in all it’s a great hobby and has been a blast.

I am burning some hours in this game lately heh

7 Likes

Yeah, that’s exactly what I meant. You could maybe name it something more… personal? to reflect your journey towards creating it. Just a suggestion :slight_smile: since its current name is fine of course but a tad generic.

And yes, the best thing about these shaders (besides exploring the rabbit hole of endless tweaking and experimentation) is that old games can be made to look so pretty that playing them like this is way, way more enjoyable. I don’t think one can actually appreciate retro graphics without a good crt or a nice shader setup. And in most cases, that applies to modern games that use pixel graphics too. They look a thousand times better with scanlines, mask, halation, etc

1 Like

They will always look better on CRT or a shader, because they drop the digital square pixel shape and replace it with analogue look rounded one (light is round not square, and phosphors emit light), then projecting 240p on a 480p panel (which is what a CRT does) makes it look like higher resolution (pixels are smaller than raw squares). Add some extra analogue imperfections that actually help it look better like color bleed etc.

2 Likes

just look at that beautiful 90s experience thanks to @DariusG

An unexperienced guy would have no idea if this is real console or not

This is why I’ve had my doubts about these guys that talk so many wonders about expensive hardware like MiSTer FPGA

Who need hardware when you got real geniuses like DariusG ? This is the type of content makes me believe since more than a half decade already that RetroArch is the ultimate Retro experience.

Thank you so much !

4 Likes

Really great work. I had made an account and I guess it disappeared since I hadn’t posted anything and just left likes. Thank you for making this ntsc shader + consumer crt shader.

I have only tweaked it a little and just with NES, and really seems like what my TV back in the day looked like!

2 Likes

Yep, and don’t forget the lovely pointillistic effect that the mask provides. Man I need augmented reality CRT glasses…

(and btw, BoF 2 is awesome, as is 3!)

2 Likes

Not sure if this is intended or not but this is a little difference I found in Rainbow effect.

Is there some way to get a similar effect on pipes like its does for crt guest ntsc preset ?

First image is your preset, and second is from CRT guest.

Guest’s version is something I’ve truly seen way more times in real console recordings from Youtube and my own experience as well.

Thank you again.

Depends if you want to recreate a messy composite. Perhaps lower comb filter strength and reduce chroma resolution even more?

e.g. here is same game, on same TV on composite on Sega CDX (almost invisible rainbow) and Genesis model 1 which had the worst composite available at the time. It’s not they wanted it to be there, it was a side effect of using a cheap/junk composite encoder, probably leaving tons of cross talk between Y and C or even (most definitely) in-between C.

2 Likes