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

本文关键字:图像 模糊 透明图 透明 覆盖 覆盖图 应用 | 更新日期: 2024-10-23 21:02:23

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

未模糊-不重叠https://i.stack.imgur.com/joKzu.png

完全模糊-部分重叠https://i.stack.imgur.com/k8Tb7.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(); 
        } 
    } 

所以我想让部分重叠的部分只模糊重叠的部分,而不是整个精灵。解决这个问题的任何帮助或指导都将是伟大的。谢谢

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

这是一种非常错误的方法,你要么模糊所有东西,要么什么都不模糊。

例如,您可以执行以下操作:在不将着色器渲染到屏幕外渲染目标的情况下,解析该渲染目标(通过将RT切换回null-backbuffer),将其全屏渲染,然后使用模糊着色器渲染气泡,将气泡后面内容的现有渲染目标发送到着色器(到其第二个纹理采样器)。您还需要视口的宽度和高度。现在,根据顶点位置将渲染目标投影到像素着色器中,将其与气泡纹理组合并剪裁或丢弃圆外的像素,或者通过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

首选夹子。