如何在 Three.js 中显示一百万条交互式线串

The*_*kov 6 3d three.js react-three-fiber react-three-drei

我想使用react-三纤维(或使用Drei库)显示电路。

  • 电路由segments和组成turns
  • 段是通过两点来定义的
  • 转弯是通过点列表来定义的

段和转弯

我希望我的用户能够自己构建电路。这意味着他将能够修改(拖/放/删除等...)转弯和线段。它将产生大约 10,000 个段和转弯,因此会产生超过 100,000 个点。

你将如何进行? (有关我的测试的更多详细信息,请参阅下文)


考虑的解决方案和困难

  • r3f((react-三纤维)instanceMesh组件(带有矩形):我需要存储链接到我的转弯/段id的instanceId的地图,这似乎不是不可能的。这似乎是一个很好的解决方案,并且仍然是具有超过 100k 元素的性能。我在这里实现了一个快速示例来测试此逻辑。

  • drei实例组件:当元素超过 1k 时,它开始变得滞后。您可以在这里玩一个示例(改编自 r3f 示例)

转弯

  • r3finstanceMesh组件:回合可以看作是段的列表。使用这个解决方案,如果我们放大太多,我们可以清楚地看到每个部分。这可能并不理想,但似乎正在发挥作用。另一个问题是,一个回合可以由 100+ 点组成。如果我有 1k 圈,它将绘制 100k 段,这开始很多

  • line:我们只能创建一种将所有转弯都包含在内的几何体。然而,目前我的所有线条都是链接的(就像我用一支笔一次性绘制它们一样)。此外,我认为用这个解决方案不容易操纵特定的转弯。

  • Linev2:我们还可以创建与转弯一样多的几何形状。每个回合都将是一个实体,而不是许多段。但是,不建议使用 1K+ 几何形状。使用这个解决方案时,性能一点都不好。

  • 限制对象的数量:我想尝试的另一个解决方案是在一个几何体中绘制所有转弯。在这种情况下,我不会有任何互动。当放大到足够大时,最多只能看到 50 个可见区域,我会添加包含所有交互的实线。这有点棘手,但似乎也是一个很好的妥协。

理想的情况是拥有一个转弯实例(例如线段)。然而,每个转弯似乎都是唯一的,我不知道如何在一个实例中仅创建一个几何体来显示所有可能的转弯。


实现这个逻辑的最佳方法是什么?


我尝试了这种方法,仅绘制最接近的转弯。它保持相当流畅。我将尝试进一步研究这个解决方案:这是一个实现的 GIF 示例:

在此输入图像描述

小智 3

我为一个组件做了一个 PRLineSegments,该组件现在可以在 Drei 9.53.0 中使用。你可以像这样使用它<Line segments />

\n

该组件可以在一次调用中渲染线条(带间隙)具有线条宽度(1px 除外)。这可能是最有效的绘制方式。

\n

LineSegments基本上是 Drei 的Line组件,但使用 Three.jsLineSegments2而不是Line2. LineSegments2orLine2使我们能够绘制线宽小于一像素的线条。

\n

对于交互,您仍然可以使用光线投射器。R3F 的指针事件还公开了一个faceIndex可用于确定哪一行的指针事件。

\n

如果您想绘制各种宽度,请根据宽度对线条进行分组,并创建LineSegments2每个宽度。

\n

如果帧速率太低,请将其与LOD和视锥体剔除结合起来。

\n

最后,如果重新渲染的数量很高,您的帧速率也会下降。例如,请添加一些控制台日志,以查看您是否在画布上以及画布外重新渲染了很多!我注意到,当我也有大量与 Three.js\xe2\x80\x94 无关的 CPU 周期\xe2\x80\x94 重新渲染、计算等时,帧速率也会下降。

\n