Search code examples
shadertextureshlsldds-format

Sampling compressed textures with less than 4 channels


Are there any differences between sampling 4-channel 32-bit textures and, say, 2-channel floating point textures, such as 16.16f or 32.32f (red + green)?

I'm primarily referring to DDS texture formats, but believe I've seen similar things available for OpenGL. I'm not familiar with the use of textures that have less than 4 channels in them, but I've read somewhere that they remain compressed in memory. I'm assuming this also means that 2-channel textures will remain as 2 channels in memory, so I'm wondering what data type is returned from these when they are sampled in fragment shader code, such as GLSL or HLSL? And is there more than one way to sample from them?

If sampling these textures will always return float4 or vec4, does that mean the API is converting the data to float4 with something like return float4( texel.r, texel.g, 0, 0 ) each time it is sampled?

Are there any other considerations or advice when using these types of textures in shaders?


Solution

  • DDS is just a container file format with support for BCn compressed texture data that can be consumed in both DirectX and OpenGL.

    When not dealing with emulated support the data stays compressed in GPU memory and is uncompressed on-the-fly when reading. Sampling from it in shader does indeed yield a 4 component vector, in OpenGL sampling from a 2 channel texture of format RG yields vec4(R,G,0,1) whereas the format LUMINANCE_ALPHA yields vec4(L,L,L,A), i wouldn't really say the data is "converted" as there's no work involved.

    Regarding other considerations, you should know that some BCn formats have varying channel bit-depth, so if you encode data like normals or material properties in textures you'll want to choose your channels and compression algorithm carefully. There's also a speed/quality tradeoff in compressors. But this is way too open ended of a question really.