Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am attempting to use Gaussian blur on a 2D platform game, selectively blurring specific types of platforms with different amounts. I am currently just messing around with simple test code, trying to get it to work correctly. What I need to eventually do is create three separate render targets, leave one normal, blur one slightly, and blur the last heavily, then recombine on the screen. Where I am now is I have successfully drawn into a new render target and performed the gaussian blur on it, but when I draw it back to the screen everything is purple aside from the platforms I drew to the target.

This is my .fx file:

#define RADIUS  7
#define KERNEL_SIZE (RADIUS * 2 + 1)

//-----------------------------------------------------------------------------
// Globals.
//-----------------------------------------------------------------------------

float weights[KERNEL_SIZE];
float2 offsets[KERNEL_SIZE];

//-----------------------------------------------------------------------------
// Textures.
//-----------------------------------------------------------------------------

texture colorMapTexture;

sampler2D colorMap = sampler_state
{
    Texture = <colorMapTexture>;
    MipFilter = Linear;
    MinFilter = Linear;
    MagFilter = Linear;
};

//-----------------------------------------------------------------------------
// Pixel Shaders.
//-----------------------------------------------------------------------------

float4 PS_GaussianBlur(float2 texCoord : TEXCOORD) : COLOR0
{
    float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);

    for (int i = 0; i < KERNEL_SIZE; ++i)
        color += tex2D(colorMap, texCoord + offsets[i]) * weights[i];

    return color;
}

//-----------------------------------------------------------------------------
// Techniques.
//-----------------------------------------------------------------------------

technique GaussianBlur
{
    pass
    {
        PixelShader = compile ps_2_0 PS_GaussianBlur();
    }
}

This is the code I'm using for the gaussian blur:

public Texture2D PerformGaussianBlur(Texture2D srcTexture,
                                             RenderTarget2D renderTarget1,
                                             RenderTarget2D renderTarget2,
                                             SpriteBatch spriteBatch)
        {
            if (effect == null)
                throw new InvalidOperationException("GaussianBlur.fx effect not loaded.");

            Texture2D outputTexture = null;
            Rectangle srcRect = new Rectangle(0, 0, srcTexture.Width, srcTexture.Height);
            Rectangle destRect1 = new Rectangle(0, 0, renderTarget1.Width, renderTarget1.Height);
            Rectangle destRect2 = new Rectangle(0, 0, renderTarget2.Width, renderTarget2.Height);

            // Perform horizontal Gaussian blur.

            game.GraphicsDevice.SetRenderTarget(renderTarget1);

            effect.CurrentTechnique = effect.Techniques["GaussianBlur"];
            effect.Parameters["weights"].SetValue(kernel);
            effect.Parameters["colorMapTexture"].SetValue(srcTexture);
            effect.Parameters["offsets"].SetValue(offsetsHoriz);

            spriteBatch.Begin(0, BlendState.Opaque, null, null, null, effect);
            spriteBatch.Draw(srcTexture, destRect1, Color.White);
            spriteBatch.End();

            // Perform vertical Gaussian blur.

            game.GraphicsDevice.SetRenderTarget(renderTarget2);
            outputTexture = (Texture2D)renderTarget1;

            effect.Parameters["colorMapTexture"].SetValue(outputTexture);
            effect.Parameters["offsets"].SetValue(offsetsVert);

            spriteBatch.Begin(0, BlendState.Opaque, null, null, null, effect);
            spriteBatch.Draw(outputTexture, destRect2, Color.White);
            spriteBatch.End();

            // Return the Gaussian blurred texture.

            game.GraphicsDevice.SetRenderTarget(null);
            outputTexture = (Texture2D)renderTarget2;

            return outputTexture;
        }

And this is the draw method affected:

    public void Draw(SpriteBatch spriteBatch)
    {
        device.SetRenderTarget(maxBlur);
        spriteBatch.Begin();
        foreach (Brick brick in blueBricks)
            brick.Draw(spriteBatch);
        spriteBatch.End();

        blue = gBlur.PerformGaussianBlur((Texture2D) maxBlur, helperTarget, maxBlur, spriteBatch);

        spriteBatch.Begin();
        device.SetRenderTarget(null);

        foreach (Brick brick in redBricks)
            brick.Draw(spriteBatch);

        foreach (Brick brick in greenBricks)
            brick.Draw(spriteBatch);

        spriteBatch.Draw(blue, new Rectangle(0, 0, blue.Width, blue.Height), Color.White);

        foreach (Brick brick in purpleBricks)
            brick.Draw(spriteBatch);

        spriteBatch.End();
    }

This is what it should look like(if it were blurred correctly) non-blurred correct

This is what it currently looks like blurred incorrect

I'm sorry about the massive brick of text and images, but I wanted to get my problem across clearly as I have been searching for an answer to this for quite a while now. As a side note, I have seen the bloom sample. Very well commented, but overly complicated since it deals in 3D; I was unable to take what I needed to learn form it. Thanks for any and all help.

share|improve this question
    
Hi Josh, could you post links to pictures of the visual effect you are working to achieve and cannot add to your Question? –  Zehelvion Nov 22 '12 at 6:58

2 Answers 2

The purple background generally means that nothing is being rendered as that is the default back buffer color in XNA. I cannot verify this, but it looks like your order of drawing state swapping may be incorrect. Try setting the render target before beginning the spritebatch

share|improve this answer

The kernel is too big. Try reducing the size of the kernel, did you normalize the kernel coefficients? (So in that Paul Rideout example, he divides each weight by (1+4+6+4+1)=16). I know the kernel weights initially look to be 1,4,6,4,1, but they are actually 0.0625,0.25,0.375,0.25,0.0625

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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