Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 低帧速率_C#_Xna_Draw_Mesh_Frame Rate - Fatal编程技术网

C# 低帧速率

C# 低帧速率,c#,xna,draw,mesh,frame-rate,C#,Xna,Draw,Mesh,Frame Rate,好的,我有80000个简单纹理的“长方体”网格 我已经设定了视野和距离 只画你能看到的 为DrawModel函数留下600到1000个 问题是我每秒只有10帧,而且我的视距很差 另外,我已经对所有代码进行了内存测试,“mesh.draw()”每秒减少30帧。 没有比这更接近的了。 有什么帮助吗 private void DrawModel(MeshHolder tmpMH) { Model tmpDrawModel =

好的,我有80000个简单纹理的“长方体”网格 我已经设定了视野和距离 只画你能看到的 为DrawModel函数留下600到1000个 问题是我每秒只有10帧,而且我的视距很差 另外,我已经对所有代码进行了内存测试,“mesh.draw()”每秒减少30帧。 没有比这更接近的了。 有什么帮助吗

        private void DrawModel(MeshHolder tmpMH)
        {          
            Model tmpDrawModel = (Model)_Meshs[tmpMH.MeshFileName];
            Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];
            tmpDrawModel.CopyAbsoluteBoneTransformsTo(transforms);
            foreach (ModelMesh mesh in tmpDrawModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {

                    effect.LightingEnabled = false;

                    effect.TextureEnabled = true;
                    effect.Texture = (Texture2D)_Textures[tmpMH.GetTexture(Count)]; 



                    effect.View = _MainCam.View;
                    effect.Projection = _projection;
                    effect.World =
                         transforms[mesh.ParentBone.Index] *
                        Matrix.CreateFromYawPitchRoll(tmpMH.Rotation.Y, tmpMH.Rotation.X, tmpMH.Rotation.Z) *
                        Matrix.CreateScale(tmpMH.Scale) *
                        Matrix.CreateTranslation(tmpMH.Position);
                }

                    mesh.Draw();               
            }
        }
我不是一个剖析者,但我觉得这句话很痛苦。矩阵创建和乘法非常昂贵!我理解这段代码是必要的,因此,除非您可以预先计算这些矩阵,否则我会尝试:

Matrix pitch, scale, translation, temp1, temp2;

Matrix.CreateFromYawPitchRoll(
    tmpMH.Rotation.Y, tmpMH.Rotation.X, tmpMH.Rotation.Z, out pitch);
Matrix.CreateScale(ref tmpMH.Scale, out scale);
Matrix.CreateTranslation(ref tmpMH.Position, out translation);
Matrix.Multiply(ref transforms[mesh.ParentBone.Index], ref pitch, out temp1);
Matrix.Multiply(ref temp1, ref scale, out temp2);
Matrix.Multiply(ref temp2, ref translation, out effect.World);

这可能会更快,因为无需复制堆栈上的每个矩阵来进行参数传递(要复制的内容要少20倍以上)

正如您所说,破坏性能的是
ModelMesh.Draw
。绘制模型时,其工作原理如下:

for each frame
  for each Model
    for each ModelMesh // you call Draw(), which does:
      for each ModelMeshPart
        for each Effect
          for each EffectPass
            Draw some triangles // sends a batch of instructions to the GPU
所以问题是:每帧向GPU发送批处理的次数是多少?因为在CPU达到饱和之前,每帧只能发送几千个批次-达到“批次限制”。(每个批处理都会占用图形驱动程序中的CPU时间-它也会占用一些带宽和GPU时间,但CPU时间占主导地位。)

您可能需要阅读和了解更多信息

解决方案是修改场景(例如:组合一些网格部分,执行一些剔除,添加实例支持),以减少发送到GPU的批次数


另外,在
绘制
更新
循环中尽量避免类似的事情:

Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];

你真的应该尽最大努力避免每一帧发生的内存分配,因为它们最终会导致昂贵的垃圾收集和潜在的帧速率问题(特别是在Xbox上)。尝试将缓冲区存储在某个地方并重复使用。

我严重怀疑未经微优化的矩阵计算是否在这里主导CPU使用。还有
effect.World
不能是
out
参数。@安德鲁·拉塞尔:我认为这会有帮助。复制周围的东西是相当昂贵的不是CPU的使用,它只是减慢了一切,因为CPU需要等待内存(),而这两个版本的代码都不会命中主内存。这里的少量堆栈数据很容易放入CPU缓存。将CPU置于等待状态(如缓存未命中)仍然会被视为CPU使用量达到您的CPU限制。您的代码将“有帮助”,因为需要的指令更少,但数量很少,而且肯定不足以使OP低于CPU限制。这与非常类似。batchbatch.pdf链接现在似乎不起作用。这里有一个是有效的:那一个也坏了,现在。我已将其更新为一个新的有效版本。
Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];