gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > 18 bit LCDs

#159454 - sverx - Tue Jul 01, 2008 1:35 pm

Hi there
I was just curious, I've read GBATek specs and this topic, they both say that the NDS LCDs are 18 bpp...

Does that mean that blending two backgrounds with two different palettes (each 15bpp) the result will be an image with a 18bpp palette? (I didn't want to say an 18 bpp image because it's not so, you can't set the value for each pixel...)

Ideas? Opinions? Code? ;)

Ciao :)

#159455 - elhobbs - Tue Jul 01, 2008 2:17 pm

I am not sure what type of effect you would be able to achieve with this in mind. however, it does produce slightly smoother blending for multiple backgrounds in 2d and for alpha blending and hardware lights in 3d.

#159458 - silent_code - Tue Jul 01, 2008 3:44 pm

A lot of cheap and "fast" (low response time) consumer level TFT displays (PC and TV) are 18bit, too. So?
It's just the display pannels and color mapping, colors are still handled in whatever bit depth used by the graphics hardware, no big deal.

Most people don't even notice it until they start to "make art" and realize the color range seems odd. Or they play UnrealEngine3 games (it happens to be a lot more visible in those games, maybe due to the engine's gamma correction or whatever) and see the ugly dithering the displays produce in dark areas. :^D

That's one factor of why some displays cost a lot more than others: they simply have true 30bit or 32bit (or at least very good 24bit) panels.

IIrc, the NDS' color ranges are like this: (15 + 1)bit colors, 24bit 3D computations (converted back to 16bit color afterwards!) and 18bit displays.
You really don't have any control over the color depth of the displays and I guess, it's not even taken into account when blending occurs... the hardware then simply mapps 15bit (yes, it's 15 this time!) to 18bit colors.

Although I don't have in depth knowledge to assure you that it's just like that on the NDS, I know that's how things work in other devices.

#159465 - Cydrak - Tue Jul 01, 2008 5:21 pm

Nah. Unless my eyes deceive, it really does render 18bpp. The shaded polys are too smooth, and there is more banding if you capture and redisplay them. In 2D, an 8/8 blend with black or white shows up to 32 levels, even though the range is halved.

Most interesting is ordinary white; if I turn on blending I can see it's a little "shy"--true saturated white is a notch brighter. I guess it just doubles the 3*5 bits. (There is no kink in the midrange, as one gets by rounding, either.)

What could you do with this? The smallest blend is 1/16, and blending *does* round--to 5 levels. Values 4-11 (of 31) give the second darkest. So, maybe if you had a 4bpp layer with RGBs of 0/8, you can selectively "add 1" to each channel. Then you would have your low 3bpp, and 248 colors left for the bitmap. (If you use a palette there at all.)

That wouldn't work for textures, of course, but one could imagine overblending 50% with full primaries instead.

#159472 - silent_code - Tue Jul 01, 2008 6:58 pm

Perception is a ... you know what: very subjective matter. ;^)

A (at best) remotely related example:

I know of two guys who made their semester audio project together and although they had to make separate final productions (everything else during preproduction would be shared), they ran out of time and submitted the exact same thing to the same teacher.
One got X3%, the other got X5% (X is > 5, both passed), but you wouldn't believe how much the "cathegory grades" for each aspect of the production differed! Although it was the exact same thing!

Knowing that, the grades seemed so random - all due to "warped" perception and uncontious subjectivity. Take it from someone who know what "warped" perception actually look, smells, feels, tastes and sounds like. ;^)


But back on topic: By that I didn't want to say you misinterpret things - I can't judge that.

Right now, I'm very interested in the facts, so:

For example: What format are the render buffer lines in? 18bit? 16bit? 24bit? If it's 16bit, then all the 18bit magic happens in the color mapping (16bit -> 18bit). If it's 18bit... that would be odd, so let's assume 24bit instead: then the 24bit 3D rendering would be mapped directly to 18bit.

It's true that captured images look a little dull and less colorful (both due to less gradients) compared to "live" renderes. That would imply, that the conversion is indeed 24bit -> 18bit from render buffer to display, and not 24bit -> 16bit -> 18bit (which wouldn't be that unreasonable at all and that's how the captured images get displayed!)

But even that doesn't give you any controll over the color range... And blending is min((0..16 + 0..16) / 2), 16).

... Blending is a very specific topic and my experience with capturing tells me, that everything is getting rounded down and clamped, so choose your values wisely to make it fit your image, not ruin it. ;^)

Well, does anyone have any other ideas?

#159501 - Cydrak - Wed Jul 02, 2008 2:32 am

Hmm... I got too curious. Mind the random photos! Had to grab something...

18 bpp display demo

I think this would look awesome in paint apps, where the color banding is actually really obvious to me. Or dark/toony cutscene artwork, like Zelda has or something. Photos are more of a mixed bag.

Either way, lookit that gradient. 64 greyshades, mmm... @_@

#159533 - fluff - Wed Jul 02, 2008 12:24 pm

Cool stuff! :) That's quite a difference in appearance...

