2012-10-01 23 views
2

我的程序顯示了一個靜態場景,其中包含幾個3d模型的不同位置的實例,例如一棵樹。這個模型可能很「重」,介於50000到100000個三角形之間,並且性能會隨着實例的數量而迅速下降(性能不可接受超過10個實例)。wpf 3d,Model3DGroup的多個實例,試圖優化性能

我的第一個代碼,沒有優化,看起來是這樣的:

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

我已經有了好運氣,可以分離應用任何轉換的網格,然後重新連接網格。我從這裏得到了這個想法:http://msdn.microsoft.com/en-us/library/bb613553.aspx

+0

如果不是轉換問題;在視口中添加模型的函數BuildScene()僅被調用一次,以創建靜態場景;通過靜態,我的意思是一旦顯示視口,其內容不會改變,只有相機移動。 我知道你的鏈接指向的文章,實際上它在那裏我讀 「只有當它們需要不同的材質或變形時才創建不同的模型,否則,嘗試將許多具有相同材質和變形的GeometryModel3D實例合併成幾個較大的GeometryModel3D和MeshGeometry3D實例。「 – jpg

+0

嗯,具體取決於究竟有多大,通過這個我的意思是屏幕上的大小,對象是多少,你可以看到在任何給定的時間點。我的意思是,如果您的對象被viewport3d動態剪裁,那麼您將遇到動畫緩慢或閃爍的問題。這包括相機移動的動畫。老實說,我認爲你最好的選擇可能是在最低限度管理的DX上轉向Direct X。 – Nomad101