【问题标题】:Graph rendering using 3D acceleration使用 3D 加速的图形渲染
【发布时间】:2010-09-18 04:55:55
【问题描述】:

我们为庞大的数据集生成图表。我们说的是每秒 4096 个样本,每张图 10 分钟。一个简单的计算得出每个线图有 4096 * 60 * 10 = 2457600 个样本。每个样本都是一个双精度(8 字节)精度的 FP。此外,我们在一个屏幕上渲染多个线图,最多大约一百个。这使得我们在一个屏幕上渲染了大约 25M 的样本。使用常识和简单的技巧,我们可以使用 CPU 在 2D 画布上绘制此代码来获得高性能。高性能,即渲染时间低于一分钟。 由于这是科学数据,我们不能遗漏任何样本。说真的,这不是一个选择。甚至不要开始考虑它。

当然,我们希望使用所有可用的技术来缩短渲染时间。多核、预渲染、缓存都很有趣,但不要削减它。我们希望这些数据集的渲染速度至少为 30FPS,首选 60FPS。我们现在这是一个雄心勃勃的目标。

卸载图形渲染的一种自然方法是使用系统的 GPU。 GPU 可用于处理庞大的数据集并并行处理它们。一些简单的 HelloWorld 测试向我们展示了使用 GPU 在渲染速度上的昼夜差异。

现在的问题是:OpenGL、DirectX 和 XNA 等 GPU API 是专为 3D 场景而设计的。因此,使用它们来渲染 2D 线图是可能的,但并不理想。在我们开发的概念证明中,我们遇到了需要将 2D 世界转换为 3D 世界的情况。突然间,我们必须使用 XYZ 坐标系和多边形、顶点等等。从发展的角度来看,这远非理想。代码变得不可读,维护是一场噩梦,还有更多的问题。

您对此 3D 有什么建议或想法?执行此操作以实际转换两个系统(2D 坐标与 3D 坐标和实体)的唯一方法是什么?还是有更时尚的方法来实现这一目标?

-为什么在一个像素上渲染多个样本很有用? 因为它更好地代表了数据集。假设在一个像素上,您有值 2、5 和 8。由于某些样本省略算法,只绘制了 5。这条线只会到 5,而不是 8,因此数据会失真。你也可以反对相反的观点,但事实是第一个参数对我们使用的数据集很重要。 这正是我们不能省略样本的原因。

