The shader is taking a grayscale texture and interpret it as a single channel R8_UNORM texture. The grayscale texture is generated from an offline tool (for now) that read indexed images and write the the indices as grayscale values and write it to a PNG (which supports grayscale pixel format).
The palette data is stored in a GPU-optimized buffer that is sub-allocated from 65536 bytes, the minimum buffer size allowed. It allows to store up 16384 colors, more than enough for storing lots of palette, like 1024 palette of 16 colors.
* Store the indices as pixel value of a single channel texture
* Store the palette into a buffer instead of a texture for easier reading and less memory usage.
* Sample the indice and fetch the color from the palette in the pixel shader.
Comments
We then sample the texture to get the palette index and read the packed color from the palette. It is then unpacked into a float4.
Before I used R8_UINT texture and Load() but using UNORM permit more filtering options.
* Store the indices as pixel value of a single channel texture
* Store the palette into a buffer instead of a texture for easier reading and less memory usage.
* Sample the indice and fetch the color from the palette in the pixel shader.