我有一个截断的金字塔网格堆叠在一起。
我的目标是扭转它,将其变成球体近似值。为此,我绘制完全相同的东西,但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足以找到它。
答案 0 :(得分:1)
我不使用 WPF ,也不使用 C#,因此无法帮助您实际实施。无论如何首先看到:
我认为您的问题是三角形渲染的错误顺序。当您获得更多交叉图层时,这很难按照上面的链接顺序进行。但是,如何处理这个问题还有更多选择:
<强> Z分类强>
您只需收集所有三角形的列表进行渲染,并按照距摄像机的距离对其进行排序。由于你的网格是自相交的,你需要将所有相交的面分成不相交的面,这是令人讨厌的事情并且很难正确实现。完成后,按顺序渲染三角形......
(返回)光线追踪
将您的ender更改为光线跟踪技术。这些本身正确处理透明度。这是一个例子:
修复网格
您可以通过从网格中移除所有内部面来使用计算几何来修复网格。但是自相交网格并不容易。完成后,您可以在第一个链接中使用该方法。
对于复杂的网格,我会选择#2 ,但如果你需要速度,那么#3 就是这样。
答案 1 :(得分:0)
在Windows Presentation Foundation中渲染半透明3d对象时出现的主要问题与错误的z缓冲区遮挡有关。具体来说,当渲染透明表面或多边形时,它会设置z缓冲区深度值,以阻止渲染位于其后面的对象,即使它们应在透明层中显示。
在带有C#的WPF中,无法访问z缓冲区。因此,不能在透明渲染期间禁用它。取而代之的是,我们必须最后渲染透明对象,以使它们在场景的其余部分上分层,并且透明对象后面的对象可以显示出来。
例如:
qModelGroup.Children.Add(qBackGeometry);
qModelGroup.Children.Add(qOuterGeometry);
请注意,最后添加了透明的“外部几何”层。 See the reference for more details.
另一种方法是在WPF中使用EmissiveMaterial
或SpecularMaterial
代替DiffuseMaterial
。这对我来说是一个复杂的问题。 See this post for more.