30
\$\begingroup\$

I noticed that in very soft gradients, the 24-Bit colordepth is not enough as you can see the transitions of the color. This pops out the most in dark scenes or night skies.

Why doesn't anybody change the colordepth to two bytes per channel? I know that would be alot of work and a lot of hardware would have to be repalced, but I find it a bit annoying. I really don't think that the technology of the hardware isn't mature enough.

So why is no one doing that?

Here's a picture of "The War Z" where you can see what I mean:

The War Z color transitions

\$\endgroup\$
3
  • 12
    \$\begingroup\$ Your image is in JPEG format, that too can produce artifacts. Can you present an example in lossless format? \$\endgroup\$ Aug 21, 2013 at 11:44
  • \$\begingroup\$ Are you kidding me? You complain about bit depth but you upload a JPEG file? \$\endgroup\$
    – Tara
    May 3, 2015 at 17:15
  • 1
    \$\begingroup\$ Exactly. No need for a lossless format when JPG is greatly demonstrating what I mean. BTW: It's not the compression which caused this effect. Save your resources man ... \$\endgroup\$
    – RenX
    Jul 1, 2015 at 20:21

5 Answers 5

19
\$\begingroup\$

You more or less said it yourself: 'I know, that would be a lot of work and a lot of hardware would have to be replaced.' While the graphics-hardware end of things would actually be relatively straightforward (if expensive - doubling the size of all textures and frame buffers is far from trivial), the 'ecosystem' for higher color-depth imagery simply isn't in place to the kind of extent that makes this a worthwhile expenditure on anyone's behalf, as no LCD manufacturers are focusing on trying to get up to 16 bits per pixel (though there have been some experiments at 10BPP, which conveniently still fits an RGB signal into a 32-bit channel).

In short, it's simply too much work for what most people consider yet to be too little gain. It may well be 'a bit annoying', but that annoyance level is so slim that other improvements to image quality have been taking priority.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Although not directly accessible to end users some high end 27/30" monitors targeted at image/video professionals are 14 bits internally/10 externally and use the extra 4 bits to store a look up table to assist in calibrating the colors on the display. \$\endgroup\$ Aug 20, 2013 at 20:38
  • \$\begingroup\$ @DanNeely: Any "end user" can have one for a couple thousand US dollars.They also need a pro level graphics card, like a Quadro. Considering what some people pay for their TV and sound system this isn't bad. \$\endgroup\$
    – Zan Lynx
    Aug 20, 2013 at 21:29
  • \$\begingroup\$ @ZanLynx I used the phrase targeted at pros as opposed to only for pros deliberately. Anyone can buy the full stack; but prices are so high and benefits so rare that very few people do. ex only 1.17% of Steam users have 2560 displays. And the monitor is the only part of the needed stack that a power user is likely to end up getting incidentally because some (all?) of the 2011 model year brand name 2560 displays from mainstream vendors included 10/14bit color; and the cheaper Korean imports weren't widely available for a while afterwards. Quadro/etc cards offer nothing to gamers vs standard. \$\endgroup\$ Aug 20, 2013 at 22:21
  • 1
    \$\begingroup\$ Is it possible that the such banding is actually a textual optimisation to reduce the amount of work rendering the sky? When I create a 24bit gradient in GIMP it does not look like that. See static.inky.ws/image/4306/gradient.png for a 24bit gradient. \$\endgroup\$
    – user34388
    Aug 20, 2013 at 23:16
  • 2
    \$\begingroup\$ @ldrumm no, not really, you really took advantage of the most extreme range and enabled dithering in gimp, take a look at this example with dithering (slight banding visible) and here without dithering. The problem is that you can't just universally post-process dithering into textures and most textures aren't created with by using gradients.If they're hand-painted and have some form of large area with a gradient between 2 rather similar colors then there will be banding \$\endgroup\$
    – PeterT
    Aug 21, 2013 at 2:53
43
\$\begingroup\$

Yep, you're not the first person to notice this. :) With today's high contrast ratios, 8 bits per component is not enough to make a smooth gradient without visible banding - unless dithering is used.

Using more than 8 bits per channel on a display is called "deep color" by display manufacturers. It isn't very widespread because of a chicken-and-egg problem. A deep color display is useless without a video card that can output deep color, and a game engine that supports rendering to deep color. Likewise, there is no point in a game engine or a video card that supports deep color without the display. So there is not much incentive for hardware manufacturers and game developers to add support for this technology, as from either end, there is no market to justify the cost of development.


Also, there are other ways to fix banding due to the limited 8-bit precision. As I mentioned earlier, game engines can use dithering to hide the banding.


(Picture of a cat with a 256-color palette, without and with dithering. Created by Wikipedia user Wapcaplet, used under the CC-By-SA 3.0 license.)

