4

我是 Opengl ES 2.0 新手(和 GLSL 新手),如果这是一个明显的问题,请原谅我。

如果我有一个在程序开始时在 CPU 上初始化一次的 VBO,是否可以使用顶点着色器在每帧更新它而不在 cpu 上进行计算,然后将其重新上传到 GPU?我不是指发送制服并基于此操作数据。相反,我的意思是导致 GPU 本身的 VBO 持续变化。

所以我能想到的最简单的例子是每次渲染帧时在顶点着色器中的 gl_Position 的 x、y 和 z 分量上加 1。这意味着如果我只有一个顶点并且它的初始位置在 cpu 上设置为 (0,0,0,1) 那么在 30 帧之后它将是 (30,30,30,1) 。

如果这是可能的,它在代码中会是什么样子?

4

1 回答 1

1

在现代桌面硬件(GL3/DX10)上,您可以使用变换反馈将顶点或几何着色器的输出写回缓冲区,但我真的怀疑 iPhone(或通常在 ES 中)是否支持 transform_feedback 扩展。

如果支持 PBO(我也对此表示怀疑),您至少可以使用一些 GPU-GPU 副本来做到这一点。只需将顶点缓冲区复制到纹理中(通过将其绑定为 PBO),然后渲染带纹理的全屏四边形并在片段着色器中执行更新。之后,您将帧缓冲区(现在包含更新的顶点数据)复制到顶点缓冲区(再次将其绑定为 PBO)。但是这样你必须做 2 个副本(尽管它们都应该完全发生在 GPU 上),如果顶点数据是浮点数据,你也需要浮点渲染目标和帧缓冲对象来支持。

我认为在 ES 中最好的解决方案实际上是在 CPU 上进行计算。只需保存一份 CPU 副本(这样您至少没有不必要的 GPU-CPU 回读)并每帧更新缓冲区数据(使用GL_DYNAMIC_DRAW甚至GL_STREAM_DRAW作为缓冲区使用情况)。

也许您还可以通过使更改依赖于另一个更简单的数据来完全防止持久更新。在您的示例中,您可以只使用统一的帧号并将其设置为每帧顶点着色器中的坐标,但我不知道您的更新函数到底有多复杂。

于 2011-08-26T23:49:16.573 回答