我最近将我的 iPad2 从 5.x 更新到 iOS 6.0.1,并将 xcode 升级到 4.5.2。现在,当我构建和运行我的游戏时,它以 60 fps 的速度平稳运行。但是,当 3d 模型靠近屏幕时,帧速率现在会下降到 40fps 并保持在那里,即使模型远离屏幕也是如此。有什么办法可以克服这个问题,还是 iOS 6.0.1 或 xcode 4.5.2 的错误?这可能是 iOS 6.0.1 的某种省电功能吗?任何帮助,将不胜感激。
2 回答
据我所知,iOS 6.0.1 或 Xcode 4.5.2 中没有可能导致此问题的错误,但我只是一名工作的 iOS 开发人员,而不是负责这些项目质量控制的工程师。
有了这个问题中可用的最少信息,我的第一个猜测是模型是使用 mipmapped 纹理绘制的。当远离相机时使用较小版本的纹理,但当它靠近相机时使用较大版本的纹理。您可以做的一个可能的检查是关闭此模型的纹理并检查性能。然而,我假设您正在使用纹理,所以这个建议可能离题了。
诊断此问题的最佳方法是使用 Xcode 4.5 中提供的最新 OpenGL 调试和分析工具。我建议观看去年夏天关于 OpenGL 的 WWDC 的会议视频,以了解如何使用这些工具。
编辑以评论您发布的着色器:
着色器可以并行处理片段,但如果着色器中的条件在片段之间评估为不同的值,则会减少并行处理的数量。引用OpenGL ES 2.0 Programming Guide的第 156 页:
GPU 通常执行具有多个顶点的顶点着色器或具有并行多个片段的片段着色器。并行执行的顶点或片段的数量将取决于 GPU 的性能目标。if 和 if-else 条件语句中的 bool_expression 对于并行执行的顶点或片段可以具有不同的值。这会影响性能,因为 GPU 并行执行的顶点或片段的数量减少了。我们建议,为了获得最佳性能,条件语句应与 bool_expression 值一起使用,这些值对于并行执行的顶点或片段是相同的。如果使用统一表达式,就会出现这种情况。
也许 GPU 会愉快地处理很多片段,因为每个片段的布尔值都是相同的。然后,GPU 获取布尔值不再评估相同的片段,并且不再并行处理片段。知道这些可以评估为不同的值,GPU 继续以较少的并行度处理片段,即使在模型远离相机之后也是如此。
您的一系列 if 语句将值限制为特定状态。也许写一个能给出类似结果的方程可能会解决这个问题。尝试类似:
df = (floor(mod((((df + 0.2) * 10.0) / 3.0), 4.0)) * 3.0) / 10.0;
我实际上并没有使用此代码编译着色器,也没有完全匹配您的范围,因此您可能需要进行一些调整。但这应该保持并行性。
似乎“问题”在 iOS 7 上得到了解决。
我遇到了完全相同的问题...今天早上安装了新操作系统,似乎帧率问题刚刚消失。
现在帧率下降是一致的。当然,如果你做太多 GPU 的事情,它仍然会下降……但它会下降并逐渐恢复到 60,因为 GPU 执行的操作更少。
所以最后它似乎是某种“驱动程序/操作系统问题”(虽然没有官方确认)