【问题标题】:How do I create an alpha mask which is rewritten when added to?如何创建添加时重写的 alpha 蒙版?
【发布时间】:2013-07-23 01:09:12
【问题描述】:

我正在尝试在应用程序中创建类似雾的效果,其中纹理(在上面的示例中为白色)在精灵周围变得透明(显示下面的黑色纹理),并且密度渐变远离它们的中心。然而,每当我向 alpha 蒙版添加一个新圆圈时,它都会覆盖之前添加到蒙版纹理中的内容,从而产生如上图所示的不和谐效果。我一直在尝试为蒙版纹理添加新内容,以便与之前添加的内容很好地融合,但我不知道该怎么做。

我尝试过为我的遮罩创建一个遮罩以与之混合,但它总是什么都不显示,或者使用我的 alpha 着色器 fx 文件绘制到我的 alpha 遮罩(这会产生一些非常奇怪的视觉效果)

p>

如何将添加到 alpha 蒙版的内容混合在一起,以免它们相互覆盖?

非常感谢任何帮助。

-------------代码:-------------

Alpha 掩码的更新是在这个方法中完成的:

public void createLightSource(Vector2 RemovePosition, Texture2D circleTexture)
    {

            // Create a render target, which we will draw to instead of the screen
            RenderTarget2D target = new RenderTarget2D(graphics.GraphicsDevice, mainTexture.Width, mainTexture.Height);

            // set the RenderTarget2D as the target for all future Draw calls untill we say otherwise
            graphics.GraphicsDevice.SetRenderTarget(target);

            // start our batch as usual..
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);

            // start with a transparent canvas
            graphics.GraphicsDevice.Clear(Color.Transparent);

            // add in the previously drawn dots from the current alpha map.
            spriteBatch.Draw(alphaMask, new Vector2(0, 0), null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 1f);

            // add a new dot to the map. 
            play.game.spriteBatch.Draw(circleTexture,
                    new Vector2((float)(RemovePosition.X - mainTexture.x), (float)(RemovePosition.Y - mainTexture.y)),
                    null,
                    Color.White,
                    0f,
                    new Vector2(circleTexture.Width / 2f, circleTexture.Height / 2f),
                    1f,
                    SpriteEffects.None,
                    1f);

            // end the draw call
            spriteBatch.End();

            // start drawing to the screen again
            graphics.GraphicsDevice.SetRenderTarget(null);

            // set our Texture2D Alpha Mask to equal the current render target (the new mask).
            // RenderTarget2D can be cast to a Texture2D without a problem
            alphaMask = target;
        }

主纹理的绘制是在这个方法中完成的:

public void mainTextureDraw()
        {
            //alpha shader is the fx file (below)
            alphaShader.Parameters["MaskTexture"]
                                .SetValue(alphaMask);
        // start a spritebatch for our effect
        spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend,
            null, null, null, alphaShader);

        play.game.spriteBatch.Draw(mainTexture,
            position,
            null, Color.White, 0f,
            new Vector2(0, 0),
            1f, SpriteEffects.None, 1f);

        spriteBatch.End();
    }

以及fx文件中的重要方法:

float4 PixelShaderFunction(float2 inCoord: TEXCOORD0) : COLOR
{
    // we retrieve the color in the original texture at 
    // the current coordinate remember that this function 
    // is run on every pixel in our texture.
    float4 color = tex2D(mainTexture, inCoord);

    // Since we are using a black and white mask the black 
    // area will have a value of 0 and the white areas will 
    // have a value of 255. Hence the black areas will subtract
    // nothing from our original color, and the white areas of
    // our mask will subtract all color from the color.
    color.rgba = color.rgba - tex2D(alphaMask, inCoord).r;

    // return the new color of the pixel.
    return color;
}

【问题讨论】:

    标签: c# xna


    【解决方案1】:

    我不能 100% 确定从哪个方向着手,因为我不知道实际结果应该是什么样子。以下是我所说的几个例子。

    https://plus.google.com/photos/117280483756658540406/albums/5903487202722042913?authkey=CK-_kZvo2Iqy9wE

    但是,我认为最好的方法是查看PixelShaderFunction。您已经在color 中获得了现有纹理,并且您正在使用tex2D() 的红色组件。我想知道它是否是一种有用的方法是采用 tex2D().r 并查看它是否大于 color.r,如果是,则使用颜色的值而不是减去 tex2D()。

    基本上,您有一个想要保持的阈值。您需要在像素上测试您的条件,然后决定如何以及是否要更改它。

    【讨论】:

    • 第二个:lh3.googleusercontent.com/-jPUqW89ZRk4/Ue1mViaBgTI/AAAAAAAAApA/… 绝对是我要找的。我已经设法用 BlendState.Additive 得到了一些接近的东西,但是尝试了你上面建议的东西,它只是让整个屏幕完全变白了。我能看到第二种状态的解决方案吗?
    • i.imgur.com/F8DhKZC.png 这是我使用混合状态添加剂得到的结果,但正如你所见,仍然有白色的日冕扩散到另一个圆圈中。
    • 嗯...我用 Photoshop 制作了这两个。第二个使用 Multiply,您可以使用 (color1.r * color2.r)/255
    猜你喜欢
    • 1970-01-01
    • 2011-03-22
    • 2011-09-18
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 2014-02-10
    相关资源
    最近更新 更多