【问题标题】:AlphaMask in monogame not working properly单人游戏中的 AlphaMask 无法正常工作
【发布时间】:2014-02-05 03:34:42
【问题描述】:

我正在尝试为战争迷雾示例构建渲染目标 alpha 蒙版。我告诉它我想用纯白色 (Alpha 255) 清除渲染目标

然后我用透明圆圈将我的图像绘制到 alpha 通道上,从那里我希望在渲染目标中有一个图像,其中有孔。然而事实并非如此。我非常熟悉 alpha 蒙版,并且在将单个图像绘制到 alpha 蒙版时已经成功地做到了这一点,但是当像我们这里一样绘制一堆时,它完全无法给我正确的 alpha 值.

if (mFogOfWarRT == null)
{
    mFogOfWarRT = new RenderTarget2D(pGraphics.GraphicsDevice, MapSize, MapSize);
    pGraphics.GraphicsDevice.SetRenderTarget(mFogOfWarRT);
    //pGraphicsDevice.Clear(Color.Black);
}
else
{
    pGraphics.GraphicsDevice.SetRenderTarget(mFogOfWarRT);
}

pGraphicsDevice.Clear(Color.White);
pSpriteBatch.Begin();
BlendState lKeep = new BlendState();
lKeep.AlphaSourceBlend = Blend.One;
lKeep.AlphaDestinationBlend = Blend.Zero;
lKeep.ColorSourceBlend = Blend.Zero;
lKeep.ColorDestinationBlend = Blend.One;
lKeep.ColorBlendFunction = BlendFunction.Subtract;
lKeep.AlphaBlendFunction = BlendFunction.Add;
pGraphicsDevice.BlendState = lKeep;
pGraphicsDevice.BlendState.ColorWriteChannels = ColorWriteChannels.Alpha;

foreach (ClearArea lArea in mDrawQueue)
{
    pSpriteBatch.Draw(mAlphaMask, new Rectangle((int)lArea.X, lArea.Y, lArea.Diameter, lArea.Diameter), Color.White);
}
//pSpriteBatch.Draw(mDot, new Rectangle(0, 0, 100, 100), Color.White);
pSpriteBatch.End();

pGraphicsDevice.SetRenderTarget(null);

这是我的 alpha 蒙版绘制代码。当绘制到屏幕上时,我们得到一个白色方块,没有别的。

在下面我将我的“地图”绘制为 RGB,然后设置 A,并绘制我的 alphamask 纹理,但它失败了

pGraphicsDevice.SetRenderTarget(null);

// Draw minimap texture
pGraphicsDevice.Clear(Color.CornflowerBlue);
pGraphicsDevice.BlendState = lKeep;
pGraphicsDevice.BlendState.ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Blue | ColorWriteChannels.Green;

pSpriteBatch.Begin();
pSpriteBatch.Draw(mDot, new Rectangle(0, 0, 400, 400), Color.Blue);
pGraphicsDevice.BlendState.ColorWriteChannels = ColorWriteChannels.Alpha;
pSpriteBatch.Draw(mFogOfWarRT, Vector2.Zero, Color.White);

pSpriteBatch.End();

对此的任何帮助将不胜感激..

粘贴完整代码的bin

http://pastebin.com/KsEVaW0d

如果需要,可以提供结果的屏幕截图。

【问题讨论】:

    标签: c# .net xna monogame


    【解决方案1】:

    在我找到 Stencils 进行研究后,我决定 alpha 遮罩不是最好的方法。

    下面的代码通过写入模板缓冲区解决了这个问题。

    graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
    graphics.ApplyChanges();
    
    AlphaTestEffect alphaTestEffect = new AlphaTestEffect(pGraphicsDevice);
    alphaTestEffect.VertexColorEnabled = true;
    alphaTestEffect.DiffuseColor = Color.White.ToVector3();
    alphaTestEffect.AlphaFunction = CompareFunction.Equal;
    alphaTestEffect.ReferenceAlpha = 0;
    alphaTestEffect.World = Matrix.Identity;
    alphaTestEffect.View = Matrix.Identity;
    Matrix projection = Matrix.CreateOrthographicOffCenter(0, 400,400, 0, 0, 1);
    alphaTestEffect.Projection = projection;
            // Create fog of war mask
            if (mFogOfWarRT == null)
            {
                mFogOfWarRT = new RenderTarget2D(pGraphics.GraphicsDevice, MapSize, MapSize, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
                pGraphics.GraphicsDevice.SetRenderTarget(mFogOfWarRT);
    
            }
            else
            {
                pGraphics.GraphicsDevice.SetRenderTarget(mFogOfWarRT);
            }
            //important both stencil states be created in their own object, cannot modify once set for some reason.
            DepthStencilState lState = new DepthStencilState();
            lState.StencilEnable = true;
            lState.StencilFunction = CompareFunction.Always;
            lState.ReferenceStencil = 1;
            lState.StencilPass = StencilOperation.Replace;
            lState.DepthBufferEnable = false;
            pGraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil,
                                      new Color(0, 0, 0, 1), 0, 0);
            pSpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, lState, null, alphaTestEffect);
            foreach (ClearArea lArea in mDrawQueue)
            {
    //draw whatever you want "visible" anything in the texture with an alpha of 0 will be allowed to draw.
                pSpriteBatch.Draw(mAlphaMask, new Rectangle((int)lArea.X, lArea.Y, lArea.Diameter, lArea.Diameter), Color.White);
            }
    
            pSpriteBatch.End();
    
            // Draw minimap texture
            DepthStencilState lState2 = new DepthStencilState();
            lState2.StencilEnable = true;
            lState2.StencilFunction = CompareFunction.Equal;
            lState2.ReferenceStencil = 0;
            lState2.StencilPass = StencilOperation.Keep;
            lState2.DepthBufferEnable = false;
    
            pSpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, lState2, null);
            pSpriteBatch.Draw(mDot, new Rectangle(0, 0, 400, 400), Color.Black);
    
            pSpriteBatch.End();
            //done drawing to the render target
            pGraphicsDevice.SetRenderTarget(null);
            pGraphicsDevice.Clear(Color.Gray);
            pSpriteBatch.Begin();
            pSpriteBatch.Draw(mDot, new Rectangle(0, 0, 400, 400), Color.Blue);
            pSpriteBatch.Draw(mFogOfWarRT,Vector2.Zero,Color.White);
            pSpriteBatch.End();
    

    【讨论】:

    • 以后试试这个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多