A new little shader i did (glsl)

A good NTSC phase advance per pixel table. I must correct some values on my ntsc shaders heh.

5 Likes
6 Likes

Thanks @DariusG! Looks like I have a new shader stack to build!

1 Like

Do some testing and tell me what you think, that’s a pretty accurate NES/SNES composite there AFAIK.

1 Like

Heym thank you again for your work.

How do i load them ?

Do I have to update shaders?

Do I load each individual shader to test ? or is there some specific preset that load these shaders on that link?

Thank you

Yes maybe tomorrow update slang shaders. Preset is on crt folder and it’s called crt-consumer-1w-ntsc

I think have loaded your content properly.

It looks outstanding and once again, thank you a lot for your work.

Little suggestion:

Is there some way to bring rainbow FIX for BORDERS = FULL ?

Apparently, your rainbow was intended to work WITHOUT borders.

The thing is that on Genesis console, full borders is the original experience. So if its enabled on GPGX or BlastEm (by default) it will not show up properly.

Amazing work. Picture one is NO borders. Second its enabled.

1 Like

Probably would need to change that 170.666 color cycles to how many on full border (probably something like 185.0) but then it will be non-universal and genesis plus gx specific.

1 Like

Full borders should really have been more of an exceptional experience, as those borders would be most often hidden in the overscan area, unless you were a power user that adjusted their TV for that (or for people who used more easily adjusted monitors). You couldn’t even be certain to see the full picture with no borders. I agree of course that NTSC shaders should work if possible for any borders config.

2 Likes

That’s just a matter of driving the “subcarrier phase” with ntsc clock (3.57mhz) / emulated system clock (which is what’s happening in reality) for it to work. Then you should make it a 10 heads Hydra, with clocks for Snes low, high, genesis low/high, ps1 256/320 and on and on.

Now it relies on TextureSize.x which changes if you enable borders and breaks the relationship between ntsc and clock that suggests no borders.

2 Likes

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