Real GBA and DS-Phat colors

Interesting. The input gamma is what the gamma setting on the shader and the LUT shader work, as it does alter the gamma before it does the color correction, which is what the given presets on the wiki states. As for brightness and contrast, somehow it tries to emulate the contrast of the displays to give it a look? Not sure if the given contrast ratio was from the test or something to increase black levels and decrease white levels, but it is interesting. I don’t plan on approaching the same contrast accuracy due to varying degrees of LCD displays and varying levels of contrast ratio. I know both Sameboy and BGB tries to replicate it.

Also, on my GBA preset, the input gamma pretty much ranges from 2.2 and 3.8. The default being around 3.0 when flashed the gamma ramps on the GBA in center light angle when using 240p test suite. The GBA shader preset have very similar gamma as the old one as you demonstrated, when I just tested the preset on Retroarch.

That reminds me your shaders do the darken screen adjustment on the input side. I found that doing it like that changes the colors noticeably the stronger darken screen is. Would not it make sense to change the gamma on the output side or is there a specific reason it’s done like this?

Oh, and before i forget extrems explained how contrast and brightness are calculated.

profi200: The values were calculated using part of this formula:
https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.1886-0-201103-I!!PDF-E.pdf#page=4

Example for https://www.gc-forever.com/wiki/index.php?title=Game_Boy_Interface/Standard_Edition#Game_Boy_Advance
gamma = 4
brightness = (1 / 250) ^ (1 / gamma)
contrast = 1 - brightness

The output gamma affects the primary colors when doing color correction from RGB. It wouldn’t look right, but with input gamma, it affects the gamma before the color correction takes place, which retains gamma corrected color correction to the primary, with gamma 2.2 adjusted.

Merry Christmas!

I got myself a colorimeter and made some measurements. I guess the thread title can now be changed because we have data on old 3DS and IPS New 3DS XL as well. :stuck_out_tongue: I didn’t measure the New 3DS XL bottom LCD because it has a way too warm whitepoint. I plan on doing more measurements as well as measuring my DSi and DSi XL LCDs.

Mentioning my setup just in case i made a mistake. HCFR 3.5.1.4. The colorimeter is a Calibrite Display Plus HL and i made all measurements in the dark under my table and with the second LCD backlight turned off (to prevent the other LCD light from influencing the measurements) because the colorimeter does not sit on the LCD directly (light can enter from the sides). I also made sure colorimeter and LCD are warmed up. This was specially challenging because the 3DS LCD backlight kept drifting downwards even after over 30 minutes to make it stabilize. The New 3DS XL on the other hand stabilized very quickly. I adjusted brightness until the colorimeter read about 80 nits on 100% white for all measurements.

Results:
old 3DS top LCD. Gamma is an accident as well as color temperature. HCFR can only show a single point in the top right corner for the color temperature.

old 3DS bottom LCD. About the same as top but a little bit of a different gamma.

New 3DS XL top LCD (IPS). Much lower delta error rates but still bad in many measurements. The blue channel is different than old 3DS. HCFR also partially can’t show the color temperature but it’s much closer to D65 than o3DS.

Bonus microscope shots of the top LCDs i made years ago. In order o3DS and N3DS XL IPS.

Files:
https://www.dropbox.com/scl/fi/o6dryycdkjlo3rgbow72q/3DS_LCD_measurements.7z?rlkey=a4vfz3ueel8e5nhu5r7x7i99b&st=ovuoter1&dl=1

The code i wrote to to show the test patterns. The overlay from HCFR showed slightly different values than the reference in a few cases. I used the RGB values shown in the overlay.

3 Likes

The 3ds seems to share very similar colorspace the whole DSLite-DSi and GBA-SP 101 have. The only difference is the blue color is much closer to sRGB’s blue color, only a little higher hue and slightly out of gamut of sRGB. The IPS one has the Red color raise more saturation a bit to nearly its fullest of sRGB, only still a bit more orange like the non-IPS one, and somewhat better gamma and color temps, but far from what average IPS displays from the last couple of years has provided. Still an improvement at the least especially the viewing angle. Also can’t wait to see the DSi measurements as well as XLs. I would request the LCD subpixel photo if possible. Thanks for sharing them

I have two AGS-001s. These are second hand so I dunno the history, but these two have screens that look different Here’s a photo with the frontlight off.

The left one looks warmer, the right one colder.

2 Likes

If you shine light from the top of the LCD does one of them look darker than the other? That’s what i observed with my SP’s.

