Jump to content
  • Advertisement
Sign in to follow this  
Alex F

Lookup table using pixel shader

This topic is 3849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is it possible to write pixel shader which converts texture image using Lookup table? Pseudo-code is: unsigned char LUT[256]; for each pixel in image pixel = LUT[pixel]; Image is 8 bpp monochrome. Inside of pixel shader it looks like ARGB image with equal R,G and B components. Is it possible to write such shader, load LUT to it programmatically, and execute it?

Share this post


Link to post
Share on other sites
Advertisement
Yes. The easiest option is to put the LUT in another texture. Make sure you use point sampling for both textures and it should be straight forward to do.

Share this post


Link to post
Share on other sites
Here's an HLSL shader I wrote for 8-bit paletted images. The textures are stored in monochrome L8 format. The palette texture is 256x1 in size.


float4x4 WorldViewProj : WORLDVIEWPROJ;

Texture ColorTexture;

sampler ColorTextureSampler = sampler_state { texture = <ColorTexture> ; magfilter = NONE; minfilter = NONE; mipfilter = NONE; AddressU = wrap; AddressV = wrap; };

Texture PaletteTexture;

sampler PaletteTextureSampler = sampler_state { texture = <PaletteTexture> ; magfilter = NONE; minfilter = NONE; mipfilter = NONE; AddressU = wrap; AddressV = wrap; };

struct a2v
{
float4 Position : POSITION0;
float2 TexCoords : TEXCOORD0;
};

struct v2p
{
float4 Position : POSITION0;
float2 TexCoords : TEXCOORD0;
};

struct p2f
{
float4 Color : COLOR0;
};

void vs( in a2v IN, out v2p OUT )
{
OUT.Position = mul( IN.Position, WorldViewProj );
OUT.TexCoords = IN.TexCoords;
}

void ps( in v2p IN, out p2f OUT )
{
float4 TextureColor = tex2D( ColorTextureSampler, IN.TexCoords );
OUT.Color = tex1D( PaletteTextureSampler, TextureColor.r );
}

technique PaletteTechnique
{
pass p0
{
vertexshader = compile vs_1_1 vs();
pixelshader = compile ps_1_4 ps();
}
}

Share this post


Link to post
Share on other sites
One thing to watch out for doing a pixel shader based palettized texture like this is that texture filtering won't work correctly. You'll either need to live with texture filtering turned off (as in Scet's example) or implement the filtering manually yourself in the shader. You will also have to write custom code to generate your mipmap chain as standard mipmapping won't work correclty either.

The reason that filtering and mipmapping don't work with palettized textures is that the lerp of two palette indices doesn't generally equate to the index of the lerp of the two colours, unless your palette happens to be a linear ramp.

Share this post


Link to post
Share on other sites
Thank you very much, two textures and function ps( in v2p IN, out p2f OUT ) did the trick.

Share this post


Link to post
Share on other sites
Hello. I found interesting bug in this code: pixel with value 255 is always mapped to 0. All other pixel values are OK. After playing some time with shader text I found the version which works correctly:

void ps( in v2p IN, out p2f OUT )
{
float4 TextureColor = tex2D( ColorTextureSampler, IN.TexCoords );
float f = TextureColor.r;

if ( f == 1.0 )
{
f = 0.999;
}

OUT.Color = tex1D( PaletteTextureSampler, f );
}

It looks like avoiding 1.0 value solved the problem. Maybe there is more elegant solution? Thank you.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!