I have implemented a simple pixel shader which can replace a particular colour in a sprite with another colour.

It looks something like this:

sampler input : register(s0);
float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
    float4 colour = tex2D(input, coords);
    if(colour.r == sourceColours[0].r &&
    colour.g == sourceColours[0].g &&
    colour.b == sourceColours[0].b) return targetColours[0];
    return colour;

What I would like to do is have the function take in 2 textures, a default table, and a lookup table (both same dimensions). Grab the current pixel, and find the location XY (coords) of the matching RGB in the default table, and then substitute it with the colour found in the lookup table at XY.

I have figured how to pass the Textures from C# into the function, but I am not sure how to find the coords in the default table by matching the colour.

Could someone kindly assist?

Thanks in advance.

  • \$\begingroup\$ Hmm, think I got it, It involves using a for loop to cycle through the a variant of the above code but I am getting this silly error now =( Shader uses texture addressing operations in a dependency chain that is too complex for the target shader model (ps_2_0) to handle. \$\endgroup\$ – derrace Nov 22 '12 at 8:04

Hmm, I have just registered my account, but I can't access my original post. Can any moderator help?

Anyway, I was using 2D array so that I can store different "palettes" and swap between them. I will simplify the solution so that it uses a 1x4 and see if I can "toggle" between the 4 pixels with hardcoded values.

  • \$\begingroup\$ pastebin.com/TBWvjrqE Ok, I have created a 4x1 png and inserted 4 different coloured pixels. I have changed index from 0 to 3 (or any value for that fact) but it always display the colour of the first pixel. If i change index with the var coords in the tex1D method, and move my sprite, it cycles through the colours when I move, but displays the colour of the first pixel when stationary. Do you have any idea why this is happening? \$\endgroup\$ – derrace Nov 22 '12 at 17:10

You should not use loops...

Have you consider using a palette, and use one color channel of the primary texture as index?

You can use the red channel as index, and sample to a Texture1D where you store your palette colors

  • \$\begingroup\$ Hi Blau, I am passing in 2 palettes, one the default of the sprite, and the other a lookup. When the function is called, I am comparing the RGB of that pixel with the default palette to determine the location, so that I can grab the colour I want from the look up. But this involves using a loop. With your suggestion, Assuming my red channel is unique for my base sprite and my colour table has 15 RGB values, would that mean I would have (255-15) empty values as I would only sample 15 values of Red? \$\endgroup\$ – derrace Nov 22 '12 at 9:03
  • \$\begingroup\$ what's the matter with that? one colour channel lets you index to 256 colours, but if u have less there is no problem. Let tex1D get the color for you, tex1D samples in u coords [0..1], so if your texture palette has 16 colors, divide the index by 16 to get you value in [0..1] range, and then you can sample it easily. \$\endgroup\$ – Blau Nov 22 '12 at 9:53
  • \$\begingroup\$ hmm, how do u insert code in the new comments? It wraps all my lines up =\. Anyway, the main gist of the code is: int2 index = int2(colour.r,0); float4 lookUp = tex2D(PaletteSampler,index); the 2nd param for tex2D, is the pixel coordinate relative to the size of texture I have passed in for PaletteSampler? I am asking because it's returning me a different colour. \$\endgroup\$ – derrace Nov 22 '12 at 10:34
  • \$\begingroup\$ use pastebin.com ... :) debugging pixel shader is hard... why don't use one dimension array for colors and sample it with Tex1D? \$\endgroup\$ – Blau Nov 22 '12 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.