gpt4 book ai didi

opengl - 绘制一堆CUDA/OpenCL生成的元素?

转载 作者:行者123 更新时间:2023-12-04 05:45:51 25 4
gpt4 key购买 nike

我是图形编程的新手,需要为我们正在创建的演示添加渲染后端。我希望你们能指出我正确的方向。

短版 : 有什么方法可以向 OpenGL 发送不同元素的数据数组,而不必为每个元素分别发出绘制命令?

长版 :我们有一个 CUDA 程序(最终将是 OpenCL),它为我们计算一堆对象的一堆数据。然后我们需要使用例如 OpenGL 来渲染这些对象。

CUDA 内核可以生成我们的顶点,并且使用 OpenGL 互操作,它可以将这些推到 OpenGL VBO 中,而不必将数据传输回主机设备内存。但问题是我们有一堆(我们的目标是一百万以上)不同的对象。看起来我们最好的选择是分配一个 VBO 并将每个对象的顶点放入其中。然后我们可以使用该 VBO 中每个元素的偏移量和长度调用 glDrawArrays。

但是,每个对象可能具有可变数量的顶点(尽管场景中的总顶点可以有界。)我想避免必须从 CUDA -> CPU 每帧传输起始索引和长度列表,尤其是在给定的情况下这些绘图命令将直接返回到 GPU。

有没有办法用数据打包缓冲区,这样我们只能发出一次对 OpenGL 的调用来渲染缓冲区,并且它可以从该缓冲区渲染许多不同的元素?

(希望我也提供了足够的信息来避免这里的 XY 问题。)

最佳答案

一种方法是避免将这些理解为单独的对象,而是将它们变成一个使用单个绘制调用绘制的单个大对象。问题是,区分对象的数据是什么,这意味着您在对 glDrawArrays/glDrawElements 的各个调用之间更改了什么数据。 ?

如果它是简单的东西,比如颜色,那么提供一个额外的每个顶点属性可能会更容易。通过这种方式,您可以使用单个绘制调用将所有对象渲染为一个单独的大对象,并正确着色各个子对象(现在实际上仅存在于概念上)。附加属性的内存成本可能非常值得。

如果它有点复杂(如纹理),您仍然可以使用额外的每个顶点属性来索引它,或者是纹理数组的索引(因为纹理数组应该在 CUDA/OpenCL 上支持-硬件)或纹理坐标到单个大纹理的特定子区域(所谓的纹理图集)。

但是如果这些对象之间的差异更复杂,比如不同的着色器或其他东西,您可能真的需要渲染单个对象并进行单独的绘制调用。但是您仍然不需要必须往返于 CPU。随用ARB_draw_indirect扩展(这是自 GL 4.0 以来的核心,我认为,但可能在 GL 3 硬件(以及因此 CUDA/CL 硬件)上受支持,不知道)您可以将参数提供给 glDrawArrays/glDrawElements从附加缓冲区调用(您可以像任何其他 GL 缓冲区一样使用 CUDA/CL 写入该缓冲区)。因此,您可以在 GPU 上组装每个单独对象的偏移长度信息,并将它们存储在单个缓冲区中。然后你做你的glDrawArraysIndirect循环偏移到这个单一的绘制间接缓冲区(各个对象之间的偏移现在是恒定的)。

但是,如果发出多个绘制调用的唯一原因是您希望将对象渲染为单个 GL_TRIANGLE_STRIP s 或 GL_TRIANGLE_FAN s(或者,上帝当心,GL_POLYGON s),你可能想重新考虑只使用一堆 GL_TRIANGLES这样您就可以在一次绘制调用中渲染所有对象。使用三角形 strip (可能)节省的时间和内存可能会被多次绘制调用的开销所抵消,尤其是在渲染许多小三角形 strip 时。如果您真的想使用 strip 或扇形,您可能需要引入退化三角形(通过重复顶点)以将它们彼此分开,即使使用单个绘制调用绘制也是如此。或者您可以查看 glPrimitiveRestartIndex GL 3.1 引入的功能。

关于opengl - 绘制一堆CUDA/OpenCL生成的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10697303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com