是否可以在顶点着色器内持续更改 iPhone OpenGL ES 2.0 上 VBO 的值?
我是 Opengl ES 2.0 新手(和 GLSL 新手),所以如果这是一个明显的问题,请原谅我。
如果我有一个 VBO,在程序开始时在 CPU 上初始化一次,是否可以使用顶点着色器在每帧更新它,而无需在 cpu 上进行计算,然后将其重新上传到 GPU?我不是指发送制服并据此操纵数据。相反,我的意思是导致 GPU 本身上的 VBO 发生持续变化。
因此,我能想到的最简单的例子是每次渲染帧时,将 1 添加到顶点着色器中 gl_Position 的 x、y 和 z 分量。这意味着,如果我只有一个顶点,并且它在 cpu 上的初始位置设置为 (0,0,0,1) ,那么在 30 帧后它将是 (30,30,30,1) 。
如果这可能的话,代码会是什么样子?
I am an Opengl ES 2.0 newbie (and GLSL newbie) so forgive me if this is an obvious question.
If I have a VBO that I initialize once on the CPU at the start of my program is it possible to then use vertex shaders to update it each frame without doing calculations on the cpu and then reuploading it to the GPU? Im not referring to sending a uniform and manipulating the data based on that. Instead I mean causing a persistent change in the VBO on the GPU itself.
So the simplest example I can think of would be adding 1 to the x,y and z component of gl_Position in the vertex shader every time the frame is rendered. This would mean that if I had only one vertex and its initial position was set on the cpu to be (0,0,0,1) then after 30 frames it would (30,30,30,1) .
If this is possible what would it look like in code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(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 作为缓冲区使用情况)。
也许您还可以通过使更改依赖于另一个更简单的数据来完全阻止持久更新。在您的示例中,您可以仅使用统一的帧编号,并将其设置为每帧顶点着色器中的坐标,但我不知道您的更新函数到底有多复杂。
On modern desktop hardware (GL3/DX10) you can use transform feedback to write back the output of the vertex or geometry shader into a buffer, but I really doubt that the transform_feedback extension is supported on the iPhone (or in ES in general).
If PBOs are supported (what I also doubt), you can at least do it with some GPU-GPU copies. Just copy the vertex buffer into a texture (by binding it as a PBO), then render a textured fullscreen quad and perform the update in the fragment shader. After that you copy the framebuffer (which now contains the updated vertex data) into the vertex buffer (again by binding it as PBO). But this way you have to do 2 copies (although they should both happen completely on the GPU) and if the vertex data is floating point you will need to floating point render targets and framebuffer objects to be supported, too.
I think in ES the best solution would really be to do the computation on the CPU. Just hold a CPU copy (so you at least have no unneccessary GPU-CPU readback) and update the buffer data every frame (using
GL_DYNAMIC_DRAW
or evenGL_STREAM_DRAW
as buffer usage).Maybe you can also completely prevent the persistent update by making the changes dependent on another simpler data. In your example you could just use a uniform for the frame number and set this as coordinate in the vertex shader every frame, but I don't know how complex your update function really is.