@Pokefan531 I was made aware of a small quirk of how GBA mode on DS works. On DS the LCDs use 6 bits per channel and seems like they bodged it by leaving bit 0 as always zero and the upper bits are from GBA hardware. Mentioning this because the DS (lite) shaders may not be accurate to what it looks like on hardware.

1 Like

Hi @Pokefan531 , I’m the developer for a (3)DS Capture Card Viewer software. I’ve already implemented some of your shaders based on the OAF implementation. You can see the data here: https://github.com/Lorenzooone/cc3dsfs/blob/3bc9425bad768fe6be013a4d06a9e9895712fd56/source/frontend.cpp#L369 Thanks a ton for all your hard work!

I’d like to know, from @pica200 ‘s files, how could I get the values needed for a shader to recreate the colors of the 3DS’ screens? Thanks a ton for any answer!

Semi-related, but I noticed that FFTA has a color-corrected mode for TVs built into the game. Anyone know of other GBA games that had this feature?

I know some games with GameBoy Player support loading different palettes for it. Mother 3, for example, calls this “Gamma Correction” in the debug menus.

1 Like

That’s interesting. Is this similar to the built-in colour palettes in the GBC for select GB games? Or is it a debug feature never used. I’ve been recently playing Mother 3 and tinkering with various shaders to get the best ‘Developer-intended’ look when playing on a TV.

P.S. Thanks for your work on Mother 3 v1.3, dunno who to send this to but the DL from the fobby blog is outdated compared to the one from the github repo, so small chance some players are playing on an outdated patch. (eye drop battle description bug)

There is another that I know of which is Shin Megami Tensei II. Interestingly this also includes a colour mode for the SP as well as TV. It seems to desaturate the reds/oranges and darkens the screen, going from Normal to TV but would be interesting to compare it in detail.

2 Likes

Yeah some screens looks different from screen to screen, on either Sharp or Panasonic brand, model to model of GBA or GBC. They can vary on their white balance from each unit, despite using same model, and same screen’s manufacturer. My GBC and GBA I have around are both made by sharp, and yet I see the GBA being closer to 6500k than GBC or the SP-001 I got from last November.

The gamma itself would look darker once the light shoots from the top. And yeah they may vary gamma from unit to unit, but in most average, the 32-pin Panasonic manufactured displays used in GBA SP-001 and late 2001 onwards of OG GBA model, have around up to 4.0 gamma at its highest when lights shot from the above.

I used the 240p test suite for GBA. The GBA uses 15bit color depth that has all grey swatches be consistently the same RGB value. And when each RGB hits the highest value under GBA test suite, it would use the highest value the screen can output, so nothing is affected by lower color depth, on either DS mode or GBA mode, unless if I need to check in greyscale gamma data. There’s 32 swatches from going black to white under GBA.

No problem. I’m glad I can help out to show off how the shader works, and it turns out to play well under the 3DS virtual console.

I find it interesting to see some games have two colorspace options that targets the OG GBA and the SP-001. I already covered the TV one before, so that should be used when using anything outside the GBA, SP-001, NDS, or GB Micro.

In fact, I had done two weeks so far to update my shader package again, as I just got back to doing colorspace works and include the GBA SP-001 onto the package. Yeah, those Panasonic displays has a different colorspace than ones found by Sharp displays that my GBA and GBC shaders currently uses. While it looks similar, the SP has a bit of less saturation of green but higher luminance, and the red color is slightly warm, but not by much, as it still looks a little cold. Tho it seems like those reflective displays were somehow made to have the red colors to look colder as it’s often shot by warmer light such as the sunlight or fluorescent lights at home that would look warm that is likely below 6500k, with some screen variance on white points to be somewhat warmer, like with Mckimiaklopa’s SP-001 units. My SP-001 is also on the warm side too. But yeah, it is a mess that those displays could not be literally easier to figure out as efficient as backlit displays, so I had to rely on all the tools I use that helped me out over the years. My latest GBA seems to have the red be less pinkish in as of the last fall’s update, which was helped by the portable LED lights that has white lights built in.

A preview on the update, I got rid of the LUTs as they’re not needed, but modified by existing shaders. GBC’s grey ramp is now based on the snes-gamma shader and modify the values. GBA shaders uses a new gamma shader I made just for the GBA oriented shader presets. The NSO-GBC shaders are done, as it uses the modified snes-gamma shader to modify each RGB gamma ramp to match on how it looks from the NSO. All the colorspace shaders, minus the VBA, GBC-dev, and NSO-GBC ones, would have four target your displays colorspace. sRGB, DCI-P3, AdobeRGB, and Rec2020. AdobeRGB is a new addition to a target host display to show off more clue saturation levels than what sRGB or DCI-P3 can show. GBA (from Sharp display ones) and NDS can show full saturation under AdobeRGB colorspace. The PSP, GB Micro, and GBA Panasonic displays would still need Rec2020 displays in the future to see proper blue color from their original display. I added it because of how far a couple of OLED screens can reach. The Ayaneo Air 1S has an OLED display that reaches 99% coverage of both AdobeRGB and DCI-P3 from a notebookcheck website results. More will be explained later on.

