Convert a grayscale png file to BC3_UNORM_SRGB

Jul 11, 2013 at 7:24 AM
Hi, I'm using the texconv to convert a grayscale png file to a dds file. I use the command:
-srgb -f -BC3_UNORM_SRGB
It turns out many pixels in the dds file looks carnation or aqua.
I'm a newer in dds so can you tell me how this problem comes out.

Thanks.
Coordinator
Jul 11, 2013 at 7:57 PM
Can you attached the PNG file you tried to convert?
Jul 12, 2013 at 1:55 PM
![Image]([http://farm8.staticflickr.com/7329/9266910011_e495b312cf.jpg]
Actually, I've tried to convert a grayscale image to a dds file by writing my own program or using the nvidia ps plugin, but it didn't work. There are still many colorful pixels. They're not very obvious so you may need a shader program to check the R/G/B channels.
Coordinator
Jul 12, 2013 at 2:48 PM
BC compression is lossy, and cannot be relied on to preserve exact greyscale data. In particular, BC3 format uses 5.6.5 encoding for the block endpoint colors. Having a different number of bits for the green vs. red and blue channels allows more accurate representation of luminance, which is helpful for noisy, organic type images, but at the cost of some chroma shift which I suspect is what you are seeing here.

A better option might be the R8 or A8 formats, which will exactly encode greyscale information with better precision and the same size as BC3.
Coordinator
Jul 12, 2013 at 6:49 PM
Sorry, that jpeg link doesn't work for me.

I just tried a greyscale image and used 'texconv -f BC3_UNORM' and the results are exactly what I would expect.

I'll open a work item for this issue. Please attach your PNG file to that so I can try to repro it...
Coordinator
Jul 12, 2013 at 7:03 PM
This issue has been moved to DirectXTex issue 980
Jul 14, 2013 at 1:41 PM
I think ShawnHargreaves is right, the problem is from BC3 itself.
However, sometimes I try to convert a rgba format image into BC3 format image and it has the same problem. So I don't think R8 or A8 formats will solve the problem but thanks anyway and I know the reason now.
By the way, I've uploaded the png file in DirectXTex issue 980.
Coordinator
Jul 15, 2013 at 1:29 AM
Edited Jul 15, 2013 at 1:30 AM
I meant that you should use R8 or A8 as your /output/ format, not as the input for compression into a BC format. The BC1-3 family of compression algorithms are not great for encoding single channel data. You'll get far better quality for the same number of bits using a format that just directly stores that single channel.
Jul 16, 2013 at 6:24 AM
Imaging there's a RGBA texture, some pixels are bright and colorful, some pixels are dark and their R/G/B channels are equal to each other. If I use R8 format I can't get the G/B/A channels' data. If I use R8G8B8A8 format then there's no diffrence with original png texture. If I use BC3 format the dark pixels' R/G/B will not be equal anymore. This may not be obvious in the texture but if I put the texture into my shader program the result will be quite different to that using the png texture. So this is where the BC3 format troubles me.
Coordinator
Jul 16, 2013 at 6:37 AM
Edited Jul 16, 2013 at 6:51 PM
The choice of runtime format depends heavily on the content of the image. If the image is truly greyscale, then you are much better using DXGI_FORMAT_Rx_UNORM and then having your shader replicate the colors to all three channels. This is memory and hardware efficient.

If your image contains general color images, then the BC1-3 formats can be extremely useful in reducing the overall memory usage of the texture. Compared to an RGBA32 format, BC1 is 8X smaller (each 4x4 block of 16 pixels takes 8 bytes in BC1 and in the original image it took 4 * 4 * 4 bytes which is 64). The trade off is that BC1-3 uses two 16bit RGB colors as end-points on a linear interpolation and then 2 bits per pixel to indicate which of 3 or 4 colors to use. This means an inexact reconstruction, but it is extremely useful for many textures.... just not greyscale ones.

See MSDN
Coordinator
Jul 16, 2013 at 7:07 PM
Generalities aside, I don't actually see any problem converting your test image to either BC3_UNORM or BC3_UNORM_SRGB. The results are quite reasonable for the block compression and there's no significant color shift.

MSE between the original and the BC3 version comes out as {"[red: 0.000058 green: 0.000013 blue: 0.000058]"} which means there's a little more error in R and B and a little less error in G which is to be expected for a 5:6:5: color.

Make sure you are using the latest version of the library and tool.
Jul 17, 2013 at 11:51 AM
Thanks walbourn.
I know more about DDS format now. I'll think through about this convert thing.
Coordinator
Jul 17, 2013 at 9:06 PM
Sounds good. If you would like to do any more reading on block compression, keep this link handy...
Marked as answer by walbourn on 1/23/2014 at 11:27 PM