【问题标题】:WPF semi-transparent mesh issueWPF半透明网格问题
【发布时间】:2018-02-15 09:24:12
【问题描述】:

我有一个网状截头金字塔堆叠在一起。

我的目标是反转它,把它变成一个球体近似值。为此,我画了完全相同的东西,但 Z 轴颠倒了。它可以工作,只是背面是半透明的。

这里我设置了brush.Opacity = .3;,让半透明问题更加明显。

不幸的是,我在该主题上所能找到的只是未能为单独的网格元素启用透明度,而不是删除它。什么可能导致问题,我该如何解决?这是我绘制网格的代码摘录:

public void Approximate()
{
    group.Children.Clear();
    SolidColorBrush brush = new SolidColorBrush(Colors.Blue);
    DiffuseMaterial material = new DiffuseMaterial(brush);

    [...]

    for(int level = 0; level < level_number; level++)
    {
    GeometryModel3D model_front = new GeometryModel3D();
    model_front.Material = material;

    GeometryModel3D model_back = new GeometryModel3D();
    model_back.Material = material;

    [...]

    TruncatedPyramid pyramid1 = new TruncatedPyramid(bottom_points, top_points);
    pyramid1.Draw(model_front);
    group.Children.Add(model_front);

    TruncatedPyramid pyramid2 = new TruncatedPyramid(bottom_points, reverse_points);
    pyramid2.Draw(model_back);
    group.Children.Add(model_back);
    }
}

我在其中设置了窗口:

    <Viewport3D Name="myViewport" Margin="0,94,0,0" >

        <Viewport3D.Camera>
            <PerspectiveCamera  Position="10,10,10" LookDirection="-2,-2,-2" UpDirection="0,1,0" />
        </Viewport3D.Camera>

        <ModelVisual3D>
            <ModelVisual3D.Content>
                <DirectionalLight x:Name = "dirLightMain" Direction = "-1,-1,-1">
                </DirectionalLight>
            </ModelVisual3D.Content>
        </ModelVisual3D>

        <ModelVisual3D x:Name = "Wedge">
            <ModelVisual3D.Content>
                <Model3DGroup x:Name="group">

                </Model3DGroup>
            </ModelVisual3D.Content>

            <ModelVisual3D.Transform>
            [...]
            </ModelVisual3D.Transform>

        </ModelVisual3D>
    </Viewport3D>

我删除的代码确实可以正常工作,并且似乎与问题无关(计算网格点的函数和负责旋转组的类)

我的猜测是正面具有某种与透明度相关的质量,而背面仍然没有,尽管使用相同的画笔绘制,但我对 WPF 不够熟悉,无法找到它。

【问题讨论】:

    标签: c# wpf graphics 3d transparency


    【解决方案1】:

    我不使用 WPF 也不使用 C#,因此无法帮助您进行实际实施。反正先看:

    我认为您的问题是您的三角形渲染顺序错误。当你有更多的相交层时,要像上面的链接那样以独立的方式做到这一点并不容易。然而,有更多的选择来处理这个问题:

    1. Z 排序

      您只需收集所有要渲染的三角形列表,并按与相机的距离对其进行排序。由于您的网格是自相交的,您需要将所有相交的面划分为不相交的面,这是一件令人讨厌的事情,而且很难正确实施。完成后,按从前到后的顺序渲染三角形...

    2. (返回)光线追踪

      将您的 ender 更改为光线追踪技术。这些本机正确处理透明度。举个例子:

    3. 修复网格

      您可以使用计算几何来修复您的网格,方法是从网格中移除所有内部面。但自相交网格并不容易。完成后,您可以使用第一个链接中的方法。

    对于复杂的网格,我会选择 #2,但如果您需要速度,那么 #3 是最好的选择。

    【讨论】:

      【解决方案2】:

      在 Windows Presentation Foundation 中渲染半透明 3d 对象时出现的主要问题与错误的 z 缓冲区遮挡有关。具体来说,当渲染透明表面或多边形时,它会设置 z 缓冲区深度值以阻止其后面的对象被渲染,即使它们应该通过透明层显示。

      在带有 C# 的 WPF 中,z 缓冲区不可访问。因此,在透明渲染期间不能禁用它。相反,我们必须最后渲染透明对象,以便它们在场景的其余部分上分层,并且它们后面的对象可以显示出来。

      例如:

      qModelGroup.Children.Add(qBackGeometry);
      qModelGroup.Children.Add(qOuterGeometry);
      

      请注意,透明的“外部几何”图层是最后添加的。 See the reference for more details.

      更新:

      另一种方法是在 WPF 中使用 EmissiveMaterialSpecularMaterial 而不是 DiffuseMaterial。这对我来说是一个复杂的问题。 See this post for more.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-25
        • 2011-09-15
        • 2015-11-12
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多