【问题讨论】:

    标签: .net 3d gpu linegraph


    【解决方案1】:

    不确定这是否有帮助,但您可以使用时间作为维度吗?即一帧是一z?这可能会让事情更清楚,也许?那么也许您可以有效地应用增量来构建(即在 z 轴上)图像?

    【讨论】:

      【解决方案2】:

      这使得我们可以在一个屏幕上渲染大约 2500 万个样本。

      不,你不需要,除非你有一个非常大的屏幕。鉴于屏幕分辨率可能更像是 1,000 - 2,000 像素,您真的应该考虑在绘制数据之前对数据进行抽取。在性能方面,以每条线 1,000 个点绘制一百条线可能不是什么大问题。

      【讨论】:

        【解决方案3】:

        如果您不想,您真的不必担心 Z 轴。在 OpenGL 中(例如),您可以指定 XY 顶点(隐式 Z=0)、zbuffer 的转动、使用非投影投影矩阵,嘿,你就在 2D 中。

        【讨论】:

        • 我相信您所说的“非投影矩阵”称为正交投影。
        【解决方案4】:

        如果您将投影设置为正交(无 z),OpenGL 很乐意渲染 2D。你也应该抽取你的数据。将同一个像素渲染 1000 次是对 GPU 的浪费。使用 performat 多线程抽取器提前花时间。确保使用顶点数组或顶点缓冲区对象在 GPU 上爆炸大型数组(显然我是一个 OpenGL 类型的人)

        【讨论】:

          【解决方案5】:

          不,你不会,除非你有一个非常大的屏幕。鉴于屏幕分辨率可能更像是 1,000 - 2,000 像素,您真的应该考虑在绘制数据之前对数据进行抽取。在性能方面,以每条线 1,000 个点绘制一百条线可能不是什么大问题。

          首先,我们在渲染时不能省略任何样本。这是不可能的。这意味着渲染对图表所基于的数据不准确。这真的是一个禁区。时期。

          其次,我们正在渲染所有样本。可能是多个样本最终在同一个像素上。但是,我们仍在渲染它。样本数据在屏幕上转换。因此,它被渲染。人们可能会怀疑这种可视化数据的有用性,因为科学家(我们的客户)实际上要求我们这样做。他们有一个很好的观点,恕我直言。

          【讨论】:

          • 您可以使用 LOD 技术来解决这个问题。除非您可以放大并逐步细化数据,否则将多个样本渲染到同一个像素是没有用的。
          • 好吧,我很高兴您接受了试用 VTK 的建议,因为它会为您处理缩放/抽取。我确实感到困惑的是,您说渲染每个数据点很重要,即使它们最终位于同一个像素上。我觉得这里一定有沟通障碍。
          • 我试图在我的问题中解释这一点(我只是编辑了它)。真的,我在这个项目上的第一个回复和你的一样。一起工作,我明白我们不能省略样本,并且需要全部绘制。
          【解决方案6】:

          Mark Bessey 提到过,您可能缺少用于显示图形的像素。但是根据您的解释,我假设您知道自己在做什么。

          OpenGL 有一个正交模式,其内部有一个 z 坐标 (0;1)。没有透视投影,您绘制的多边形将与屏幕剪辑区域保持平面。

          DirectX 也会有类似的。在 OpenGL 上,它被称为 gluOrtho2d()。

          【讨论】:

            【解决方案7】:

            将库包装在一个更柔和、更友好的 2D 库中,并将 Z 和旋转都设置为 0。

            -亚当

            【讨论】:

              【解决方案8】:

              一个非常流行的科学可视化工具包是VTK,我认为它适合您的需求:

              1. 它是一个高级 API,因此您不必使用 OpenGL(VTK 构建在 OpenGL 之上)。有 C++、Python、Java 和 Tcl 的接口。我认为这将使您的代码库保持干净。

              2. 您可以将各种数据集导入 VTK(从医学影像到财务数据有大量示例)。

              3. VTK 速度非常快,如果您想做非常大的可视化,可以将 VTK 图形管道分布在多台机器上。

              4. 关于:

                这使得我们可以在一个屏幕上渲染大约 2500 万个样本。

                [...]

                由于这是科学数据,我们不能遗漏任何样本。说真的,这不是一个选择。甚至不要开始考虑它。

              您可以通过采样和使用 LOD 模型在 VTK 中渲染大型数据集。也就是说,您有一个模型,您可以从远处看到较低分辨率的版本,但如果放大,您会看到更高分辨率的版本。很多大型数据集的渲染都是这样完成的。

              您不需要从实际数据集中消除点,但是当用户放大时,您肯定可以逐步细化它。当用户无法将 2500 万个点渲染到单个屏幕上时,这对您没有好处处理所有这些数据。我建议您同时查看 VTK 库和 VTK 用户指南,因为那里有一些关于可视化大型数据集的方法的宝贵信息。

              【讨论】:

                【解决方案9】:

                如果您的代码因为直接处理 3D 内容而变得不可读,则需要编写一个薄的适配器层来封装所有 3D OpenGL 内容,并以对您的应用程序方便的形式获取 2D 数据。

                如果我遗漏了什么,请原谅我,并向合唱团宣讲基本的面向对象设计。只是说...

                【讨论】:

                  【解决方案10】:

                  您不需要从实际数据集中消除点,但是当用户放大时,您肯定可以逐步细化它。当用户无法将 2500 万个点渲染到单个屏幕上时,这对您没有好处处理所有这些数据。我建议您同时查看 VTK 库和 VTK 用户指南,因为那里有一些关于可视化大型数据集的方法的宝贵信息。

                  非常感谢。这正是我一直在寻找的。 VTK 似乎也使用硬件来卸载这些渲染。顺便说一句,我猜你的意思是有价值 ;)。 其次,用户确实获得了我给出的示例的信息。无论多么简洁,数据的概述对于科学家来说确实是纯金。它不是为用户处理所有数据,而是从渲染中获取有价值的信息。用户似乎会这样做,即使在数据集非常“缩小”的表示中也是如此。

                  还有什么建议吗?

                  【讨论】:

                  【解决方案11】:

                  我想在 tgamblin 的回答后面评论您关于不能省略样本的断言。

                  您应该将绘制到屏幕上的数据视为一个抽样问题。您说的是 240 万个数据点,而您正试图将其绘制到只有几千个点的屏幕上(至少我假设是这样,因为您担心 30fps 的刷新率)

                  这意味着对于 x 轴上的每个像素,您都不需要渲染大约 1000 个点。即使您确实走上了利用 gpu 的道路(例如,通过使用 opengl),对于不可见的行,gpu 仍然需要做大量工作。

                  我用来呈现样本数据的一种技术是生成一组数据,它是整个数据集的子集,仅用于渲染。 对于 x 轴上的给定像素(即给定 x 轴屏幕坐标),您需要渲染 absolute 最多 4 个点 - 即最小 y、最大 y、最左侧 y 和最右侧 y . 这将呈现所有可以有用呈现的信息。您仍然可以看到最小值和最大值,并保留与相邻像素的关系。

                  考虑到这一点,您可以计算出将落入 x 轴上相同像素的样本数(将它们视为数据“箱”)。在给定的 bin 内,您可以确定最大值、最小值等的特定样本。

                  重申一下,这只是用于显示的子集 - 并且仅适用于显示参数更改之前。例如。如果用户滚动或缩放图形,则需要重新计算渲染子集。

                  如果您使用的是 opengl,则可以这样做,但由于 opengl 使用标准化坐标系(并且您对现实世界的屏幕坐标感兴趣),您将不得不更加努力地准确确定您的数据箱。 这在不使用 opengl 的情况下会更容易,但您无法充分利用图形硬件。

                  【讨论】:

                  • 可以从原始数据集派生出一个数据集用于显示目的,以便视觉表示与原始数据集相同。然而,这个过程也是计算密集型的。这个过程的净收益是有限的,并没有增加显着的渲染时间优势。
                  【解决方案12】:

                  我想指出的是,除了直接使用 VTK 之外,还有另外两个基于 VTK 构建的产品可能会引起您的兴趣。

                  1) ParaView (paraview.org) 是一个建立在 VTK 之上的用户界面,它使科学可视化产品变得更加容易。你可以渲染所有你想要的数据,只要你有硬件来处理它,它支持多处理器/内核/集群的 MPI。它可以通过用户创建的插件进行扩展,并使用自动化工具进行项目构建和编译。

                  2) ParaViewGeo (paraviewgeo.mirarco.org) 是我工作的公司出品的 ParaView 地质矿产勘探衍生产品。它内置支持读取 ParaView 不支持的文件格式,例如 Gocad、Datamine、Geosoft、SGems 等。更重要的是,我们经常与其他对科学感兴趣的团体合作,也就是与采矿有松散联系的可交付成果,例如我们最近与一个做有限/离散元建模的团体合作。可能值得一试。

                  在这两种情况下(PV 和 PVG),您的数据都被视为与您对该数据的视图是分开的,因此,您永远不会“呈现”所有数据(因为您可能没有足够大的监视器来这样做)但请放心,它将按照您的预期从您的数据集中“在那里”处理。如果您对数据运行其他过滤器,则只会“渲染”可以看到的内容,但过滤器将对您的所有数据进行计算,虽然可能不会一次全部可见,但它们都将存在于内存中。

                  如果您正在寻找数字,今天我在 PVG 中计算了三个由 800 万个单元组成的规则网格。一个包含一个 7 元组向量属性(7x 800 万个 double 值),另外两个每个包含一个标量属性(每个 1x 800 万个 double 值),内存中总共有 7200 万个 double 值。我相信内存占用接近 500MB,但我也有一个 400,000 个点集,其中每个点都有一个 7 元组向量属性和一些其他可用的杂项数据。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-12-22
                    • 2013-09-29
                    • 2012-01-21
                    相关资源
                    最近更新 更多