HLSL Pixel Shader that does palette swap

Started by
18 comments, last by derrace 11 years, 4 months ago
Alright, I have tried using greyscale as my index.

http://imgur.com/CWZju

Hmm, it looks a bit better after using greyscale, but still far from perfect.. Running out of ideas =\
Advertisement
Argh, turns out when my engine is running at 1x (default resolution) the shader works perfectly, any scale of that (including the default XNA's graphics.ToggleFullScreen();) stuffs it up =\.

I am passing a transformation matrix into my spriteBtach.Begin method to scale my playable window by X amount, as well as using it for my camera + parallax effect.

It appears that the translation or scale operations are messing up my pixel shader?


I need help, badly now =(
You might want to play around with the texture filtering for the sprite batch. Try adding this before the begin call:

this.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;

The default in XNA (according to the interlect) is LinearClamp
I say Code! You say Build! Code! Build! Code! Build! Can I get a woop-woop? Woop! Woop!

You might want to play around with the texture filtering for the sprite batch. Try adding this before the begin call:

this.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;

The default in XNA (according to the interlect) is LinearClamp



Hi there, I have tried that, but to no avail.

I have been reading up on this: http://msdn.microsoft.com/en-us/library/ff604998.aspx

But I have no experience with sampler state. Do you know of any tutorials which might help?

I am thinking of using the shader to do my scaling (magnification) just for the sprite. I am really at a lost atm =\
If you're using SpriteBatch, you have to specify the sampler state in the Begin call. Otherwise it will override it with LinearClamp.

So use the overload of SpriteBatch.Begin that takes a SamplerState.

If you're using SpriteBatch, you have to specify the sampler state in the Begin call. Otherwise it will override it with LinearClamp.

So use the overload of SpriteBatch.Begin that takes a SamplerState.


Ah, that did the trick. Thanks a lot!

Are there any sites you could recommend to read up on this? The lack of documentation on MSDN is really slowing my progress and I am just stumbling along with random google searches.... =(
Yeah, the MSDN documentation is pretty awful. The education samples are pretty good though: http://xbox.create.msdn.com/en-US/education/catalog/

I would also recommend Shawn Hargreaves blog, though I suspect your random google searches lead you there pretty frequently anyway :-).

Replacing my default sprites with a greyscale one is kinda tedious, and I am hoping there's a better way.


I wonder if tinting the player would be good enough instead of a full palette swap ... don't use your existing palette swapping pixel shader, instead treat the image of your character as a greyscale by sampling the original texture and ignoring 2 out of the 3 color channels, then multiply the greyscale by a passed in tintcolor to make the player a different color.

float4 originalColor = tex2d( TexSampler, tex0.xy );
float4 greyColor = float4( originalColor.r, originalColor.r, originalColor.r, originalColor.a );
float4 newColor = greyColor * tintColor;

where you pass tintColor in as a uniform extern.

You might have to experiment with which channel you want to use as the grey scale (r,g or b).

[quote name='derrace' timestamp='1353690938' post='5003531']
Replacing my default sprites with a greyscale one is kinda tedious, and I am hoping there's a better way.


I wonder if tinting the player would be good enough instead of a full palette swap ... don't use your existing palette swapping pixel shader, instead treat the image of your character as a greyscale by sampling the original texture and ignoring 2 out of the 3 color channels, then multiply the greyscale by a passed in tintcolor to make the player a different color.

where you pass tintColor in as a uniform extern.

You might have to experiment with which channel you want to use as the grey scale (r,g or b).
[/quote]

Hi Steve, changing my spritesheet to greyscale was a lot easier than I thought, although it's more of a Black and White filter (with same values for RGB).

I had thought of that prior, but I have a problem that with my original palette, I don't have a unique RGB band, so sampling just one of the band is not possible. Selecting the average 2 of the 3 yields duplicate values, and it gets messy if i take the average of all 3. This was why I went with greyscale.

My motivation for getting the palette swap working was because it would be reused in many situations. My palette has 15+ samples, so it would be a nightmare trying to get the right set of colours for try and error with the tinting method. Doing it with a colour table makes it easy to swap the colours, as well as knowing exactly what colours it would be swapping.
Anyway, I got it working. Thanks everyone for their help.

Here's it in action =)

This topic is closed to new replies.

Advertisement