2
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Hi Josh, could you post links to pictures of the visual effect you are working to achieve and cannot add to your Question? \$\endgroup\$
    – AturSams
    Nov 22, 2012 at 6:58

2 Answers 2

3
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$

You must log in to answer this question.

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