XNA 4.0中的设备AlphaBlend状态

时间:2011-06-10 14:52:39

标签: xna alphablending

我在使图形设备上的BlendState正常工作并正确显示alpha混合时遇到问题。

Render Output

在某些情况下,您可以通过其他树叶看到树叶,在其他情况下,您无法看到。树干也总是模糊不清。

我尝试了很多不同的设置BlendState的组合。目前它看起来像这样:

        GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        //GraphicsDevice.BlendState = BlendState.AlphaBlend;
        GraphicsDevice.BlendState = new BlendState()
        {
            AlphaBlendFunction = BlendFunction.Add,
            AlphaDestinationBlend = Blend.InverseSourceAlpha,
            AlphaSourceBlend = Blend.One,
            BlendFactor = new Color(1.0F, 1.0F, 1.0F, 1.0F),
            ColorBlendFunction = BlendFunction.Add,
            ColorDestinationBlend = Blend.InverseSourceAlpha,
            ColorSourceBlend = Blend.One,
            ColorWriteChannels = ColorWriteChannels.All,
            ColorWriteChannels1 = ColorWriteChannels.All,
            ColorWriteChannels2 = ColorWriteChannels.All,
            ColorWriteChannels3 = ColorWriteChannels.All,
            MultiSampleMask = -1
        };

着色器代码如下:

float alpha = 1.0F; if(HasAlphaTexture)     alpha = tex2D(AlphaSampler,IN.UV).xyz;

// ... //确定颜色值等 ///...

返回float4(result.xyz,alpha);

我正在使用的地图如下所示: Opacity Map Diffuse/Color Map

1 个答案:

答案 0 :(得分:4)

首先,您要对几何体进行排序或使用alpha测试,因为您无法将基于Z缓冲区(又称:深度缓冲区)的渲染与透明度相结合。没有办法“混合”一个Z缓冲区值 - 所以它总是使用最高值,阻止背后的东西,即使你渲染的颜色是透明的。

查看this article以获得解释(and this one for a word on quality)。这将解决您的几何问题有时不会出现在某些透明几何体后面。

您的混合状态的问题在于您正在使用预乘混合与尚未预乘的数据。

See this article for an explanation of premultiplied alpha。那是made the default in XNA 4.0

当你预乘时,你可以在混合之前将你的颜色值(RGB)缩放你的alpha值(即:你乘以它们)(即: pre )。

所以有两种可能的解决方案:你可以使用BlendState.NonPremultiplied。但预乘会有好处(正如在aritcle中所解释的那样),所以更好的解决方案是在你的着色器中执行乘法,如下所示:

return float4(result.xyz * alpha, alpha);

当然,如果可能的话,最好只使用带有alpha通道的单个纹理。如果您无法使用艺术工具组合Alpha通道,则可以使用XNA内容管道组合两个纹理并在构建期间执行预乘。默认情况下,默认的Content Pipeline纹理导入器会进行预乘。