1 Like

Hi, @Pokefan531

A few years ago, I started researching ways to replicate DS Lite screen colors. Back then, I managed to get some results but couldn’t properly verify them since I only had uncalibrated TN panels and no colorimeter.

Things have changed a bit: I still don’t own a colorimeter, but I now have an M1 MacBook Pro and some smarphones, which should provide acceptable DeltaE accuracy. This brought me back to the project, where I found this forum thread.

First, congratulations on your work. After reading through many posts, I noticed some possible limitations:

  • It seems there isn’t a full colorspace conversion pipeline (1) (RGB → linear RGB → XYZ → chromatic adaptation → XYZ → linear RGB → RGB). I saw matrix multiplications in the shaders suggesting RGB→XYZ conversion, but without documentation I’m unsure how recent measurements and conversions were handled, especially since tools and methods have changed over time.
  • It looks like the shaders assume a fixed gamma across RGB channels which is very problematic given how unstable gamma curves are on old consoles. In fact, even a small gamma deviation (e.g., 0.15) can cause DeltaE > 3 (5), which is significant when aiming for accuracy. This issue is one of the reasons I paused my work after reading DisplayMate’s article on the DS Lite, which only included the grayscale gamma curve.

Can you clarify these two points? Fixing these issues could significantly improve shader accuracy without requiring manual tweaks.

I also saw that @pica200 shared 3DS and New 3DS XL HCFR data, which I used to create a shader with the colorspace conversion pipeline mentioned above. The 3DS top screen shader came surprisingly close to the DS Lite’s look as you also said. Seeing that result after years was incredibly rewarding. Here are the GLSL shaders (3)(4) if you’d like to try them:

Could you please share the HCFR CHC output files for the consoles you measured? (2) I only saw some screenshots and would love to try them out.

Thanks again


(1) If you want to learn more about colorspaces conversions you can look at the h_ttp://brucelindbloom.com/ website.

(2) If you are interested, I’m also developing a display measurement guideline so that everyone can follow and be aligned on the tools, the methodologies and what data needs to be measured. You can find it here: h_ttps://github.com/Brankale/Nintendo-DS-Lite-colorspace/blob/main/measurements/README.md. Be aware that the file directory can change, so if the link is broken just search in the github project.

(3) The GLSL shaders are only targeting sRGB display. I also tried DisplayP3 but the result was a washed out and greenish image. I suspect the framebuffer where the shader writes data into, is interpreted as sRGB causing color misinterpretation.

(4) In the GLSL shader there’s also a commented line that, if enabled, visualizes out-of-gamut colors.

(5) NDS Lite colorspace gamma with 0.15 delta:

  • h_ttps://github.com/Brankale/Nintendo-DS-Lite-colorspace/blob/main/gamma%20analysis/0.15%20gamma%20diff/deltaE_summary.png
  • h_ttps://github.com/Brankale/Nintendo-DS-Lite-colorspace/blob/main/gamma%20analysis/0.15%20gamma%20diff/deltaE_all_colors.png
1 Like

@Brankale Thanks for telling me about all of this. I’m glad to see you work with color matrix with proper conversions shown on your github. Now to answer your questions.

It seems there isn’t a full colorspace conversion pipeline (1) (RGB → linear RGB → XYZ → chromatic adaptation → XYZ → linear RGB → RGB). I saw matrix multiplications in the shaders suggesting RGB→XYZ conversion, but without documentation I’m unsure how recent measurements and conversions were handled, especially since tools and methods have changed over time.

Yeah that was long before any color shaders that relies on color matrix and chromatic adaptions has existed, such as Colorimetry, Grade, and Chromaticity from the “misc” folder inside the shader folders. So we relied on just gamma corrected to linear, handling color matrix manually by modifying RGB individually.

But as I recently got back and have multiple host colorspace such as DCI-P3, AdobeRGB, and Rec2020, I was thinking of switching from color-mangler to something like Colorimetry as it contains multiple targeted specified colorspaces. I did play around a bit with Colorimetry shader and added gamma correction to have linear behavior on the color matrix as it doesn’t have one originally. I did modify its XYZ for its host colorspace just to copy the given colors to my current shaders. I can add multiple host colorspace and targeted colorspace to the shader, as well as white balance.

