-1

我有一个包含 2300 万条记录的表格文件,格式如下 {atomName, x, y, z, transparence}。对于解决方案,我决定使用 OpenGL。

我的任务是渲染它。在第一次迭代中,我使用块“glBegin/glEnd”并将每个原子绘制为点某种颜色。这个解决方案奏效了。但我得到了 0.002 fps。

然后我尝试使用 VBO。我形成了三个缓冲区:顶点、颜色和索引。这个解决方案奏效了。我得到了 60 fps,但我没有舒适的绑定缓冲区,我正在绘制点,而不是球体。

然后我读到了 VAO,它可以简化绑定缓冲区。好的,它成功了。我得到了舒适的绑定。

现在我想画球体,而不是点。我想,相对于顶点集的每个点形成一个球体,在这些点上可以构建一个球体(具有一定的准确性)。但是如果我有 2300 万个顶点,我必须计算每个点之间的 12 个或更多顶点相关。23 000 000 * 4 (float) = 1 Gb 数据,也许这不是一个好的解决方案。

我应该做的最好的下一步是什么?我无法完全理解此任务中适用的着色器或存在其他方式。

4

1 回答 1

1

关于你的绘图过程

我的任务是渲染它。在第一次迭代中,我使用块“glBegin/glEnd”并将每个原子绘制为点某种颜色。这个解决方案奏效了。但我得到了 0.002 fps。

想一想:对于 2300 万条记录中的每一条,您至少直接调用了一个函数(glVertex),并且可能由此隐式调用了几个函数。更糟糕的是,glVertex 可能会导致上下文切换。这意味着,您的 CPU 对于它必须处理的每个顶点都会遇到几个减速带。如今,一流的 CPU 的时钟频率约为 3 GHz,流水线长度约为 10 条指令。当您进行上下文切换时,流水线会停止,在最坏的情况下,它需要一个流水线长度来实际处理一条指令。假设您必须执行至少 1000 条指令来处理单个 glVertex 调用(这实际上是一个相当乐观的估计)。仅此一项就意味着,您每秒最多只能处理 300 万个顶点。

但是你也有上下文切换,这增加了进一步的惩罚。并且可能有很多分支会产生进一步的管道刷新。

这只是 glVertex 调用。你那里也有颜色。

你想知道即时模式很慢吗?

当然,它很慢。15 年来一直不鼓励使用立即模式。顶点数组从 OpenGL-1.1 开始可用。

这个解决方案奏效了。我有60 fps,

是的,因为所有数据现在都驻留在 GPU 自己的内存中。GPU 是大规模并行和优化的,可以处理此类数据并执行它们所做的操作。

但我不习惯绑定缓冲区

好吧,OpenGL 不是一个高级场景图库。这是一个中低级绘图 API。您可以像使用复杂的铅笔一样使用它在数字画布上绘图。

然后我读到了关于 VAO

好吧,VAO 旨在合并属于一起的缓冲区对象,因此使用它们是有意义的。

现在我想画球体,而不是点。

你有两个选择:

  • 使用点精灵纹理。这意味着您的点在绘制时将获得区域,并且该区域将应用​​纹理。我认为这是最适合你的方法。给定正确的着色器,您甚至可以为您的点精灵提供正确的深度值,这样您的“球体”实际上会像深度​​缓冲区中的球体一样相交。

  • 另一种选择是使用单个球体几何的实例化,使用您的原子记录作为实例化过程的控制数据。然后,这将处理真实的球体几何。但是,我担心目前实现实例化绘图过程对于您的技能水平来说可能有点太高级了。

关于绘制2300万点

说真的,你有什么样的显示器可以画出 2300 万个可区分的点?您的典型计算机屏幕大约有 2000×1500 点。现在你可以买到的最高分辨率显示器大约有 4k×2.5k 像素,即 1000 万个单独的像素。让我们假设您的原子均匀分布在一个平面上:在 2300 万个原子上绘制每个像素将被透支数倍。你根本无法以这种方式显示 2300 万个单独的原子。另一种看待这一点的方法是,显示器的像素网格意味着空间采样,并且您无法再现小于平均采样距离两倍的任何东西(采样定理)。

因此,仅绘制数据的子集是绝对有意义的,即实际在视图中的子集。此外,如果您被放大得很远(即您可以看到完整的数据集),那么在附近合并原子是有意义的。

将数据分类为空间细分结构绝对有意义。在您的情况下,我认为八叉树将是一个不错的选择。

于 2013-10-24T10:50:11.470 回答