Search code examples
hlslpixel-shaderdirectx-12direct3d12

D3D12 Dynamic indexing of textures with different formats


In shader model 5.1 we can use dynamic indexing for textures like so:

Texture2D textures[5] : register(t0)
PixelShader(Input p) : SV_TARGET
{
     float4 color = textures[0].Sample(someSampler, p.UV);
     return color;
}

Here it's assumed that all textures have 4 channels (rgba). However, I have no idea how to sample when my texture array is a mix of different formats like BC3 (rgba), BC4 (single channel R), BC5 (dual channel RG). For example, in case of BC4 I could try

float R = textures[0].Sample(someSampler, p.UV).r;

But wouldn't this just skip over three texels?


Solution

  • HSLS Shader model 5.1 is quite confusing because you have a distinction between "texture array" and "texture array"...

    The first meaning is the one that appeared with DX10, A single texture resource is made of several slices and a shader can index in the slices. The major limitation is that each slice have to share size and format.

    The second meaning, introduced with API like DX12 or Vulkan is closer to "an array of textures". You can now group multiple resource objects into an array of descriptors. The shader can freely use any of them with dynamic indexing. The constraint of a texture array are lifted. The one limitation is the use of the NonUniformIndex intrinsic to let the driver fix up indexing limitation a GPU may have.

    As for your original questionm, It is then up to you to know what texture are where, if you group texture with formats like BC4 and BC7, it is probably because one is an albedo while the other may be a gloss map. Your shader will give the semantic to what it read. But if you want a BC4 texture to expand as RRRR instead of the default R001, you can use the component mapping in the shader resource view.