Adding a slight dither of ±0.5/255 before writing out the pixel value to the framebuffer is extremely effective at hiding banding on smooth gradients, and essentially unnoticeable. If you're in an HDR engine, you do this during the tonemapping stage.


Finally, as others have noted, texture compression can be a bigger source of banding-like artifacts in the image than the 8-bit precision is. This may be what's going on with the sky in that picture, although it's difficult to tell - it's got so much JPEG compression on it that any artifacts due to DXT compression are pretty much swamped.

\$\endgroup\$
4
  • \$\begingroup\$ +1 - an excellent answer, and I'd completely missed the likelihood that the banding had other causes. \$\endgroup\$ Aug 20, 2013 at 21:40
  • 1
    \$\begingroup\$ +1 for noticing that the file is a jpeg. A lossless example by the OP would prevent poor judgement due to noise in the data. \$\endgroup\$
    – user34388
    Aug 20, 2013 at 23:13
  • \$\begingroup\$ @ldrumm Also a game/engine that isn't terrible... \$\endgroup\$ Aug 21, 2013 at 1:47
  • \$\begingroup\$ I added pictures to emphasize the difference dithering can make. Feel free to revert if you don't like it :) \$\endgroup\$ Aug 21, 2013 at 15:07
13
\$\begingroup\$

It's also worth noting that many LCD panels aren't even 8 bits per channel. The cheaper ones tend to use less bits and use various tricks to try to hide it. For example they might switch rapidly between two adjacent colours to represent the one in between. http://www.anandtech.com/show/1557/3

There's some details on how DXGI supports 10-bits per channel and brighter than white colours at http://msdn.microsoft.com/en-us/library/windows/desktop/jj635732%28v=vs.85%29.aspx

D3D has also supported more than 8-bits per channel for years. There's nothing stopping a developer doing some dithering down from 16-bits per channel to 8-bits if they think it's a good idea.

Of course that won't help so much if the source data (texture, etc) is only 8-bit (or more likely DXT1, which is effectively 5-6-5 bits per channel). I believe that's what's up with the sky in that screenshot (an 8-bpp gaussian blur makes it much smoother for me) but it's hard to be certain.

\$\endgroup\$
10
\$\begingroup\$

Steven Stadnicki's answer is correct -- games rarely use higher precision textures because it requires too much texture memory, and consequently too much memory bandwidth when sampling the texture in a pixel shader. However, there are solutions that don't require big textures. (I would post this as a comment, but it's too long.)

Homeworld solves this problem by encoding the sky image as vertex gradients. This technique works great for large, low-frequency images (i.e., smooth gradients) -- like skies -- where the texture covers a huge number of in-game pixels.

Another possible solution is to apply histogram normalization to your sky image. If the texture data lies within a narrow value range, like a dark night sky, most of the bits in each color channel are carrying no useful data. Instead, do this:

  • Author the original texture in a 16-bit format, like a 16-bit TIFF.
  • When you prepare your textures for the game engine, find the darkest pixel present in the image and keep track of this as an offset. Let's say this pixel value is 0.1 in a possible range of 0-1.
  • Next, find the brightest pixel and subtract the darkest pixel to get the range of values in the image. So, if the brightest pixel is still pretty dark -- say 0.35 -- the range is only 0.35 - 0.1 = 0.25. Only 25% of the value range is present in the image.
  • Generate your DXT/BC-compressed in-game texture. Subtract the darkest value from every pixel, and multiply to use the entire color range. In the example calculation we subtract our dark value of 0.1 and, because only 25% of the available value range is present, we multiply every pixel value by 4x to create the in-game texture. Make sure to do all this before you quantize your 16-bit source image down to the 8bpp input to the DXT compressor. The output image will now utilize the entire range of values supported by the in-game format. We are allocating all our bits to represent the values actually present in the image.
  • Store the dark value offset (0.1) and range (0.25) in metadata somewhere. Pass these as inputs to your pixel shader.
  • In pixel shader code, sample your shifted, expanded texture, convert it to a float value and then do a multiply/add to restore the original color value. In other words, multiply by 0.25 and add 0.1 to restore the value stored in the source image.

Make sure the shader code is gamma correct. If you do math (lighting & post-processing) on texture samples that are not converted from sRGB color space to linear space, you will see banding artifacts like the one you describe. Gamma correction was created to help alleviate this kind of problem by allocating more bits to dark values where your eyes are more sensitive to value changes. But you can easily break things if you don't account for gamma correction when calculating, for example, lighting, exposure, or post-processing FX. The Gamma FAQ is helpful.

\$\endgroup\$
1
\$\begingroup\$

24 bits is not quite enough, but it's much more common for problems like this to be caused by image compression algorithms, aliasing, or other digital artifacts. Also, don't overlook the role of the display technology - no matter what the digital inputs, the display may not produce the appropriate steps in actual brightness.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .