2011-06-10 64 views
0

我在图形设备上的BlendState正常工作并正确显示Alpha混合时遇到问题。XNA 4.0中的设备AlphaBlend状态

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 
     }; 

的着色器代码如下:

浮子阿尔法= 1.0F; if(HasAlphaTexture) alpha = tex2D(AlphaSampler,IN.UV).xyz;

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

返回个float4(result.xyz,阿尔法);

我使用的是这种情况的地图如下所示: Opacity Map Diffuse/Color Map

回答

4

首先,你想要么排序几何体或使用alpha测试,因为你不能结合Z缓存的(又名:深度缓冲)基于透明度的渲染。没有办法“混合”一个Z-buffer值 - 所以它总是使用最高值,即使当你渲染的颜色是透明的时候也会阻挡背后的东西。

看一看this articleand this one for a word on quality)。这将解决你的几何问题,有时不会出现在某个透明几何体的背后。

混合状态的问题在于,您正在使用未预乘的数据进行预乘混合。

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

当你预乘,你通过你的alpha值扩展您的颜色值(RGB)(即:你他们),然后混合它们(即:)。

所以有两种可能的解决方案:您可以使用BlendState.NonPremultiplied。但左乘具有益处(如在该aritcle解释),因此更好的解决方案是在着色器像这样执行乘法运算:

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

当然,优选的是,简单地使用单个纹理的α信道如果这是可能的话。如果您无法使用您的绘画工具合并Alpha通道,则可以使用XNA内容管道将两个纹理合并,并在构建期间执行预乘。默认情况下,默认的内容管道纹理导入器执行预乘。

+0

谢谢安德鲁。非常感激。 – helloserve 2011-06-11 11:44:19