Device AlphaBlend state in XNA 4.0

假如想象 提交于 2019-12-02 20:06:44

问题


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

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,
            ColorDestinationBlend = 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:


回答1:


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.



来源:https://stackoverflow.com/questions/6308079/device-alphablend-state-in-xna-4-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!