ios游戏 - GPU端计算有任何缺点吗?

时间:2015-12-01 12:45:58

标签: ios opengl-es shader gpu

主题几乎是个问题。我试图了解CPU和GPU的合作方式。

我通过cocos2d开发我的游戏。它是一个游戏引擎,所以它每秒重绘整个屏幕60次。 cocos2d中的每个节点都绘制自己的三角形集。通常在CPU端执行节点转换(从节点到世界)后设置三角形的顶点。通过将视图模型投影传递给制服,我已经意识到使用顶点着色器在GPU端进行此操作的方法。

我看到CPU时间减少~1ms,gpu时间增加~0.5ms。 我可以将此视为性能提升吗?

换句话说:如果可以在GPU方面做些什么,你有什么理由不应该这样做吗?

1 个答案:

答案 0 :(得分:1)

如果您需要CPU端的结果(以易于访问的形式)以进一步模拟,那么您唯一不应该在GPU端执行某些操作。

举个例子。如果我们假设您有4个250KB网格,它们代表身体部位的层次结构(作为骨架)。让我们假设您使用4x4浮点矩阵进行每个网格的转换(64字节)。你可以:

  1. 每帧,在应用程序端(CPU)执行网格变换计算,然后将四个网格上传到GPU。这将导致每帧大约1000kb的数据被发送到GPU。

  2. 当应用程序启动时,将4个网格的数据上传到GPU(这将是休息/身份姿势)。然后,当您进行渲染调用时,每个帧只计算每个网格的新矩阵(位置/旋转/比例),并将这些矩阵上传到GPU并在那里执行转换。这导致每帧将〜256字节发送到GPU。

  3. 正如您所看到的,即使示例中的数据是伪造的,主要优点是您可以在每帧的基础上最大限度地减少CPU和GPU之间传输的数据量。

    您唯一希望第一个选项是您的应用程序需要转换结果才能完成其他工作。 GPU是非常有效的(特别是在并行处理顶点时),但是从GPU获取信息并且(通常在纹理上的形式 - 即RenderTarget)并不容易。这种“进一步工作”的一个具体例子可能是对变换后的网格位置进行碰撞检查。

    修改 您可以根据您在某种程度上调用存储数据的openGL api的方式来判断*。这是一个快速的破败:

    顶点阵列

    glVertexPointer(...)
    glDrawArray(...)
    

    使用此方法从CPU传递顶点数组 - > GPU每帧。顶点按照它们出现在数组中的顺序处理。这种方法有一种变体(glDrawElements),可以让你指定索引。

    <强>维也纳组织

    glBindBuffer(...)
    glBufferData(...)
    glDrawElements(...)
    

    VBO允许您将网格数据存储在GPU上(请参阅下面的注释)。这样,您不需要每帧都将网格数据发送到GPU,只需要转换数据。

    *虽然我们可以指出我们的数据存储位置,但实际上并未在OpenGL规范中指定供应商如何实现这一点。这意味着,我们可以提示我们的顶点数据应该存储在VRAM中,但最终还是要归功于驱动程序!

    这个东西的好参考链接是:

    OpenGL参考页面:https://www.opengl.org/sdk/docs/man/html/start.html

    OpenGL解释:http://www.songho.ca/opengl

    用于呈现的Java OpenGL概念:http://www.java-gaming.org/topics/introduction-to-vertex-arrays-and-vertex-buffer-objects-opengl/24272/view.html