我一直在使用 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 class在 http://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/