How can I draw a transparent 3D object with the SharpDX Toolkit?

雨燕双飞 提交于 2019-12-10 13:31:33

问题


I'm working on an application that uses SharpDX and the SharpDX Toolkit to draw simple 3D shapes, and the Geometrics.Desktop sample was very helpful in getting started. Now I'm trying to make some shapes transparent, and to keep things simple I'm just trying to make the teapot model in in that sample appear transparent (perhaps translucent would be more precise).

For those not familiar with the Geometrics.Desktop sample, it draws a few simple primitive geometric shapes in 3D. Being a sample app, it's pretty simple, so it makes a pretty good scratchpad for experimenting with the 3D features of the SharpDX "Toolkit" library.

I've added this to the LoadContent method (which runs once at startup time), in an effort to prepare Direct3D to do blending:

        var blendStateDescription = new BlendStateDescription();

        blendStateDescription.AlphaToCoverageEnable = false;

        blendStateDescription.RenderTarget[0].IsBlendEnabled = true;
        blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha;
        blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;
        blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add;
        blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero;
        blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
        blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;
        blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

        var blendState = SharpDX.Toolkit.Graphics.BlendState.New(this.GraphicsDevice, blendStateDescription);
        this.GraphicsDevice.SetBlendState(blendState);

I have set up the depth stencil as follows:

        var depthDisabledStencilDesc = new DepthStencilStateDescription()
        {
            IsDepthEnabled = false,
            DepthWriteMask = DepthWriteMask.All,
            DepthComparison = Comparison.Less,
            IsStencilEnabled = true,
            StencilReadMask = 0xFF,
            StencilWriteMask = 0xFF,
            // Stencil operation if pixel front-facing.
            FrontFace = new DepthStencilOperationDescription()
            {
                FailOperation = StencilOperation.Keep,
                DepthFailOperation = StencilOperation.Increment,
                PassOperation = StencilOperation.Keep,
                Comparison = Comparison.Always
            },
            // Stencil operation if pixel is back-facing.
            BackFace = new DepthStencilOperationDescription()
            {
                FailOperation = StencilOperation.Keep,
                DepthFailOperation = StencilOperation.Decrement,
                PassOperation = StencilOperation.Keep,
                Comparison = Comparison.Always
            }
        };

        // Create the depth stencil state.
        var depthDisabledStencilState = SharpDX.Toolkit.Graphics.DepthStencilState.New(this.GraphicsDevice, depthDisabledStencilDesc);
        //turn z-buffer off
        this.GraphicsDevice.SetDepthStencilState(depthDisabledStencilState, 1);

And in the Draw method (which run at the frame rate and iterates through a small array of 3D models, drawing each one), I've added the code below. It moves the teapot to the center of the viewport and make it large enough to occlude some of the other objects. The teapot is drawn last, so the other models have already been rendered, so I was really hoping this would draw a translucent teapot on top of them:

// Draw the primitive using BasicEffect
if (i == 6)
{
    basicEffect.Alpha = 0.5f;
    basicEffect.World *= Matrix.Translation(-x, -y, 0);
    basicEffect.World *= Matrix.Scaling(3);
}
else
{
    basicEffect.Alpha = 1;
}

primitive.Draw(basicEffect);

(The comment and the final call to Draw were part of the original sample code.)

But alas, the result is a big opaque teapot among the other objects:

What do I need to do to make that teapot transparent?

Am I missing something, or have I misconfigured the blend state?

And just for completeness, I have also tried texturing my objects with images that have the alpha channel at 50%, but that still results in opaque objects.

Thanks in advance for any assistance!


回答1:


I have SourceAlphaBlend and DestinationAlphaBlend set to Zero and it works as it should. Other than those the state description looks correct to me. Also, make sure that AlphaToCoverage is disabled in the blendstate or else you'll have other things acting weird.

Also make sure that you set the BlendState before drawing each frame.



来源:https://stackoverflow.com/questions/26646715/how-can-i-draw-a-transparent-3d-object-with-the-sharpdx-toolkit

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