首页 > 解决方案 > 在 CPU 上计算矩阵占用了大部分帧时间

问题描述

我正在为一个简单的游戏编写一个简单的引擎,到目前为止,我很喜欢我的小爱好项目,但游戏不断发展,现在一个场景中一次大约有 800 个游戏对象。

每个对象,就像在 Unity 中一样,都有一个变换组件,该组件在初始化组件时计算变换矩阵。我开始注意到,对于 800 个对象,只需 5.4 毫秒即可更新每个矩阵(例如,如果每个对象都已移动),而无需任何其他组件或其他任何东西。

我使用 GLKit 数学库,由于某种原因,它比使用本机 simd 类型更快。使用 simd 类型将计算时间增加三倍

这是运行它的一段代码

    let Translation : GLKMatrix4 = GLKMatrix4MakeTranslation(position.x, position.y, position.z)
    let Scale : GLKMatrix4 = GLKMatrix4MakeScale(scale.x, scale.y, scale.z)
    let Rotation : GLKMatrix4 = GLKMatrix4MakeRotationFromEulerVector(rotation)
    
    //Produce model matrix
    let SRT = GLKMatrix4Multiply(Translation, GLKMatrix4Multiply(Rotation, Scale)) 

问题:我正在寻找一种优化方法,以便可以使用更多游戏对象。并在我的对象上使用更多组件

标签: iosswiftmacosopengl-esmetal

解决方案


您的程序中可能存在多个瓶颈。

  1. 优化您的帧依赖性以尽可能避免停顿,例如通过在 CPU 上预先计算帧数据。是了解这项技术的好资源。
  2. 确保所有矩阵都存储在一个 MTLBuffer 中,该 MTLBuffer 是从您的顶点阶段索引的
  3. 在 Apple 芯片和 iOS 上使用 MTLResourceStorageModeShared
  4. 如果你真的想扩展到数以万计的对象,那么在计算着色器中计算你的矩阵以将它们存储在 MTLBuffer 中。然后,使用间接渲染来发出您的绘图调用。
  5. 一般来说,了解AZDO

了解计算着色器:https ://developer.apple.com/documentation/metal/basic_tasks_and_concepts/performing_calculations_on_a_gpu

了解间接渲染: https ://developer.apple.com/documentation/metal/indirect_command_buffers


推荐阅读