gpt4 book ai didi

c# - 如何处理 WPF 3D 中的漫反射 Material 透明度?

转载 作者:行者123 更新时间:2023-12-04 16:05:34 27 4
gpt4 key购买 nike

我有一个场景,其中多个模型具有平面和具有透明度的漫反射 Material 。

这些模型有时会由于摄像机角度的变化而重叠,然后这些模型无法正确渲染,如下图所示,蓝色透明面隐藏了红色立方体的一部分:

blue transparent face hides part of the red cube

经过一些研究,我发现在所有情况下都需要深度排序才能正确渲染模型。

是否有任何图书馆已经处理过这个问题,例如通过实现 Newell 算法还是有人知道其他解决方案?

最佳答案

我发现了一种基于模型边界框的排序算法,该算法来自一个非常古老的 Microsoft 博客,该博客已无法访问。

下面是对代码进行一些更改以直接传递 ModelVisual3D 实例的类:

// original class taken from
// https://web.archive.org/web/20071201135137/http://blogs.msdn.com/pantal/archive/2007/07/23/sorting-for-wpf-3d-transparency.aspx
public static class SceneSortingHelper
{
/// <summary>
/// Sort Modelgroups in farthest to closest order, to enable transparency
/// Should be applied whenever the scene is significantly re-oriented
/// </summary>
public static void AlphaSort(Point3D CameraPosition,
System.Collections.Generic.List<System.Windows.Media.Media3D.ModelVisual3D> ModelVisual3Ds, Transform3D WorldTransform)
{
ArrayList list = new ArrayList();
foreach (var m in ModelVisual3Ds)
{
var location =
WorldTransform.TransformBounds(
m.Transform.TransformBounds(
m.Content.Transform.TransformBounds(
m.Content.Bounds
)
)
).Location;

double distance = Point3D.Subtract(CameraPosition, location).Length;
list.Add(new ModelVisual3DDistance(distance, m));
}
list.Sort(new DistanceComparer(SortDirection.FarToNear));
ModelVisual3Ds.Clear();
foreach (ModelVisual3DDistance d in list)
{
ModelVisual3Ds.Add(d.modelVisual3D);
}
}

private class ModelVisual3DDistance
{
public ModelVisual3DDistance(double distance, ModelVisual3D modelVisual3D)
{
this.distance = distance;
this.modelVisual3D = modelVisual3D;
}

public double distance;
public ModelVisual3D modelVisual3D;
}

private enum SortDirection
{
NearToFar,
FarToNear
}

private class DistanceComparer : IComparer
{
public DistanceComparer(SortDirection sortDirection)
{
_sortDirection = sortDirection;
}

int IComparer.Compare(Object o1, Object o2)
{
double x1 = ((ModelVisual3DDistance)o1).distance;
double x2 = ((ModelVisual3DDistance)o2).distance;

if (_sortDirection == SortDirection.FarToNear)
{
if (x1 > x2)
return -1;
else
if (x1 < x2)
return 1;
else
return 0;
}
else
{
if (x1 > x2)
return 1;
else
if (x1 < x2)
return -1;
else
return 0;
}
}

private SortDirection _sortDirection;
}
}

我将上述类与以下 Viewport3D 扩展方法结合使用 ...

namespace Viewport3DExtensions
{
public static class Implementation
{
public static void AlphaSortModels(this System.Windows.Controls.Viewport3D viewport3D)
{
var projectionCamera = viewport3D.Camera as System.Windows.Media.Media3D.ProjectionCamera;

if (projectionCamera != null)
{
var modelVisual3Ds = new System.Collections.Generic.List<System.Windows.Media.Media3D.ModelVisual3D>();

foreach (var c in viewport3D.Children)
{
var m = c as System.Windows.Media.Media3D.ModelVisual3D;

if (m != null)
modelVisual3Ds.Add(m);
}

// note:
// the following method works well most of the time but sometimes the sort is wrong as the sort is simply based on model bounds,
// to get rid of artifacts we would need something like binary space partitioning
SceneHelper.SceneSortingHelper.AlphaSort(
projectionCamera.Position,
modelVisual3Ds,
new System.Windows.Media.Media3D.Transform3DGroup()
);

viewport3D.Children.Clear();

foreach (var c in modelVisual3Ds)
viewport3D.Children.Add(c);
}
}
}
}

...像这样

System.Windows.Controls.Viewport3D scene;  
...
scene.AlphaSortModels();

场景现在看起来不错:

Transparency displayed correctly

关于c# - 如何处理 WPF 3D 中的漫反射 Material 透明度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48924505/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com