2
\$\begingroup\$

I am trying to make a pixel shader that achieves an effect similar to this video http://www.youtube.com/watch?v=f1uZvurrhig&feature=related

My basic idea is render the scene to a temp render target then Render the previously rendered image with a slight fade on to another temp render target Draw the current scene on top of that Draw the results on to a render target that persists between draws Draw the results on to the screen

But I am having problems with the fading portion. If I have my pixel shader return a color with its A component set to 0, shouldn't that basically amount to drawing nothing? (Assuming that sprite batch blend mode is set to AlphaBlend)

To test this I have my pixel shader return a transparent red color. Instead of nothing being drawn, it draws a partially transparent red box.

I hope that my question makes sense, but if it doesnt please ask me to clarify

Here is the drawing code

    public override void Draw(GameTime gameTime)
    {
        GraphicsDevice.SamplerStates[1] = SamplerState.PointWrap;

        drawImageOnClearedRenderTarget(presentationTarget, tempRenderTarget, fadeEffect);
        drawImageOnRenderTarget(sceneRenderTarget, tempRenderTarget);
        drawImageOnClearedRenderTarget(tempRenderTarget, presentationTarget);

        GraphicsDevice.SetRenderTarget(null);

        drawImage(backgroundTexture);
        drawImage(presentationTarget);

        base.Draw(gameTime);
    }

    private void drawImage(Texture2D image, Effect effect = null)
    {
        spriteBatch.Begin(0, BlendState.AlphaBlend, SamplerState.PointWrap, null, null, effect);
        spriteBatch.Draw(image, new Rectangle(0, 0, width, height), Color.White);
        spriteBatch.End();
    }

    private void drawImageOnRenderTarget(Texture2D image, RenderTarget2D target, Effect effect = null)
    {
        GraphicsDevice.SetRenderTarget(target);
        drawImage(image, effect);
    }

    private void drawImageOnClearedRenderTarget(Texture2D image, RenderTarget2D target, Effect effect = null)
    {
        GraphicsDevice.SetRenderTarget(target);
        GraphicsDevice.Clear(Color.Transparent);
        drawImage(image, effect);
    }

Here is the fade pixel shader

sampler TextureSampler : register(s0);

float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
    float4 c = 0;
    c = tex2D(TextureSampler, texCoord);
    //c.a = clamp(c.a - 0.05, 0, 1);
    c.r = 1;
    c.g = 0;
    c.b = 0;
    c.a = 0;
    return c;
}

technique Fade
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
\$\endgroup\$

1 Answer 1

6
\$\begingroup\$

BlendState.AlphaBlend uses premultiplied blending so check out this for why you can a value of 0 for alpha and still have the pixel not be transparent (especially the last paragraph).

So I believe what you need is in your shader is (I'm bad with shaders so take this with a grain of salt).

c.a = clamp(c.a - 0.05, 0, 1);
c.r = c.r * c.a;
c.g = c.g * c.a;
c.b = c.b * c.a;
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .