开发者

Device AlphaBlend state in XNA 4.0

I'm having a problem getting the BlendState on the graphics device to work properly and display the alpha blending correctly.

Device AlphaBlend state in XNA 4.0

In some cases you can see the leaves through other leaves, in other cases you cannot. And the trunk is also always obscured.

I've tried so many different combinations of setting up the BlendState. At the moment it looks like this:

        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,
            ColorDestina开发者_如何学JAVAtionBlend = Blend.InverseSourceAlpha,
            ColorSourceBlend = Blend.One,
            ColorWriteChannels = ColorWriteChannels.All,
            ColorWriteChannels1 = ColorWriteChannels.All,
            ColorWriteChannels2 = ColorWriteChannels.All,
            ColorWriteChannels3 = ColorWriteChannels.All,
            MultiSampleMask = -1
        };

The shader code are as follows:

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

//... //determine color values etc.. ///...

return float4(result.xyz,alpha);

The maps I'm using for this looks like the following:

Device AlphaBlend state in XNA 4.0

Device AlphaBlend state in XNA 4.0


First of all you want to either sort your geometry or use alpha-testing, because you cannot combine Z-buffer (aka: depth-buffer) based rendering with transparency. There is no way to "blend" a Z-buffer value - so it always uses the topmost value, blocking off the things behind, even when the colour you are rendering is transparent.

Take a look this article for an explanation (and this one for a word on quality). This will solve your problem of geometry sometimes not showing up behind some transparent geometry.

The problem with your blend state is that you're using premultiplied blending with data that has not been premultiplied.

See this article for an explanation of premultiplied alpha. It was made the default in XNA 4.0.

When you premultiply, you scale your colour values (RGB) by your alpha value (ie: you multiply them) before you blend them (ie: pre).

So there are two possible solutions: you could use BlendState.NonPremultiplied. But premultiplying has benefits (as explained in that aritcle), so the better solution is to perform the multiplication in your shader like so:

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

Of course, it is preferable to simply use a single texture with an alpha channel, if that is at all possible. If you can't combine the alpha channel using your art tools, you could use the XNA Content Pipeline to combine the two textures and perform premultiplication during your build. The default Content Pipeline texture importer does premultiplication by default.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