JavaFX 3D 适用于超过 100 万个 Box 对象

标签 java javafx 3d

我一直在使用 JavaFX 创建 3D 模型。我关注了this guide除了当我开始添加自己的数据时,一切都很顺利。作为一个最小的工作示例,请考虑上述指南中的示例应用程序(注意:您可能必须添加指南中缺少的以下类变量: doublemodifierFactor = 0.1;)并将 buildMolecule() 函数体替换为:

Random rand = new Random(System.currentTimeMillis());
int dim = 10;
int dimhalf = dim>>1;
for (int i = 0; i < dim; i++) {
    for (int j = 0; j < dim; j++) {
        for (int k = 0; k < dim; k++) {
            Box b = new Box(10, 10, 10);
            b.setTranslateX((i-dimhalf)*10);
            b.setTranslateY((j-dimhalf)*10);
            b.setTranslateZ((k-dimhalf)*10);
            b.setMaterial(new PhongMaterial(new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), 1.0)));
            root.getChildren().add(b);
        }
    }
}

运行应用程序(我使用附加标志-Xmx6g -Xms6g)并使用dim 的值来查看效果。如果您遇到闪烁问题(我遇到过,因为 Scene 实例上的 depthBuffering = true),请尝试设置 CAMERA_NEAR_CLIP = 100。您可能还需要将 CAMERA_INITIAL_DISTANCE 设置为 -1500 以获得更大的暗淡值。

对于暗度 < 20 的情况(在我的机器上)效果很好。对于暗度 = 30 的情况,初始渲染仍然很快,但标准操作(使用 LMB 旋转、使用 RMB 缩放以及使用 MMB 平移)很不稳定。如果将暗度增加到 70,则情况会变得越来越糟,此时初始渲染需要数秒,但与场景交互基本上是不可能的。

我面临着一种情况,我需要渲染 100 万到 1000 万个 Box 实例(所以暗淡 >= 100)。这可能吗?我可以使用一些技巧来提高性能吗?

对于那些感兴趣的人来说,底层模型是八叉树。

最佳答案

您当前方法的问题是您要添加一百万个独立的 3D 场景图节点,所有这些节点都必须进行管理、事件检测、渲染/遮挡等。无论您的渲染系统如何,这都不会发生。 对于像这样的超密集 3D 场景图,您需要将数据转换为单个连续的三角形网格,其三角形以相机仅显示数据点的方式缠绕。绝对不适合胆小的人,这就是为什么我们创建了 ScatterMesh classhttp://www.fxyz3d.org/ repo 以使其更容易。

目前还没有此类的示例,但以下是我如何使用它,如 2:05 of this video 所示。 :

DirectedScatterMesh periapsisMap3D = new DirectedScatterMesh(data, true, point3dSize, 0); periapsisMap3D.setDrawMode(DrawMode.FILL); //makes mini triangles solid periapsisMap3D.setTextureModeVertices3D(1530,colorByAngleOut); //colorByAngleOut is a Function that maps x,y numbers to a color.

setTextureModeVertices3D 允许您指定一个颜色图,然后将其转换为纹理,然后转换为 PhongMaterial,并精确地包裹在 3D 结构周围,以便您在函数中指定的颜色映射到正确的面。

下面是我的 colorByAngleOut 函数,因此您至少知道它是如何工作的:

Function colorByAngleOut = p-> Math.abs(Math.atan2(p.y, Math.sqrt(p.xp.x + p.zp.z))); //in javafx 3D y -> z and vice versa

其中 p 是一个三维点,我本质上是在计算航天器与黄道面的角度。

要添加整个 3D 结构(归根结底是一个美化的 TriangleMesh),就像将其添加到 3D 场景中一样简单,就像任何其他对象一样:

sceneRoot.getChildren().add(periapsisMap3D);

请注意,该视频实际上显示了 ScatterMesh 的修改版本,它允许定向四面体,从而允许渲染附加数据维度。当前 FXyz 版本不支持此功能,它是我进行的自定义,不是开源的。

关于JavaFX 3D 适用于超过 100 万个 Box 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44655920/

相关文章:

java - 嵌套异常是 java.lang.IncompatibleClassChangeError : org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor

JavaFX 时间轴播放 slider 在异步时间点触发事件

java - 如何更改 JavaFX DateTime API 中 LocalDate 的开始时间和结束时间

java - 如何在 CloudBees Jenkins 中选择我的 JDK 版本?

java - java实现归并排序出错?

java - 在java 2d中采摘

r - 如何使用 R 绘制 3D 矩阵的 3D 曲面

3d - 将 3d 坐标向量归一化为介于 0 和 1 之间

java - android - MapFragment 位于 Fragment 内的 ScrollView 内

java - 如何在 IDE 之外启动 JavaFX 11 应用程序?