我们为巨大的数据集生成图表.我们说的是每秒4096个样本,每个图表10分钟.一个简单的计算可以得到每行图4096*60*10 = 2457600个样本.每个样本都是双(8字节)精度FP.此外,我们在一个屏幕上渲染多个线图,最多约一百个.这使我们在一个屏幕上渲染大约25M个样本.使用常识和简单的技巧,我们可以使用CPU在2D画布上绘制此代码来获得此代码.Performant,即渲染时间低于一分钟.由于这是科学数据,我们不能省略任何样本.说真的,这不是一个选择.甚至不要开始考虑它.
当然,我们希望使用所有可用技术来改善渲染时间.多核,预渲染,缓存都非常有趣,但不要削减它.我们希望使用这些数据集进行30FPS渲染,最低为60FPS.我们现在这是一个雄心勃勃的目标.
卸载图形渲染的一种自然方法是使用系统的GPU.GPU可用于处理大型数据集并对其进行并行处理.一些简单的HelloWorld测试向我们展示了使用GPU时渲染速度的白天和黑夜的差异.
现在的问题是:GPU API,如OpenGL,DirectX和XNA都是为3D场景而制作的.因此,使用它们来渲染2D线图是可能的,但并不理想.在我们开发的概念证明中,我们遇到了我们需要将2D世界转换为3D世界.Suddnely我们必须使用和XYZ坐标系统与多边形,顶点和更多的善良.从发展的角度来看,这远非理想.代码变得难以理解,维护是一场噩梦,更多问题沸腾了.
你对3D的建议或想法是什么?这是实现转换两个系统(2D坐标与3D坐标和实体)的唯一方法吗?或者有更简洁的方法来实现这一目标吗?
- 为什么在一个像素上渲染多个样本是有用的? 因为它更好地代表了数据集.假设在一个像素上,您有值2,5和8.由于一些样本省略算法,只绘制了5.该行只会变为5,而不会变为8,因此数据会失真.您也可以争论相反,但事实是第一个参数对我们使用的数据集起作用.这正是我们不能省略样本的原因.
在tgamblin的答案背后,我想评论你断言你不能省略样本.
您应该将您绘制到屏幕上的数据视为抽样问题.你说的是2.4M的数据点,你试图把它画到一个只有几千点的屏幕上(至少我假设它是,因为你担心30fps的刷新率)
这意味着对于x轴中的每个像素,您都需要以1000点的顺序进行渲染.即使你确实沿着使用你的gpu的路径(例如通过使用opengl),这仍然是gpu需要为不可见的行做的大量工作.
我用于呈现样本数据的一种技术是生成一组数据,这些数据是整个集合的一个子集,仅用于渲染.对于x轴中的给定像素(即给定的x轴屏幕坐标),您需要渲染绝对最多4个点 - 即最小y,最大y,最左y和最右y.这将呈现可以有用地呈现的所有信息.您仍然可以看到最小值和最大值,并保留与相邻像素的关系.
考虑到这一点,您可以计算出落入x轴中相同像素的样本数(将它们视为数据"bins").在给定的bin中,您可以确定最大值,最小值等的特定样本.
重申一下,这只是用于显示的子集 - 并且仅在显示参数改变之前才适用.例如.如果用户滚动图形或缩放,则需要重新计算渲染子集.
如果你使用的是opengl,你可以这样做,但是由于opengl使用的是标准化的坐标系(你对现实世界的屏幕坐标很感兴趣),你必须更加努力地准确地确定你的数据箱.不使用opengl会更容易,但是你没有充分利用你的图形硬件.
如果你不想,你真的不必担心Z轴.在OpenGL(例如)中,您可以指定XY顶点(隐式Z = 0),转动zbuffer,使用非投影投影矩阵,并且嘿presto你是2D.
一个非常受欢迎的科学可视化工具包是VTK,我认为它适合您的需求:
它是一个高级API,因此您不必使用OpenGL(VTK建立在OpenGL之上).有C++,Python,Java和Tcl的接口.我认为这会让你的代码库非常干净.
您可以将各种数据集导入VTK(从医学成像到财务数据有大量示例).
VTK非常快,如果您想要进行非常大的可视化,您可以在多台计算机上分发VTK图形管道.
关于:
这使我们在一个屏幕上渲染大约25M个样本.
[...]
由于这是科学数据,我们不能省略任何样本.说真的,这不是一个选择.甚至不要开始考虑它.
您可以通过采样和使用LOD模型在VTK中渲染大型数据集.也就是说,你有一个模型,你可以从远处看到一个较低分辨率的版本,但如果你放大,你会看到一个更高分辨率的版本.这就是很多大型数据集渲染的完成方式.
您不需要从实际数据集中消除点,但是当用户放大时,您肯定可以逐步优化它.当用户无法处理所有这些时,您无法将2500万个点渲染到单个屏幕上数据.我建议您查看VTK库和VTK用户指南,因为在那里有关于可视化大型数据集的方法的宝贵信息.