I'm writing a bunch of GLSL effects for fun, but I can't wrap my head around this. Basically, I want to reduce a texture's palette into a pre-defined set of colors. For example, a post-processing shader would take the FBO result texture and a 1D / 2D texture that would contain the reduced palette (say, 64 colors), and the output would then be sampled based on these.
Something like this in its core:
sampler2D source;
sampler2D palette;
vec4 source = texture2D(...); // Source texture to sample
vec4 palette = texture2D(...); // Palette
vec3 result = /* color from the source converted to the closest value available in palette */;
Any ideas how to do this? And to be more precise, I don't mean palette swapping - the source texture is full-colored result, and this shader would ultimately be a post-processing shader, reducing the amount of colors to the ones that are predefined in the palette texture.
Answer
Another way to do this is to make a texture that maps each RGB to a colour on the palette, an image like this (from the NES colours):
Then in a post processing shader you can the RGB colour from your regular image in a way like this:
uniform sampler2d paletteMapping;
vec3 mapColor( vec3 realColor ) {
vec3 mappedColors = floor( realColor * 16 );
int mappedI = mappedColors.r + mappedColors.g * 16 + mappedColors.b * 16 * 16;
return texture2D( paletteMapping, floor( vec2( mappedI / 64, mod( mappedI, 64 ) ) );
}
I've not tested the shader as I'm at work, but this should work on a texture that has interpolation disabled (i.e. it uses nearest neighbour sampling).
The map image I created with a little tool I wrote, from the NES palette image on wikipedia
No comments:
Post a Comment