locked
Using Dx11 greyscale texture formats

    Question

  • It seems that all Dx11 greyscale (or single channel formats) only resolve to the red channel inside of a pixel shader.

    This can readily be solved by swizzling, i.e. color.rgb = texturesample.rrr

    However, in order to to this, that makes the shader now DEPENDENT on the details of what texture format used. This is a problem when I would like the shader to also work with full-color data as well.

    For example, Here is a typical shader using three texture samples:

    FinalColor = (DiffuseColor + DecalLayer) * LightmapSample.

    Each one of these terms may be well-suited to using a greyscale image for optimal compression, and the determination of what format to be used should only be dependent on the particular source bitmap assets.

    I am targeting the dx9 feature level to get our games working on the largest number of devices... so we do not necessarily get static branching in our pixel shaders either. 

    In dx11 it looks like I would need 8 separate pixel shaders to represent the combinations of format swizzling between each of the three texture inputs. Note that on Metro targets, all these 'swizzle variant' shaders would also have to be precompiled ahead of time, which will increase the app package size.

    This seems more complex than it needs to be. This was not a problem in DX9, nor is it an issue on GL platforms.

    I think single channel formats should just expand into the .rgb by default, as is standard everywhere else. Ideally, if more programability were required, it would be nice to just specify the swizzle at the 'sampler state' level, just like texture addressing and so forth. This would avoid a combinatorial explosion of shaders just to be able to effectively use greyscale compression.

    Any other ideas on how to approach this problem? Thanks for considering -

    Monday, September 17, 2012 6:26 PM

Answers

  • The shader swizzle is how you 'emulate' the old Direct3D 9 era "Luminance" formats with Direct3D 10.x/11.x. For Direct3D 9, this was a special case handling of a single channel. The only 'special' case for a single-channel format in DXGI is R8 vs. A8.

    You could consider packing the data to several channels of a single texture rather than having distinct textures for each channel of data, which is likely more efficient.

    Thursday, September 20, 2012 11:10 PM