WPF 3D性能-我如何使其更快

WPF 3D性能-我如何使其更快,wpf,3d,Wpf,3d,我是WPF3D的新手。我想知道wpf3d是否能满足我的需要。 为了测试,我编写了一个简单的程序,将大约15000个球体渲染到场景中。当我在释放模式下运行测试时,场景显示大约需要30秒,之后每帧绘制大约需要3秒。我做错什么了吗?或者15000个球体对于WPF渲染来说太多了。非常感谢您的帮助。我的测试代码发布在下面 公共Simple3DSceneInCode() { Title = "Simple 3D Scene in Code"; // Make DockPan

我是WPF3D的新手。我想知道wpf3d是否能满足我的需要。 为了测试,我编写了一个简单的程序,将大约15000个球体渲染到场景中。当我在释放模式下运行测试时,场景显示大约需要30秒,之后每帧绘制大约需要3秒。我做错什么了吗?或者15000个球体对于WPF渲染来说太多了。非常感谢您的帮助。我的测试代码发布在下面

公共Simple3DSceneInCode() {

        Title = "Simple 3D Scene in Code";

        // Make DockPanel content of window.
        DockPanel dock = new DockPanel();
        Content = dock;

        // Create Viewport3D for 3D scene.
        viewport = new Viewport3D();
        dock.Children.Add(viewport);

        // Create the camera.
        cam = new PerspectiveCamera(new Point3D(-20, -20, -20), new Vector3D(20, 20, 20), new Vector3D(0, 1, 0), 45);
        viewport.Camera = cam;

        ModelVisual3D modvis = new ModelVisual3D();
        modvis.Content = new AmbientLight(Colors.Gray);
        viewport.Children.Add(modvis);

        modvis = new ModelVisual3D();
        modvis.Content = new DirectionalLight(Colors.Silver, new Vector3D(2, -3, -1));
        viewport.Children.Add(modvis);

        Model3DGroup geogroup = new Model3DGroup();
        MeshGeometry3D sphereGeom = GenerateSphere(new Point3D(0.2, 0.2, 0.2), 0.3, 25, 25);
        DiffuseMaterial d1 = new DiffuseMaterial(Brushes.Green);
        DiffuseMaterial d2 = new DiffuseMaterial(Brushes.Red);


        for (int i = 0; i < 25; i++)
        {
            for (int j = 0; j < 25; j++)
            {
                for (int k = 0; k < 25; k++)
                {
                    GeometryModel3D sphereMode = new GeometryModel3D();
                    sphereMode.Geometry = sphereGeom;
                    sphereMode.Material = d1;
                    sphereMode.BackMaterial = d2;
                    sphereMode.Transform = new TranslateTransform3D((double)i / 2.0, (double)j / 2.0, -(double)k / 2.0);
                    geogroup.Children.Add(sphereMode);
                }
            }
        }

        ModelVisual3D mvgeom = new ModelVisual3D();
        mvgeom.Content = geogroup;

        viewport.Children.Add(mvgeom);

    }



    MeshGeometry3D GenerateSphere(Point3D center, double radius,
                                  int slices, int stacks)
    {
        // Create the MeshGeometry3D.
        MeshGeometry3D mesh = new MeshGeometry3D();

        // Fill the Position, Normals, and TextureCoordinates collections.
        for (int stack = 0; stack <= stacks; stack++)
        {
            double phi = Math.PI / 2 - stack * Math.PI / stacks;
            double y = radius * Math.Sin(phi);
            double scale = -radius * Math.Cos(phi);

            for (int slice = 0; slice <= slices; slice++)
            {
                double theta = slice * 2 * Math.PI / slices;
                double x = scale * Math.Sin(theta);
                double z = scale * Math.Cos(theta);

                Vector3D normal = new Vector3D(x, y, z);
                mesh.Normals.Add(normal);
                mesh.Positions.Add(normal + center);
                mesh.TextureCoordinates.Add(
                        new Point((double)slice / slices,
                                  (double)stack / stacks));
            }
        }

        // Fill the TriangleIndices collection.
        for (int stack = 0; stack < stacks; stack++)
            for (int slice = 0; slice < slices; slice++)
            {
                int n = slices + 1; // Keep the line length down.

                if (stack != 0)
                {
                    mesh.TriangleIndices.Add((stack + 0) * n + slice);
                    mesh.TriangleIndices.Add((stack + 1) * n + slice);
                    mesh.TriangleIndices.Add((stack + 0) * n + slice + 1);
                }
                if (stack != stacks - 1)
                {
                    mesh.TriangleIndices.Add((stack + 0) * n + slice + 1);
                    mesh.TriangleIndices.Add((stack + 1) * n + slice);
                    mesh.TriangleIndices.Add((stack + 1) * n + slice + 1);
                }
            }
        return mesh;
    }
Title=“代码中的简单3D场景”;
//使DockPanel成为窗口的内容。
DockPanel dock=新的DockPanel();
内容=码头;
//为三维场景创建视口3D。
viewport=新的Viewport3D();
dock.Children.Add(视口);
//创建相机。
cam=新透视摄像机(新点3D(-20,-20,-20),新矢量3D(20,20,20),新矢量3D(0,1,0,45);
viewport.Camera=cam;
ModelVisual3D modvis=新的ModelVisual3D();
modvis.Content=新环境光(颜色为灰色);
viewport.Children.Add(modvis);
modvis=新模型Visual3D();
modvis.Content=新方向光(Colors.Silver,新Vector3D(2,-3,-1));
viewport.Children.Add(modvis);
Model3DGroup地理组=新Model3DGroup();
MeshGeometry3D SPHELEGEOM=生成点(新点3D(0.2,0.2,0.2),0.3,25,25);
扩散材料d1=新扩散材料(刷子。绿色);
扩散材料d2=新的扩散材料(刷红色);
对于(int i=0;i<25;i++)
{
对于(int j=0;j<25;j++)
{
对于(int k=0;k<25;k++)
{
GeometryModel3D sphereMode=新的GeometryModel3D();
sphereMode.Geometry=sphereGeom;
sphereMode.Material=d1;
sphereMode.BackMaterial=d2;
sphereMode.Transform=新的TranslateTransform3D((双)i/2.0,(双)j/2.0,-(双)k/2.0);
geogroup.Children.Add(sphereMode);
}
}
}
ModelVisual3D mvgeom=新ModelVisual3D();
mvgeom.Content=地理组;
viewport.Children.Add(mvgeom);
}
MeshGeometry3D生成点(点3D中心,双半径,
整数切片,整数堆栈)
{
//创建网格Geometry3D。
MeshGeometry3D mesh=新MeshGeometry3D();
//填充位置、法线和纹理坐标集合。

对于(int stack=0;stack如果不打算在创建后更改GeometryModel3D对象,则可以“冻结”它们

public void Simple3DSceneInCode()
{
Title=“代码中的简单3D场景”;
//使DockPanel成为窗口的内容。
DockPanel dock=新的DockPanel();
内容=码头;
//为三维场景创建视口3D。
var viewport=new Viewport3D();
dock.Children.Add(视口);
//创建相机。
var cam=新透视摄像机(新点3D(-20,-20,-20),新矢量3D(20,20,20),新矢量3D(0,1,0,45);
viewport.Camera=cam;
ModelVisual3D modvis=新的ModelVisual3D();
modvis.Content=新环境光(颜色为灰色);
viewport.Children.Add(modvis);
modvis=新模型Visual3D();
modvis.Content=新方向光(Colors.Silver,新Vector3D(2,-3,-1));
viewport.Children.Add(modvis);
Model3DGroup地理组=新Model3DGroup();
MeshGeometry3D SPHELEGEOM=生成点(新点3D(0.2,0.2,0.2),0.3,25,25);
sphereGeom.Freeze();
扩散材料d1=新扩散材料(刷子。绿色);
扩散材料d2=新的扩散材料(刷红色);
对于(int i=0;i<25;i++)
{
对于(int j=0;j<25;j++)
{
对于(int k=0;k<25;k++)
{
GeometryModel3D sphereMode=新的GeometryModel3D();
sphereMode.Geometry=sphereGeom;
sphereMode.Material=d1;
sphereMode.BackMaterial=d2;
sphereMode.Transform=新的TranslateTransform3D((双)i/2.0,(双)j/2.0,-(双)k/2.0);
sphereMode.Freeze();
geogroup.Children.Add(sphereMode);
}
}
}
ModelVisual3D mvgeom=新ModelVisual3D();
mvgeom.Content=地理组;
viewport.Children.Add(mvgeom);
}

我发现以下两个资源非常有用:


嗨,科林斯明斯,这真的很有帮助。最初的创建时间从30秒增加到了4秒左右。谢谢。抽签仍然需要3-4秒。我能做些什么来降低这一点吗?
public void Simple3DSceneInCode()
{
    Title = "Simple 3D Scene in Code";

    // Make DockPanel content of window.
    DockPanel dock = new DockPanel();
    Content = dock;

    // Create Viewport3D for 3D scene.
    var viewport = new Viewport3D();
    dock.Children.Add(viewport);

    // Create the camera.
    var cam = new PerspectiveCamera(new Point3D(-20, -20, -20), new Vector3D(20, 20, 20), new Vector3D(0, 1, 0), 45);
    viewport.Camera = cam;

    ModelVisual3D modvis = new ModelVisual3D();
    modvis.Content = new AmbientLight(Colors.Gray);
    viewport.Children.Add(modvis);

    modvis = new ModelVisual3D();
    modvis.Content = new DirectionalLight(Colors.Silver, new Vector3D(2, -3, -1));
    viewport.Children.Add(modvis);

    Model3DGroup geogroup = new Model3DGroup();
    MeshGeometry3D sphereGeom = GenerateSphere(new Point3D(0.2, 0.2, 0.2), 0.3, 25, 25);
    sphereGeom.Freeze();
    DiffuseMaterial d1 = new DiffuseMaterial(Brushes.Green);
    DiffuseMaterial d2 = new DiffuseMaterial(Brushes.Red);

    for (int i = 0; i < 25; i++)
    {
        for (int j = 0; j < 25; j++)
        {
            for (int k = 0; k < 25; k++)
            {
                GeometryModel3D sphereMode = new GeometryModel3D();
                sphereMode.Geometry = sphereGeom;
                sphereMode.Material = d1;
                sphereMode.BackMaterial = d2;
                sphereMode.Transform = new TranslateTransform3D((double)i / 2.0, (double)j / 2.0, -(double)k / 2.0);
                sphereMode.Freeze();
                geogroup.Children.Add(sphereMode);
            }
        }
    }

    ModelVisual3D mvgeom = new ModelVisual3D();
    mvgeom.Content = geogroup;

    viewport.Children.Add(mvgeom);
}