我的程序显示一个静态场景,其中包含3d模型(例如树)在不同位置的多个实例。这个模型可能很“重”,在50000到100000个三角形之间,性能随着实例数量的增加而迅速降低(超过10个实例的性能是不可接受的)。
我的第一个代码,没有优化,看起来像这样:
public partial class Vue3D : Window
{
public ModelVisual3D modelVisual = new ModelVisual3D();
public Model3DGroup model3DGroup = new Model3DGroup();
public Vue3D()
{
...
modelVisual.Content = model3DGroup;
view1.Children.Add(modelVisual); // view1 = viewport3D
...
BuildScene();
}
void BuildScene()
{
Model3DGroup model = GetModel("tree");
foreach (Point3D pnt in <point collection>)
{
Model3DGroup modelClone = model.Clone();
Transform3DGroup tg = new Transform3DGroup();
tg.Children.Add(new TranslateTransform3D(pnt.X, pnt.Y, pnt.Z>));
modelClone.Transform = tg;
model3DGroup.Children.Add(modelClone);
}
}
}
对于每个实例,我克隆完整的模型,并在转换后将克隆添加到视口。 假设树模型包含2个GeometryModel3D: {mesh1(20000个三角形),texture1}和{mesh2(40000个三角形),texture2}。 如果我显示10棵树,我正在添加20 GeometryModel3D。
由于所有这些实例共享相同的2个纹理,我认为我可以通过仅创建2个GeometryModel3D来加速:一个所有三角形与texture1相关联,一个所有三角形与texture2相关联。这就是我在这段代码中尝试的内容:
void BuildScene()
{
List<Transform3DGroup>> listTg = new List<Transform3DGroup>();
foreach (Point3D pnt in <point collection>)
{
Transform3DGroup tg = new Transform3DGroup();
tg.Children.Add(new TranslateTransform3D(pnt.X, pnt.Y, pnt.Z>));
listTg.Add(tg);
}
Model3DGroup model = GetModel("tree");
foreach (GeometryModel3D gmodel in model.Children)
{
MeshGeometry3D mesh = gmodel.Geometry as MeshGeometry3D;
GeometryModel3D newgmodel = new GeometryModel3D();
newgmodel.Material = gmodel.Material;
newgmodel.BackMaterial = gmodel.BackMaterial;
MeshGeometry3D newmesh = new MeshGeometry3D();
newgmodel.Geometry = newmesh;
foreach (Transform3DGroup tg in listTg)
{
foreach (int indice in mesh.TriangleIndices)
newmesh.TriangleIndices.Add(indice + newmesh.Positions.Count);
foreach (Point3D p3 in mesh.Positions)
newmesh.Positions.Add(tg.Transform(p3));
if (mesh.TextureCoordinates != null)
{
foreach (System.Windows.Point p in mesh.TextureCoordinates)
newmesh.TextureCoordinates.Add(p);
}
}
newmesh.TriangleIndices.Freeze();
newmesh.TextureCoordinates.Freeze();
newmesh.Positions.Freeze();
newgmodel.Material.Freeze();
newgmodel.BackMaterial.Freeze();
newgmodel.Freeze();
model3DGroup.Children.Add(newgmodel);
}
}
表现并不好,事实上它更糟糕......我在这里缺少什么?似乎我的假设,即最小化GeometryModel3D的数量将是有益的,是错误的。我已经读过某些地方,在wpf 3d中,三角形的数量对性能没有太大影响,但纹理的数量更为关键。在这里,我有大量的三角形,但只有2个纹理,只有一个ModelVisual3D,所有都被冻结......有什么建议吗?
答案 0 :(得分:0)
我很幸运地分离了应用任何变换的网格,然后重新连接网格。我从这里得到了这个想法:http://msdn.microsoft.com/en-us/library/bb613553.aspx