如何使用SharpDX Toolkit绘制透明3D对象?

时间:2014-10-30 06:49:19

标签: c# direct3d sharpdx direct3d11

我正在使用SharpDX和SharpDX Toolkit绘制简单的3D形状的应用程序,Geometrics.Desktop示例在入门时非常有用。现在我试图让一些形状变得透明,并且为了简单起见,我只是试图让那个样本中的茶壶模型显得透明(也许半透明会更精确)。

对于那些不熟悉Geometrics.Desktop示例的人,它会在3D中绘制一些简单的原始几何形状。作为一个示例应用程序,它非常简单,因此它是一个非常好的暂存器,用于试验SharpDX" Toolkit"的3D功能。库。

我已将此添加到LoadContent方法(在启动时运行一次),以便准备Direct3D进行混合:

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

我已经设置了深度模板,如下所示:

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

在Draw方法中(以帧速率运行并迭代一小部分3D模型,绘制每个模型),我已添加下面的代码。它将茶壶移动到视口的中心,并使其足够大以遮挡其他一些物体。茶壶是最后绘制的,所以其他型号已经被渲染,所以我真的希望这会在它们上面画一个半透明的茶壶:

// 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);

(评论和对Draw的最终调用是原始示例代码的一部分。)

但是,结果是其他对象中的一个大的不透明茶壶:

enter image description here

要使茶壶透明,我需要做些什么?

我错过了什么,或者我错误配置了混合状态?

为了完整起见,我还尝试使用alpha通道为50%的图像对我的对象进行纹理处理,但仍然会产生不透明的对象。

提前感谢您的任何帮助!

1 个答案:

答案 0 :(得分:2)

我将SourceAlphaBlend和DestinationAlphaBlend设置为Zero,它可以正常工作。除了那些状态描述对我来说是正确的。另外,确保在blendstate中禁用AlphaToCoverage,否则你会有其他的行为很奇怪。

还要确保在绘制每个帧之前设置BlendState。