I haven't used it myself, but isn't there a comic book viewer of some sort for the ds? Seems like that too could make good use of this.

#159537 - silent_code - Wed Jul 02, 2008 1:12 pm

This is indeed a very interesting approach. You should write about it and explaint it a little bit more in depth. :^)

Do you think blending is done in 24bit?

#159555 - sverx - Wed Jul 02, 2008 4:58 pm

Cydrak wrote:18 bpp display demo
You did it??? That's amazing... I'm going to test it on the hardware as soon as possible, it doesn't work with the emulator (at least with no$gba -at least it seems to me-)

Anyway what you place in the palette of the second background it's unclear to me... did you build 8 color with the different possible combinations of the 3 least significant bit and you 'add' (blend) it to the other image? So the 1st image is exactly the same (16/16) and the other one is what was 'lost' in the 18->15 bit transformation?

I've got to understand how it works, I was going to write a test myself but using 2 blended 'full' (256-colors) palettes, blending together the 8/16 of both... but I think you've got a smarter idea :)

Ciao :)

#159594 - Cydrak - Wed Jul 02, 2008 8:46 pm

sverx wrote:You did it??? That's amazing... I'm going to test it on the hardware as soon as possible, it doesn't work with the emulator (at least with no$gba -at least it seems to me-)
Ah yeah, emulators will probably round it down to get 15bpp again. Even NO$GBA does that for some reason.
sverx wrote:did you build 8 color with the different possible combinations of the 3 least significant bit and you 'add' (blend) it to the other image? So the 1st image is exactly the same (16/16) and the other one is what was 'lost' in the 18->15 bit transformation?
Yes, exactly!
silent_code wrote:Do you think blending is done in 24bit?
Not sure, really. Although it's fun to speculate about the hardware, I'm mainly interested in what I can see. Unfortunately it isn't possible to run an 18-bit capture, so I've just been counting greyshades! (On DSLites, the darkest levels are very distinct.)

I'm not certain but I expect it's as simple as possible: (((5bit channel<<1) * (factor 0..16)) + 8) >> 4, with the results summed and clamped. I'm fairly sure the rounding (+8) is in there, due to "centered" spacing of the gradient with low blend factors. By blending various colors at 1/16 it may be possible to test, e.g., whether the downshift occurs before or after the sum.
silent_code wrote:This is indeed a very interesting approach. You should write about it and explaint it a little bit more in depth. :^)
Thanks. :) There really isn't much to explain. Any method of showing two layers should work; all I think is required is the 1A + 1/16B blend.

In my program the normal layer is "A". It has the usual 15 bit pixels. I just used a bitmap for clarity and generality. If you have preconverted artwork, extended palettes should work--that's 4096 "18 bit" colors at half the pixel size. For dark scenes, I'm sure this would still be an improvement.

"B" is the special layer, and the only reason I got fancy is to use the compact 4bpp tilemaps. Of that, 1bpp is ignored, wasting 6K or so. The other 3bpp are the low "RGB" bits, which index 8 matching colors in BG_PALETTE.

From there the process looks like this (*3 channels, for RGB):
1) "A" supplies 5 bit data (range 0..31).
2) Hardware shifts left to get 6 bits (range is now 0..62).
3) Hardware multiplies by 16/16 so "A" is unchanged.
4) "B" supplies 5 bit values of 0 and 8.
5) Hardware shifts these left: now 0 and 16.
6) Hardware multiplies by 1/16: now 0 and 1.
7) Summing combines the two.

Another way to look at it:
- Input: A (5 bit channel), 8*B (low bit)
- Conversion: 2*A * 16/16 + 2*(8*B) * 1/16
- Output: 2*A + B (6 bits)

Btw, I observed this to give the full 64 values. RGB5(31,31,31) seems to display as RGB6(62,62,62), because it takes one more "shade" to saturate the blend.

#159598 - silent_code - Wed Jul 02, 2008 9:43 pm

This is very impressive when seen on hardware!

Thank you! :^D

I guess we can savely assume blending happens in super 15bit color range.

EDIT: gbatek states that the 3D rendered image is in 18bit! (Then it was just lighting or rendering, that was calculated in 24bit... something *was* 24bit!)
Fog is a blending post processing effect and because all blending is likely to happen in one place, it is 18bit.

Lesson learned. :^) This is pure fun to me. :^D

And thanks for the info!

I know I could read the sources, but I am rather busy with my own stuff, so could you write (just the general appreach) about how you converted the 24bit image to a (15 + 3)bit one? Unless I haven't overlooked it, you didn't mention it. :^)

#159611 - Cydrak - Thu Jul 03, 2008 12:46 am

silent_code wrote:and because all blending is likely to happen in one place, it is 18bit.
You would think so, but I doubt it! There are at least three types of blending I can think of: BLEND_CR, POLY_ALPHA and fog. I posted a 3D blending example awhile back. The details are weird, but when BG shows through polys... then 3D RGB will be correct, but alpha may not be.
silent_code wrote:so could you write (just the general appreach) about how you converted the 24bit image to a (15 + 3)bit one? Unless I haven't overlooked it, you didn't mention it. :^)
For each channel I drop bits 0 and 1. Bit 2 goes on the 3bpp layer, and bits 3-7 go with the 15bpp as usual. Is that what you mean?