But yeah, with the color mangler, I used it to give a much better understanding how the shaders work with modifying RGB channels as well as easier read to port it to their projects, being mGBA, PPSSPP, and even Gameboy Interface. It’s been ported multiple times, seeing a same similar code that I can easily adjust for just one colorspace for one standard.

It looks like the shaders assume a fixed gamma across RGB channels which is very problematic given how unstable gamma curves are on old consoles. In fact, even a small gamma deviation (e.g., 0.15) can cause DeltaE > 3 (5) , which is significant when aiming for accuracy. This issue is one of the reasons I paused my work after reading DisplayMate’s article on the DS Lite, which only included the grayscale gamma curve.

I used more of an average outside of GBC as I see the average of gamma of the display that is suitable for the viewer. Much of them seem to follow closely to Pure Power Gamma curve as I do now work with a display to Gamma 2.2 since KDE Wayland only color corrects to sRGB with Gamma 2.2 curve. I know a lot of those old TN displays have colder greyscales than how the shaders gamma handles it. It was why I had the handheld presets use the LUT shader to load up its greyscale gamma curves that changes its color temperature. I noticed the DS-Lite has colder greyscale than GBA-SP-101. Even the PSP has a really cold greyscales. But yeah, I did have the LUTs for my current version to contain the cold ones for each system, although made under sRGB curve, which I plan to change to just shader based gamma correction with colder greyscales. Also the reason I didn’t have the generic RGB gamma was the fact it mostly covers just the middle values rather than spreading it out to most of the greyscale. By the looks at your code, it seems to do 9 greyscales between black and white, which can help out. The current shader I have just specifies the gamma for the shader ports to use, as well as the fact the color-mangler doesn’t have RGB gamma control.

As for GBC, it uses its own abnormal gamma curve. I used my ColorMunki Photo with the SpotRead app to just scan luminance the screen while swapping the greyscale swatches from 240p test suite. I scanned all 32 swatches to produce a much more accurate as to how my GBC displays its own gamma to provide constant details. It also has its colder temps on the greyscale too, which I plan to add in later on.

Could you please share the HCFR CHC output files for the consoles you measured?

Sure. Once I get on, I’ll be sharing the data I got for GBA-SP-101, NDS Phat top and bottom, DS-Lite top and bottom, GB Micro, and the PSP 1000. As for GBC, GBA, and GBA-SP-001, they’re pretty much eyeballed on the colorspace with bunch of tools to use, and gamma seems closely identical to Pure Power Gamma, except just slightly darker on very dark swatches only. I did scan out the gamma, but I had to stabilize them in GIMP to see the best results since the colormunki photo had to scan at the very dark that has a slight noise variation to very dark luminance, and same with GBC. So I only have CHC data for any screens covered here that are emitted rather than refletive. As for the Switch OLED, it already has its HCFR data shown from a video I shared here last year or two.

So yeah, I see your code being more promising to have more options to target colorspace without having a lot of work to manually put in color numbers for each RGB for any four hosts colorspace.

2 Likes

Here is the HCFR data that I sampled for the aforementioned handheld consoles from sampling with Colormunki Photo.

https://mega.nz/file/nVxykDLQ#GQNsFMV9yCVhIn3qI4XzpOika3mU6hTDzXJ6zrLF8ys

Also to bring up, I decided to load up gamma related shaders as a separate pass before it color corrects. Not only because of my lack of knowledge of coding shaders from scratch, but also needed to have the gamma pass set before any LCD shaders get applied, as I describe a couple of replies ago on how the LCD shaders should work when using the color correction. Otherwise, the LCD shaders would be less faithful to where a bright red color for example wouldn’t look bright red on the LCD if the color correction gets applied before the LCD shader. Having it applied after would make it look more faithful to the screen, as the subpixels are already using different color gamut itself. So pretty much, gamma shader pass -> LCD shader pass -> color correction pass.

Another thing to add to the current shaders is I lowered the luminance to show off the actual yellow colors since the red parts are clipped. The fact the blue color has to be subtracted because the blue color is out of gamut for sRGB for example would need the white color to be balanced, which means the red color from red and green channels adds up beyond 1.0 or 255, and then the blue color subtracts it back to 1.0. The yellow already has high red colors and it looks less warm and less accurate to the screen if it’s clipped.

1 Like

@Pokefan531 Thanks a lot for the quick response.

I just want to clarify this a little bit:

By the looks at your code, it seems to do 9 greyscales between black and white

