【发布时间】:2014-05-22 09:43:00
【问题描述】:
我有一个关于如何渲染表面粒子的非常具体的方法的问题。该方法在 Nvidia GPU Gems 3 第 7 章“GPU 上 Metaballs 的基于点的可视化”中得到了很好的解释,link to this chapter。
这篇文章是关于使用均匀分布在曲面上的点或 splat 来渲染隐式曲面。他们说这些粒子的计算完全在 GPU 上完成。只有定义表面的数据从 CPU 发送到 GPU,以保持流量尽可能低。
他们还提供了一些片段着色器程序的伪代码示例,用于计算粒子位置、速度等。对我来说,这些程序看起来应该为每个粒子运行一次。
现在我的问题是,它们如何存储这些粒子?它是什么样的数据结构? 它必须是某种可以访问的缓冲区或纹理,以便在 GPU 上进行读取和写入操作。但是如何在下一个渲染步骤中再次渲染这个缓冲区/纹理呢?
我的第一个想法是某种顶点缓冲区对象,它在开始时发送到 GPU 一次,并在每次渲染过程中不断更新。这可能吗?
对我的一个要求是它必须使用 OpenGL/GLSL 来实现,我希望这是可能的。
【问题讨论】:
-
按照今天的标准,那本书是古老的,你知道的。自从那本书写成以来,大约 2-3 代硬件已经引入了用于持久存储转换顶点的新技术。在现代硬件上,首选方法是着色器存储缓冲区和计算着色器。但是在编写时,通常在片段着色器中处理粒子模拟并将像素数据传输到顶点缓冲区或使用顶点纹理提取。转换反馈随后出现。 最终,您的方法将取决于目标硬件要求 - 它们是什么?
-
是的,使用现代技术渲染粒子可能有更好的方法。我计划尽可能地贴近他们曾经能够应用他们的方法来快速访问相邻粒子数据以及哈希表访问(纹理查询)的管道。也许我必须尝试这些方法是否也可以使用变换反馈方法来渲染粒子。 (硬件要求现在不是那么重要,shader model 4+ 硬件可用:))
-
在这种情况下,您可以使用像素包缓冲区 (PBO) 将片段着色器的输出完全传输到 GPU 上的缓冲区对象。然后转身将其用作绘图的 VBO。您可能需要多个片段着色器输出,因此需要多个 PBO。
-
好吧,这听起来很有趣。你有这方面的例子吗?如果我理解正确的话,我会先创建一个 FBO 持有一个 PBO,然后在 PBO 中绘制更改后的粒子的屏幕外绘图。但我仍然想念 PBO 到 VBO 部分 ;-) 找不到任何材料如何做到这一点(到目前为止)。
-
不是我的头顶。我假设您以前使用过 FBO?尽管它们命名它们实际上并不是“缓冲区对象”(它们是 Framebuffer 对象)。您需要做的是绘制附加到 FBO 的纹理,然后使用
glGetTexImage (...)将该附件的图像读入您的像素包缓冲区。缓冲区对象只是一般内存,因此只要对齐/图像格式有意义(例如GL_RGBA32F==vec4),Pixel Pack Buffer 就可以立即用作顶点缓冲区对象(只需将其绑定到GL_ARRAY_BUFFER) .
标签: c++ opengl graphics glsl particles