3

我想做一件简单的事情:使用 alpha chanel 混合将 2d 纹理渲染到 2d 渲染目标。

所以我创建了我的渲染目标:

renderTarget = new RenderTarget2D(m_graphicsDevice, 200, 200);

然后我创建我的纹理:

texture = new Texture2D(_device, 1, 1, false, SurfaceFormat.Color);
Color clr = Color.Red;
// set half transparency on my texture
clr.A = 128;
Color[] bitmap = new Color[1] {clr};
texture.SetData(bitmap);

然后我清除我的渲染目标白色,并在渲染目标中绘制我的纹理两次,具有良好的比例,并对颜色和 alpha 通道进行乘法运算。

graphicsDevice.SetRenderTarget(renderTarget);
graphicsDevice.Clear(Color.White);

BlendState myState = new BlendState();
// multiplicative blending on color
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.SourceColor;
// multiplicative blending on alpha
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;

spriteBatch.Begin(SpriteSortMode.Immediate, myState);
// draw my texture twice, with an overlaping part
spriteBatch.Draw(texture, new Vector2(0, 0), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.Draw(texture, new Vector2(50, 50), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.End();
graphicsDevice.SetRenderTarget(null);

我在屏幕上绘制了这个渲染目标,背景为绿色,渲染状态为非预乘渲染状态,因此纹理中的 alpha 值被应用为透明度。

graphicsDevice.Clear(Color.Green);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
spriteBatch.Draw(renderTarget, Vector2.zero, Color.White);
spriteBatch.End();

结果如预期:

  • 在渲染目标中,仅适用于属于一个纹理的像素:

    • red chanel = 纹理 red chanel (1) * 渲染目标 red chanel (1) = 1
    • 绿色和蓝色 chanel = 纹理 chanel (0) * 渲染目标 chanel = 0
    • alpha chanel = 纹理 alpha (0.5) * 渲染目标 alpha (1) = 0.5
    • 由于 alpha 透明度设置为 0.5(1/2 红色 + 1/2 绿色),因此在绿色背景上方绘制的此纹理呈现棕色
  • 在渲染目标中,用于重叠像素(因此上述计算应用了两次)

    • red chanel = 纹理 red chanel (1) * 纹理 red chanel (1) * 渲染目标 red chanel (1) = 1
    • 绿色和蓝色 chanel = 纹理 chanel (0) * 纹理 chanel (0) * 渲染目标 chanel = 0
    • alpha chanel = 纹理 alpha (0.5) * 纹理 alpha (0.5) * 渲染目标 alpha (1) = 0.25
    • 由于 alpha 值为 0.25(1/4 红色 + 3/4 绿色),这个在绿色背景上方绘制的纹理呈现出近乎绿色的颜色

现在,如果我将渲染状态更改为只应用纹理的 alpha 通道,而不是让颜色相乘:

BlendState myState = new BlendState();
// texture color is ignored, dest color remain unchanged
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.One;
// alpha chanel are still multiplied
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;

我应该得到的是:

  • 在渲染目标中,仅适用于属于一个纹理的像素:

    • red chanel = 0 * 纹理 red chanel (1) + 1 * 渲染目标 red chanel (1) = 1
    • 绿色和蓝色 chanel = 0 * 纹理 chanel (0) + 1 * 渲染目标 chanel (1) = 1
    • alpha chanel = 纹理 alpha (0.5) * 渲染目标 alpha (1) = 0.5
    • 并且这个在绿色背景上方绘制的纹理应该是浅绿色(1/2 白色 + 1/2 绿色)
  • 在渲染目标中,用于重叠像素(因此上述计算应用了两次)

    • 红色香奈儿 = 1
    • 绿色和蓝色香奈儿 = 1
    • alpha chanel = 纹理 alpha (0.5) * 纹理 alpha (0.5) * 渲染目标 alpha (1) = 0.25
    • 并且这个在绿色背景之上绘制的纹理应该会产生更强烈的绿色(0.25 * 白色 + 0.75 * 绿色)

我得到的是纯白色的纹理......

为什么当我不混合颜色时,我的渲染目标中的 alpha 混合计算停止工作?我的目标是仅在 alpha chanel 上进行计算,而不获取纹理颜色。我怎样才能做到这一点 ?

谢谢

4

1 回答 1

0

你说(我得到的是纯白色纹理......)但我得到: 在此处输入图像描述

于 2014-03-18T11:59:32.593 回答