Specific Shader Questions

Hey, time for my monthly ramblings of the problems I’ve encountered.

First off, I’ve been having difficulty with my fade shader. The issue is that I use a restricted colour palette of 16 colours. I recently added a few transparent blue as well for water. To fade in and out, I want to keep the screen locked to these colours. I have a shader which essentially takes a colour and looks it up on a texture by its green value on the Y axis, then by its ‘brightness’ on the X axis. The shader is this:
sampler inputTexture;
float fadeVal;
sampler palette;

float4 MainPS(float2 textureCoordinates: TEXCOORD0): COLOR0
	float4 color = tex2D(inputTexture, textureCoordinates);
    float4 returnColor = tex2D(palette, float2(1-fadeVal, color.g));
    return float4(returnColor.r, returnColor.g, returnColor.b, color.a);

technique Techninque1
    pass Pass1
       	PixelShader = compile ps_3_0 MainPS();
     	AlphaBlendEnable = TRUE;
     	DestBlend = INVSRCALPHA;
     	SrcBlend = SRCALPHA;

This has worked fine but now with the transparent colours, the amount of colours that could be created means that colours are colliding a lot and I feel like this system is doomed to fail with these new colours. Any ideas, perhaps a different algorithm or a better way to do this one?

My other issue is how to manage water distortions with shaders, but not with how to get the distortions, rather how to select just the area with the water. I would have normally done this with a render target, but I’m not sure how to do this in this scenario. I would need to draw everything behind the water to the render target along with the water, but I’m already drawing a lot to different render targets, and I would need to draw the water on a separate layer to everything else, which is undesirable. Essentially, I’m just wondering the best way to easily apply a shader to a specific area of the screen that also needs to take into account the backgrounds.

Thanks for any responses, you can just reply to one query without addressing the other if you would like.

Update: I have recently solved the first issue, namely by having a sperate sprite that water will use when the screen is fading. I can elaborate if anyone needs help but it seems a little too specific.

The second problem persists however, I can’t for the life of me figure out how to have a shader being applied to water tiles only. How do I tell the shader to only operate on water tiles? Perhaps a shader isnt the best way to achieve water distortion effects in 2D, but i can’t think of anything else really. Some help would be highly appreciated.

Can you render the all the water to a separate render target. Apply the shader then apply the second rendertqrget to your main rendertarget?


This was my initial idea, but I would need to render everything beneath the water too as the shader needs to accommodate for things behind it. If I were to do this then how would the shader know which tiles are water and which ones are just background tiles?

I can think of 3 masking methods for shaders. Which one is best depends on your specific situation:

1.) only draw polygons in places where you want the shader to apply
2.) keep the mask in a texture / render target. This could be a separate texture, or just the alpha channel of an existing texture.
3.) stencil buffer

Number 3 looks perfect, but i cant find any documentation on it for use with shaders. How would I use a stencil buffer to only apply shaders to a particular area? Also, since the area to apply the shaders could be anywhere and moves as well, how would i generate the stencil?

I’m going to ask this question as a separate thread since this has drifted quite far from the original question