【问题标题】:Calculating matrices on CPU takes up most of the frame time在 CPU 上计算矩阵占用了大部分帧时间
【发布时间】:2021-02-27 06:20:39
【问题描述】:

我正在为一个简单的游戏编写一个简单的引擎,到目前为止,我很喜欢我的小爱好项目,但游戏不断发展,现在一个场景中一次大约有 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)) 

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

【问题讨论】:

    标签: ios swift macos opengl-es metal


    【解决方案1】:

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

    1. 优化您的框架依赖关系以尽可能避免停顿,例如通过在 CPU 上预先计算帧数据。 This 是了解这项技术的好资源。
    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

    【讨论】:

    • 我以为我要在 gpu 上计算所有矩阵,但出现了关于从非连续内存块复制到每帧缓冲区的问题。但是,我确实在 gpu 上运行了粒子系统,因为我将粒子组件保存在一个地方,因此很容易管理对不同对象上的变换组件的随机位置块构成的缓冲区。
    • 但是间接命令与我的问题没有直接关系我刚刚尝试过,而且 man... 使用的命令编码实际上需要时间,现在因为我不在每次渲染过程中都这样做,所以我保存了一个非常感谢您指出!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2018-02-25
    相关资源
    最近更新 更多