我的文件包含2300万条记录,表格如下{atomName,x,y,z,transparence}。对于解决方案,我决定使用OpenGL。
我的任务是渲染它。在第一次迭代中,我使用块“glBegin / glEnd”并将每个原子绘制为点颜色。该解决方案有效。但我得到了0.002 fps。
然后我尝试使用VBO。我形成了三个缓冲区:顶点,颜色和索引。该解决方案有效。我得到了60 fps,但是我没有舒适的绑定缓冲区,而且我正在绘制点,而不是球体。
然后我读到了VAO,它可以简化绑定缓冲区。好的,它是有效的。我觉得很舒服。
现在我想绘制球体,而不是点数。我想,要相对于顶点集的每个点形成,在这些点上可以构建一个球体(具有一定的精度)。但如果我有2300万个顶点,我必须计算每个点相关的~12个或更多个顶点。 23 000 000 * 4(浮动)= 1 Gb数据,也许不是很好的解决方案。
我应该做的最好的下一步行动是什么?我无法完全理解,此任务中适用的着色器或存在其他方式。
答案 0 :(得分:1)
我的任务是渲染它。在第一次迭代中,我使用块“glBegin / glEnd”并将每个原子绘制为点颜色。该解决方案有效。但我得到了0.002 fps。
考虑一下:对于你的2300万条记录中的每条记录,你至少要直接进行一次函数调用(glVertex),并且可能隐含地进行几次函数调用。更糟糕的是,glVertex可能会导致上下文切换。这意味着,你的CPU会为它必须处理的每个顶点碰到几个速度颠簸。如今,顶级CPU的时钟频率约为3 GHz,流水线长度约为10条指令。当您进行上下文切换以使管道停止时,在最坏的情况下,它需要一个管道长度来实际处理一条指令。让我们考虑您必须执行至少1000条指令来处理单个glVertex调用(这实际上是一个相当乐观的估计)。仅这一点意味着,您每秒最多处理300万个顶点。因此,当时已经有不到一个FPS的2300万个顶点。
但是你也有了上下文切换,这进一步增加了一个阴谋。可能还有很多分支会导致进一步的管道冲洗。
这就是glVertex的召唤。你也有颜色。
你想知道立即模式是慢的吗?
当然很慢。 15年来,人们不鼓励使用立即模式。 Vertex Arrays自OpenGL-1.1开始提供。
此解决方案有效。我得到了60 fps,
是的,因为现在所有数据都驻留在GPU自己的内存中。 GPU是大规模并行和优化的,可以处理这类数据并完成它们的操作。
但我不习惯绑定缓冲区
嗯,OpenGL不是高级场景图库。这是一个中低级别的绘图API。你可以像使用复杂的铅笔一样在数字画布上绘画。
然后我读了关于VAO
的内容
嗯,VAO旨在合并属于一起的缓冲区对象,因此使用它们是有意义的。
现在我想绘制球体,而不是点数。
您有两种选择:
使用点精灵纹理。这意味着您的点将在绘制时获得区域,并且该区域将应用纹理。我认为这是最好的方法。给定正确的着色器,你甚至可以给你的点精灵提供正确的深度值,这样你的“球体”实际上会像深度缓冲区中的球体一样相交。
另一个选项是使用实例化单个球体几何体,使用原子记录作为实例化过程的控制数据。然后,这将处理真实球体几何形状。但是我担心实施一个实例化的绘图过程可能会对你的技能水平有点过高。
说真的有什么样的显示器,你可以画出2300万个可辨别点吗?您典型的电脑屏幕将有大约2000×1500点。这些天你可以购买的最高分辨率显示器具有大约4k×2.5k像素,即1000万个像素。让我们假设你的原子均匀分布在一个平面上:绘制每个像素的2300万个原子会多次透支。你根本无法以这种方式显示2300万个原子。另一种看待这种情况的方法是,显示器的像素网格意味着空间采样,你不能再现小于平均采样距离两倍的任何东西(采样定理)。
因此,仅绘制数据的子集(即实际可见的子集)是绝对有意义的。此外,如果您缩放得非常远(即视图中有完整的数据集),那么将原子合并在一起是有意义的。
将数据分类为空间细分结构绝对有意义。在你的情况下,我认为八叉树将是一个不错的选择。