Dogway's grading shader (slang)

I think grade.slang is broken again.

1 Like

What’s the issue you’re having?

I’m getting some clipping with the latest version (see above), not sure if that’s intended/expected.

What’s your issue?

Getting really weird colors?

I updated today what I consider now a release candidate v1. Please test with this version and if you are sure you have issues open a ticket in the repo so we don’t convert this into an issue report thread lol.

If you do please post before/after screens and explain the steps to reproduce the issue. The only thing being left for now is if we should assume Rec.601 or sRGB for the output of bsnes framebuffer, if @hunterk has any idea it would be much appreciated. I asked byuu as well but he might not respond.

I don’t think bsnes’ gamma ramp feature conforms to anything normal (it’s just a “looks good” sort of thing AFAIK), so it’s probably best to just ignore it for the most part.

2 Likes

Yes, I was going to post a few screenshots to basically explain the same. The test suite is authored in plain sRGB content, I don’t even think it conforms to BT.601.

My question is more towards native color output from snes games. The snes tells to output red (#FF0000), but what red? SDTV is 601 compliant, we need to convert the signal to Rec.709, unless byuu already used Rec.709/sRGB primaries for the red.

Just fails to load altogether. Same with the one released about 30 min ago. If I switch it out with the old 27 KB version, it works just fine. The new one that doesn’t work is 224 KB and the old one that works is 27 KB if that’s important.

GitHub desktop fucked up my commit, since it uses the same button to push and fetch. I had to rebase again a few minutes ago. Otherwise just wait a little please.

Isn’t the display device (TV/monitor) determining the primaries? In my understanding the console/computer just output RGB red and the display device (CRT phosphor / LCD LED) is the determinant which “red” primary is displayed. It would be surprising if byuu would’ve implemented this kind of “shader” conversion as default in the emulation?

2 Likes

I’m talking more on the emulation side. In digital terms what color is red? Is it (0.640, 0.330)? Is it (0.680, 0.320)? When you decide to choose a red to render you need to set your color space. Nowadays with HDTVs the choice would be sRGB but that mangles all the transformations that assume ITU 601 compliant primaries as red. byuu clearly made a choice when selecting a red, I assume he (and all emulator developers) choose sRGB but without him telling who knows.

By the way, just updated with this Rec.709 invert transformation, the shader is working fine on my end, I’m not going to work more on it today but please test, I will be reading.

1 Like

I know for RetroArch (and probably bsnes, too), default output is 8-bit UNORM (https://docs.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-data-conversion). So, 2.2 gamma corrected, I guess /shrug

Years ago, bsnes/higan (can’t remember what it was called at the time) supported 10-bit color (to accommodate a fancy monitor and quadro card he procured somehow lol), so maybe something like A2B10G10R10_UNORM_PACK32, but I don’t think that’s the case for any byuu-ware anymore.

2 Likes

It mostly talks about data types and conversion but I do guess direct3D defaults to sRGB color space for UNORM and overall, it should be written somewhere. One thing I’ve been wondering is if game color data/palettes is stored in gamma space or otherwise linear. If the gamma correction is performed by direct3D it would wrongly assume it should be seen on a 2.2 gamma corrected display, when in this case it should be 2.4 (for CRTs). Therefore I should compensate for that, probably the reason the power function looks so dark and a simple inverse sRGB transformation looks so good.

EDIT: OpenGL now (or since when), supports YUV format conversions (EXT_YUV_target), so some research on the emulator core would be necessary for peace of mind anyway.

This extension adds support for three new YUV related items: first
rendering to YUV images, second sampling from YUV images while keeping the
data in YUV space, third it defines a new built in function that does
conversion from RGB to YUV with controls to choose ITU-R BT.601-7,
ITU-R BT.601-7 Full range (JFIF images), or ITU-R BT.709-5 standard.
2 Likes

Updated to RC4, so I’ll explain what’s been fixed.

Finally got PAL YUV encoding format right so overall colors should be better there.

As expected byuu never answered (suprise) so I went ahead and decided to undo Rec.709. I ran some AB test comparisons for Rec.709->Rec.601 against some methods in avisynth (a reliable source for these kind of things) and got a match using the r709_YCC() function. The papers are never clear whether the calculations should be performed on gamma corrected space, full or limited range and so on, even I could read many contradictions here and there.

Finally reversed the framebuffer embedded sRGB gamma and applied the correct gamma type given the settings. Normally as I could read SMPTE-C gamma was kind of the standard because a simple power function would lead to “infinite slope at zero black” (poynton paper page: 18). Also some small fixes here and there.

As for glass.slang I added yesterday screen flicker, and today screen jitter. Rolling shutter is halfway done, probably I would need to ask a few things at some point.

2 Likes

Update to RC5, if this is fine for you guys I will promote this version to official repo.

Last changes; as it turns out YIQ matrices were in TV range. Apparently the signal path chain is as follows:

On System:

RGB to YIQ -> Range Compression -> Signal Composite Modulation

On CRT:

Signal Demodulation -> (Analogue Colors here ->) Range Expansion -> YIQ to RGB

Therefore grade should go before ntsc artifact shaders. Ideally this should be done in passes, first analogue signal color emulation -> ntsc artifacts -> grade. But I’m reticent to split things into more shaders. (Maybe if I ever decide to make/finish the signal bandwidth shader)

I also adjusted the clipping coeffs, and fixed the range expansion compression function to properly center the chroma plane values given the matrix. Now analogue controls happen in limited range as it should. In this sense I’m gearing towards adjusting color temperature in an analogue fashion by setting the “I/U Shift” setting to -0.04 or -0.08.

I don’t know whether to keep the “grade” name as it evolved into an accurate signal color emulation shader. Later today I will post some screenshots.

3 Likes

3 Likes

Looks great!

Are you recommending that we keep white point at 6500K, now? Are the old presets still good?

2 Likes

I don’t know, I find that for NTSC games lowering “I/Q shift” works quite great for a cooler temperature.

I think it depends on what you feel “more analogue”, I’m still experimenting but I’m quite liking it. I still haven’t run side to side tests to see what IQ Shift corresponds to what white point kelvin value.

2 Likes

I recorded a short video snap of my shader in action.

While grade is a static shader, glass has some nice dynamic effects like screen flicker and screen jitter (subtle here and masked by the rolling shutter).

I mainly wanted to show the rolling shutter shader I have been developing. The hardest 80% is done but I’m not going to continue because lack of coding support plus I have no time to spend 2 months on glsl coding, but if anyone wants to continue from here on he is free to do. I will share it in my repo.

A few things are lacking, a temporal smoother of the average diff, and a sampling window to check if going to one side or the other in the horizontal plane. The effect should be subtle (about 1px offset or less) so it can accept some bias errors.

Watch the video in 4K@60 for better phosphor rendering.

4 Likes

Updated grade with small fixes.

Pow gamma type wasn’t needed so I removed it. Also I was inspecting the dynamic range of game regions, what I observed is that all NTSC ones (USA and Japan) had a white luma value of 239, what means TV levels for luma white. PAL games had a 100% white with 255 (only tested DKC games though). The blacks were pinned at 0 values but that’s something that the function transform takes care of.

Since we mostly play on monitors or HDTVs in RGB mode and full luma range I did the luma expansion according by a factor of (255/239). EDIT: Correction, this is by system, not region, so a new setting is coming.

By the way, I noticed that the luma preservation code in the white point code block was expanding luma, probably causing clipping. So I still need to fix that.

2 Likes

@Nesguy Did you find an anwer to the above?

Does a “properly” tuned shader pass both the grey bars in the bottom right of the SMPTE color bars test and the blue bars in the pluge test at the same time or is it the one or the other?

Currently I either can make the blue bars in the pluge test correct OR the grey bars in the bottom right of the SMPTE color bars test, but not both at the same time.

EDIT: with a correct blue bars in the pluge test, I find the grey bars in the SMPTE test quite bright still. But maybe I’m doing something wrong.

1 Like