【问题标题】:How can I draw a transparent 3D object with the SharpDX Toolkit?如何使用 SharpDX Toolkit 绘制透明的 3D 对象?
【发布时间】:2014-10-30 06:49:18
【问题描述】:

我正在开发一个使用 SharpDX 和 SharpDX 工具包绘制简单 3D 形状的应用程序,Geometrics.Desktop 示例对入门非常有帮助。现在我正在尝试让一些形状透明,为了简单起见,我只是想让该示例中的茶壶模型看起来透明(也许半透明会更精确)。

对于那些不熟悉 Geometrics.Desktop 示例的人,它会在 3D 中绘制一些简单的原始几何形状。作为一个示例应用程序,它非常简单,因此它是一个很好的暂存器,可用于试验 SharpDX“工具包”库的 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 的最终调用是原始示例代码的一部分。)

但是很可惜,结果是在其他物体中出现了一个大不透明茶壶:

我需要怎么做才能让那个茶壶变得透明?

是我遗漏了什么,还是我错误地配置了混合状态?

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

提前感谢您的帮助!

【问题讨论】:

  • 你使用的是direct3d11吗?因为没有primitive,只有context
  • 是的,我使用的是 D3D11,但我使用的是几何意义上的“原始”一词 - 立方体、球体、圆柱体等。 SharpDX 工具包中的类可以轻松绘制此类形状,并且易于使用。大多。让它们变得透明非常困难。

标签: c# direct3d sharpdx direct3d11


【解决方案1】:

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

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

【讨论】:

  • 您确定这些是您所做的唯一更改吗?我刚刚对我的测试应用程序进行了这些更改,茶壶仍然不透明。不过,您的 Alpha 版工作给了我很大的希望!
  • 您在使用 Visual Studio 吗?如果是这样,请使用“Debug->Graphics->Start Diagnostrics”工具在运行时调试 D3D11 设备和状态。也许一个状态没有正确绑定。
  • 我有一个透明的茶壶!诊断工具中出现的blendstate和我在代码中配置的不一样。我把它移到了渲染循环中,透明度现在可以工作了。当然,我想将其移出渲染循环,但接下来我会研究。
  • 实际上似乎我必须在每次渲染之前执行此操作,因为仅在第一次渲染时执行此操作是不够的。我认为问题出在我使用的设置上,但真正的问题是我没有经常应用这些设置。 :)
  • 这不是典型的 directx 行为。除非您使用延迟上下文、命令列表等,否则状态应该是持久的。也许这是我不熟悉的sharpdx工具包中的一些怪癖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多