Hello.
I’m using some textures that only have black and white pixels and I want to optimize the format the best as I can, is there a way to use a texture in 1bit format?
Hello.
I’m using some textures that only have black and white pixels and I want to optimize the format the best as I can, is there a way to use a texture in 1bit format?
Is there any gpu support for 1 bit textures?
I think single channel textures is the best bet
Nice info: Unity Texture Compression Cheat Sheet - techarthub
I guess I’ll go with whichever uses less VRAM, thanks.
some compressed formats have 1 bit alpha channels. But ofc you also need to match that with a color texture.
You could also try storing it into a single channel texture but then store 8 values per pixel using bitshifting. This will reduce memory and possibly GPU bandwidth.
Thanks, I didn’t know about bitshifting. But since this is going to be used as something that stores volumetric data, I’d rather give the shader as less instructions as possible. I’ll look into that 1 bit alpha format.
Bandwidth is always more costly performance wise and energy wise than cheap/somewhat computations on the GPU. Especially since it would just be 1 bitshift and an AND operation to get your 1 bit of data back from a byte. Integer operations aren’t cheap on GPUs (depending) but will most likely beat out more memory accesses. But ofc you should profile to be sure.
To reiterate the thread, and add some additional info.
No, there is no single channel 1 bit texture format on GPUs.
The “best” (cheapest) format available for a single channel 1 bit mask is a BC4, which is a compressed single red channel format. This should be capable of storing a 1 bit mask with perfect precision using 4 bits per pixel. This is basically the alpha channel of a DXT5/BC3 texture by itself, so it can actually represent an 8 bit greyscale image.
Mentioned above is the concept of bit packing, which would let you store eight 1 bit masks in a single channel 8 bit texture. For this to work you need to use an uncompressed R8 or A8 texture, you cannot use a BC4 as the compressed format won’t guarantee the exact bits will stay the same. You also can’t use bilinear filtering or (automatic) mip mapping, if that’s something that’s wanted, as the filtered values will also loose the exact bit values needed to accurate extract the masks. Also mentioned above is that this requires bitwise and integer math to extract the masks and this can be expensive … but this isn’t really true. You can both emulate bitwise operations without even needing integer math, and it’s not actually expensive on any modern GPUs made in the last decade, including mobile GPUs. So that’s a non-issue.
Lastly, pros almost never do any of this for masks stored in assets. Bitwise operations are common for 1 bit mask you might want to generate at runtime and store in render textures, since those are (almost) always uncompressed. BC4 textures are used sometimes when you need good precision, but more commonly people use DXT1/BC, pack 3 masks into it, one in each channel, and extract them efficiently and dynamically with a single dot product.
half4 masks = tex2D(_MaskTex, uv);
// _MaskChannel
// a half4 value that you set to (1,0,0,0), (0,1,0,0), or (0,0,1,0)
// to select the red, green, or blue channel
half mask = dot(masks, _MaskChannel);
This can have problems with compression artifacts where all 3 masks edges are near each other, but most of the time this is more than sufficient. Worse case you can use a BC7 texture for fewer artifacts, and pack up to 4 masks into a single texture. Or use the BC4 format if that’s still not good enough.