私のプログラムは、樹木などの 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 のみを作成することで速度を上げることができると考えました。それが私がこのコードで試したことです:
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 は 1 つだけで、すべてが凍結しています...何か提案はありますか?