将像素从纹理复制到纹理的最佳方法是什么?
我找到了一些方法来实现这一目标。
例如,有一个方法glCopyImageSubData()
,但我的目标版本是OpenGL 2.1,所以我不能使用它。
此外,由于性能非常重要,glGetTexImage2D()
不是一种选择。
由于我将视频帧作为纹理处理,因此我必须每秒复制约30~60次。
我找到的可用选项是下一个:
您可以忽略创建fbo的成本,因为fbo只会创建一次。
请不要发布像'取决于'的东西。做你的基准。'。 我不只针对一个GPU。如果有,请,请让我知道它取决于什么。
此外,由于测量OpenGL调用的时间非常困难,我想知道的不是定量结果。我需要一些关于应该避免哪种方法的建议。
如果您知道更好的复制纹理的方法,请告诉我。
感谢您的阅读。
答案 0 :(得分:19)
由于我不知道计时器查询,我没想到基准测试。 现在,我可以做自己的基准测试。 我测量了每100次操作的次数并重复了五次。 创建FBO的成本不包括在内。
- S=source texture, D=destination texture, SF=FBO of S, DF=FBO of D
- operation=copying texture to texture
- op/s = how many operations for one second(average), larger is better
使用简单的passthrough着色器
创建DF并将S渲染为DF创建SF并使用glCopyTexSubImage2D()进行D
创建DF和SF并使用glBlitFramebuffer()
创建DF和SF并使用glCopyPixels()
passthrough shader ~ glCopyTexSubImage2D > glBlitFramebuffer >> glCopyPixels
因此,简单的passthrough着色器显示复制纹理的最佳性能。 glCopyTexSubImage2D比passthrough着色器略慢。 fbo-blitting足够快但比着色器和glCopyTexSubImage2D更糟糕。 glCopyPixels,我没有预料到好的结果,表现出最差的表现。
答案 1 :(得分:1)
我们最终最终将四边形渲染到了目标中;当使用最小着色器时,使用GPU执行blit的不同方法之间的低精度等性能差异很小,这种方法提供了最大的灵活性。
但是,如果您可以找到一种避免仅完全复制的操作的方法 - 如果您可以更改将其中一个副本变为读取原始操作的操作,则应用变异和在一次通过中生成一个新副本 - 当然会更快。