整个区别就像你说的,在纹理缓存中。因此,在这两种方法之间进行选择取决于您是否希望在可视化中利用纹理缓存。让我们看一些常见的情况:
a) 如果你想计算一个表面是如何变形的(例如水的表面,或者可能是一些弹性变形)并且你需要知道表面多边形网格的新顶点,那么你通常会使用缓冲区(数字一),除非您不需要在此处复制到 OpenGL 纹理。实际上这里不涉及复制,您只需引用 CUDA 中的缓冲区并将其用作 gl 缓冲区即可。
b) 如果您有一个粒子模拟并且需要知道更新后粒子的位置,您也可以像上述情况一样使用缓冲区。
c) 如果您有一个有限元网格模拟,其中空间中的每个固定体积单元都将获得一个新值,并且您需要通过体积渲染或等值面将其可视化,那么您将需要使用纹理对象(2D 或3D 取决于模拟的维度),因为当您投射光线,甚至生成流线时,您几乎总是需要立即缓存相邻的纹素。并且您可以避免在此处进行任何复制,因为在上述方法中您也可以直接从 OpenGL 引用一些 CUDA 纹理内存(cudaArray)。您将使用这些调用来做到这一点:
cudaGraphicsGLRegisterImage( &myCudaGraphicsResource, textureNameFromGL, GL_TEXTURE_3D,...)
...
cudaGraphicsMapResources(1, myCudaGraphicsResource)
cudaGraphicsSubResourceGetMappedArray(&mycudaArray, myCudaGraphicsResource, 0, 0)
cudaGraphicsUnMapResources(1, myCudaGraphicsResource)
因此 CUDA 中的纹理数据可以被 mycudaArray 引用,而 OpenGL 中的相同内存可以被 textureNameFromGL 引用。
从缓冲区复制到纹理是一个坏主意,因为如果您需要此数据进行纹理缓存,您将进行额外的复制。在支持纹理互操作之前,这在早期版本的 CUDA 中更受欢迎
您也可以在 a) 和 b) 用例中使用纹理。对于某些硬件,它甚至可以更快地工作,但这非常依赖于硬件。还要记住,纹理读取也会应用缩小和放大过滤器,如果您要查找的只是存储在缓冲区中的精确值,则这是额外的工作。
要与 CUDA 和 OpenGL 共享纹理资源,请参阅此示例
https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st