In my shader code and in general for my colorspace conversions, I use/need the exact gamma curve values for each R, G and B channels. Using only the greyscale gamma curve is not enough and very far from getting accurate results.

So at the end, you need to measure:

  • at least 9 patches for every channel (9*3 = 27 patches) between 10%-90% (10% increment).
  • 4 patches for every channel near black (4*3 = 12 patches) between 1%-4% (1% increment) (in the shader code I currently use only 4% to make calculations easier and also because there’s not a noticeable difference)
  • 4 patches for every channel near white (4*3 = 12 patches) between 96%-99% (1% increment) (in the shader code I use only 96% since deltaE error is very low on high luminance values)

These are only general rules to get a very good approximation without wasting too much time but obviously if you want to reach the highest level of accuracy you can also measure the exact gamma for every possible color of every channel but, keep in mind the screen bit depth to avoid unnecessary measurements. For example, DS Lite has a bit depth of 6 bits which means 64 color patches for every channel (64*3 = 192 color patches).

Also in the “measurement” readme I wrote, you can find all the data needed by the shaders and colorspace conversions: https://github.com/Brankale/Nintendo-DS-Lite-colorspace/tree/main/measurements.

I’m also trying to make a measurement report template to give more context on the measurements. This is one example https://github.com/Brankale/Nintendo-DS-Lite-colorspace/blob/main/measurements/New%203DS%20XL/20241221_top_pica200/REPORT.md. If you want you can follow this one.


@pica200 I’d like to take this opportunity to ask if you could provide us with the HCFR CHC files for both the DSi and DSi XL, since you mentioned them in a previous post. This way, we can collect data for almost all consoles in the NDS family.

Thanks again

@Pokefan531 I think I now understand what did you meant by

By the looks at your code, it seems to do 9 greyscales between black and white

If you measure the greyscale you already get the gamma of Red, Green and Blue because grey already has all of them. I don’t know how I missed that.

This also invalidates partially what I said in the previous message. There’s no need to measure all those color patches. You just need to measure 9 patches as you said (10-90%) and a few other patches for near black and near white. So for example for DS Lite they are only 64 patches if you want the max accuracy and not 192.

From the greyscale patches, I was curious on how accurate the patches would be because of the limited color depth the hardware has, GBA being 5 bit, and DS being 6 bit from your research. Tho I thought it has 8 bit when I used moonshell long time ago, but must be dithered. I get more promising results in GBA’s 240p test suite than when tried from moonshell. That’s unless if there is a similar homebrew made for NDS hardware that uses more color for better color sampling.

Yeah I get that only 9 patches is a solid choice to save time and such. I do worry on the accuracy on the gamma for GBA and NDS because of limited color depth where you can’t exactly match the color RGB value from the screen HCFR expects for each patches. It was why I did 32 patches for those screens to collect full data as none of the homebrew could dither through currently. As well as the issue also applies to black and white four patches since the GBA for example have a limited color depth that makes each BW patches have bigger luminance difference between each other, even for just one notch difference, compared to other displays that allows full 8bit color display where there’s more subtle difference between patches on luminance.

I can successfully do the PSP for 9 patches and 4 for black and white since it does allow 8bit mode for RGB and uses it for its interface when I load pictures from it. The GBA and NDS with more limited depth options is a different story. 10% grey for example expects 26 RGB to be show from the display that HCFR gives out, but GBA would only have 24 or 31 RGB greys due to limited depth, which may affect gamma results. As for the near black or near white, it would be 0 RGB, then 8 RGB, or 255 RGB, then 247 RGB, respectively. It was why I only put 32 black to white patches to the data as I wanted to preserve the gamma results without any mismatch to my concerns.

As for CHC data for DSi family, I sadly don’t have them as I only have the Phat and Lite models when I mentioned that I would share them. As for the instructional measurement, I do have Colormunki Display and Colormunki Photo, a Colorimeter and Spectrometer, respectively. I used Photo for Display’s correction for just my monitor when calibrating for better whitepoints. I wasn’t sure if the Photo is less accurate when reading your report files, but I did get very similar points from how my Display samples the colors. The Photo was able to read black colors with hardly any struggles because of its TN panels having less contrast where the black color isn’t too dark on full brightness and just around 600:1 from DS Lite.

Yeah I did my best to explain all this just to help out, I do apologize if there were few things that didn’t make sense, but I try to understand all of them as best as I can. I was happy to see your glsl shaders on the repository for each screen. My fun fact, I measure my PC monitor with higher than 10 patches on HCFR, like 20, just to check the gamma curve for the dark areas to say it follows closely to pure power gamma, as well as measuring near black and white levels to see more deeper analysis.