Code: Select all

// Palette for the 3bpp layer &#40;in the source this is just written out&#41;
for&#40;rgb = 0; rgb < 16; rgb++&#41;
    pal3&#91;rgb&#93; = RGB15&#40; 8*&#40;rgb>>2 & 1&#41;, 8*&#40;rgb>>1 & 1&#41;, 8*&#40;rgb & 1&#41; &#41;;

foreach&#40;pixel24&#41; &#123;
  int r = pixel24     & 0xff;  // depends on your pixel format!
  int g = pixel24>> 8 & 0xff;
  int b = pixel24>>16 & 0xff;
  
  // This is basically x * 64/256 or x>>2.
  // I considered doing a rounded x * 63/255, but it's not a
  // clean 2^n, so results would prolly be less uniform.
  
  int pixel15 = 0x8000 | RGB15&#40;r>>3, g>>3, b>>3&#41;;
  int pixel3  = 8 | &#40;r & 4&#41; | &#40;g>>1 & 2&#41; | &#40;b>>2 & 1&#41;;
  
  // Now toss pixel15 into a palette or a bitmap,
  // and pixel3 into a tile &#40;of course, you'll need a map too&#41;.
&#125;
As for layers, I have 16bpp + 4bpp, but that's not the only option. I used a pair of 8bpp for the gradient test--a waste, but it works just fine.

I think you could even pull off affine mode, even if it's 8bpp-only. Fill in a pair of extended palettes, like I did with the smaller one above... but use low/high nibbles of the index. That should let you pack two 4bpp tiles together (so effectively the palette# becomes part of your tile#). Sadly not my idea--NES Elite makes a good example.
silent_code wrote:Lesson learned. :^) This is pure fun to me. :^D
Agreed, the DS is a blast to work with! It's also been a serious learning experience, having to think, devise experiments, and work things out when you can't just barge in with a debugger... (Yup, I waited too long--no NO$GBA for me. :-( )

#159635 - sverx - Thu Jul 03, 2008 9:24 am

Cydrak wrote:RGB5(31,31,31) seems to display as RGB6(62,62,62), because it takes one more "shade" to saturate the blend.
mmm... that means that everywhere when we display a pixel that has a RGB5(31,31,31) color the display isn't using the brightest white it can display but the last (the brightest) gray 'before' the white? Weird! ;)

I gave a look to your code and it's really self explaining, so now we just need to find a name for that mode and spread the knowledge :) (For instance I guess the image viewers/video players applications will have a 'plus' using that mode... I've seen the difference in your image named "iridescent" and it's almost incredible... :) )

Ciao :)

#159637 - tepples - Thu Jul 03, 2008 11:54 am

It's too bad Colors! fizzled out.

Could we simulate 7 bits per channel by combining this 6-bit blending mode with flickering?

#159642 - silent_code - Thu Jul 03, 2008 2:29 pm

Well, yes, that was what I wanted to know. Thank you! :^D

Now, for another question: For "synthetic" images and illustrations, it's simply AMAZING in terms of quality gain! But with photos, there seems to be no real advantage of using the technique. At least I couldn't see any increase in image quality on the NDSp. :^(

So, the question is: Is it worth it? Do video players really need it? Will the increased color depth affect anything? We are talking about highly compressed video streams, that's not exactly illustrations with a lot of gradients (which this technique improves "over the top" - at least! ;^D ), but ever changing (at around 15 hz) blocks of very mostly simmilar colors.

I don't have much experience (if any, really) with video stream coding, but I think I got the concept... So, I'd like to read, what more experienced people have to write about it.

Well, yet another question: Can you think about a possible technique (build on top of this one - which I would describe as "Dual Layer 18bit Blending" [DL18bB] ;^p) to improve gradients in 3D scenes? Obviously there are some comlications, e.g. processing a lot of date (the whole image, which would be captured, thus 15bit anyway... I didn't have the time to think a lot about this. ;^)
I guess there's just capture blending to make the 3D scene shiny and distract the eye from the horrible color bending. ;^D

#159643 - sverx - Thu Jul 03, 2008 2:29 pm

tepples wrote:
Could we simulate 7 bits per channel by combining this 6-bit blending mode with flickering?


If you mean display one 18bpp image every two frames and another 18bpp image (with little differences from the 1st) the other frame... well, theoretically it's possible, IMHO. But I think a little flicker will be visible and maybe it will be annoying... :|

#177833 - sverx - Tue Mar 26, 2013 10:12 am

Sorry for reviving this very old topic... the matter is that I exploited this a little more and the results are quite impressive (but you've got to see it on hardware to believe it)

details here: http://adshomebrewersdiary.blogspot.com/2013/03/one-hundred-twenty-seven-shades-of-grey.html

... I hope you like it :)
_________________
libXM7|NDS programming tutorial (Italiano)|Waimanu DS / GBA|A DS Homebrewer's Diary