当透明图像覆盖图像时,应用模糊着色器导致图像模糊

时间:2015-03-07 15:45:51

标签: c# graphics xna shader xna-4.0

当透明图像覆盖时,我试图使图像模糊,我希望它只是模糊被覆盖的部分。因此,如果原始图像的一半没有重叠,那么一半不会模糊,但剩下的就是。

不模糊 - 不重叠 http://i.imgur.com/B7618pc.png

完全模糊 - 部分重叠 http://i.imgur.com/vx4Tq4b.png

Game1.cs

namespace NewShaderTutorial
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Effect blur;
        Texture2D surge;
        Rectangle surgeRectangle;
        Texture2D bubble;
        Rectangle bubbleRectangle;
        private bool overlapping;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            surge = Content.Load<Texture2D>("surge");
            surgeRectangle = new Rectangle(250, 250, surge.Width, surge.Height);

            bubble = Content.Load<Texture2D>("Bubble - Red");
            bubbleRectangle = new Rectangle(250, 250, bubble.Width, bubble.Height);

            blur = Content.Load<Effect>("blur");

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            if (Keyboard.GetState().IsKeyDown(Keys.Left))
                bubbleRectangle.X--;
            if (Keyboard.GetState().IsKeyDown(Keys.Right))
                bubbleRectangle.X++;
            if (Keyboard.GetState().IsKeyDown(Keys.Up))
                bubbleRectangle.Y--;
            if (Keyboard.GetState().IsKeyDown(Keys.Down))
                bubbleRectangle.Y++;

            blur.Parameters["blur"].SetValue(0.015f);

            Overlapping();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            if (overlapping == true)
            {

                spriteBatch.Begin(0, null, null, null, null, blur);
                spriteBatch.Draw(surge, surgeRectangle, Color.White);
                spriteBatch.End();
                //     spriteBatch.Begin(0, null, null, null, null, blur);
                spriteBatch.Begin();
                spriteBatch.Draw(bubble, bubbleRectangle, Color.White);
                spriteBatch.End();
            }
            else
            {
                spriteBatch.Begin();
                spriteBatch.Draw(surge, surgeRectangle, Color.White);
                spriteBatch.Draw(bubble, bubbleRectangle, Color.White);
                spriteBatch.End();
            }

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }

        public void Overlapping()
        {
            float surgeDimensionX = surgeRectangle.X + surge.Width;
            float surgeDimensionY = surgeRectangle.Y + surge.Height;
            float bubbleDimensionX = bubbleRectangle.X + bubble.Width;
            float bubbleDimensionY = bubbleRectangle.Y + bubble.Height;

            if ((surgeRectangle.X >= (bubbleRectangle.X) && ((surgeRectangle.X <= (bubbleDimensionX))) && (surgeRectangle.Y >= (bubbleRectangle.Y)) && (surgeRectangle.Y <= (bubbleDimensionY))))
            {
                overlapping = true;
            }
            else
            {
                overlapping = false;
            }
            Console.WriteLine(overlapping);
        }
    }
}

着色器类

 float4x4 World; 
    float4x4 View; 
    float4x4 Projection; 

    // TODO: add effect parameters here. 
    sampler TextureSampler; 

    float blur = 0.0015; 

    struct PixelInput 
    { 
        float2 TexCoord : TEXCOORD0; 
    }; 

float4 PixelShaderFunction(PixelInput input) : COLOR0 
{ 

        float4 color = tex2D(TextureSampler, 
        float2(input.TexCoord.x+blur, input.TexCoord.y+blur)); 
    color += tex2D( TextureSampler, 
        float2(input.TexCoord.x-blur, input.TexCoord.y-blur)); 
    color += tex2D( TextureSampler, 
        float2(input.TexCoord.x+blur, input.TexCoord.y-blur)); 
    color += tex2D( TextureSampler, 
        float2(input.TexCoord.x-blur, input.TexCoord.y+blur)); 

    color = color / 4; 
        return color; 
} 


    technique Default 
    { 
        pass P0 
        { 
            // TODO: set renderstates here. 

            PixelShader = compile ps_2_0 PixelShaderFunction(); 
        } 
    } 

所以我想让部分重叠的部分只模糊重叠的部分,而不是整个精灵。任何帮助或方向来解决这个问题都会很棒。感谢。

1 个答案:

答案 0 :(得分:0)

你有一个非常错误的方法,你只需要模糊一切或什么也不做。

您可以执行以下操作:渲染背景,角色等。不使用着色器进入屏幕外渲染目标,解析渲染目标(通过将RT切换回null - 后缓冲区),将其渲染为全屏,然后渲染您的气泡模糊着色器,将泡泡后面的内容渲染目标发送到着色器(到第二个纹理采样器)。您还需要视口宽度和高度。现在根据顶点位置将渲染目标投影到像素着色器中,将其与您的气泡纹理和剪辑相结合或丢弃圆形外的像素,或者用alpha剪辑它(如果只有圆形外的像素,例如color.a = 0;或者制作蒙版对于该着色器使用的另一个采样器中的那个圆圈并将其剪切。

弃掉https://msdn.microsoft.com/en-us/library/windows/desktop/bb943995%28v=vs.85%29.aspx

剪辑https://msdn.microsoft.com/en-us/library/windows/desktop/bb204826%28v=vs.85%29.aspx

首选剪辑。