java - 如何将多个 3D 对象合并为单个网格以消除视觉故障?

标签 java javafx mesh terrain javafx-3d

我一直在使用 JavaFX 3D 进行大量体素地形生成。由于某种原因,每当我生成景观时,景观的右侧总会有这些奇怪的黑线。我尝试更改 PerspectiveCamera 的近距和远距剪辑值,但它们似乎没有效果。如果您需要,我的近剪辑值设置为 0.1,远剪辑值设置为 100000.0

这是我的程序的图片,如您所见,主要在景观的右侧存在明显的视觉故障。

我很确定视觉故障是由每个立方体都是其自己的对象这一事实引起的。因此,在上图中,我创建了 22500 个立方体对象,并用调整后的颜色放置它们以形成景观。

有没有办法创建一个巨大的网格来替换我的大量立方体对象,同时仍然保留颜色?

感谢您的帮助!

最佳答案

合并立方体

使用ScatterMesh来自FXyz library您可以将立方体对象中的所有单独网格(我认为每个立方体都是一个 Box)合并为一个大三角形网格,同时保持其独特的颜色。

假设您有一组 3D 坐标,每个坐标定义一个立方体,以及每个坐标(立方体)的给定颜色,这个小代码片段演示了如何做到这一点。它基于 CUBE 标记的使用,将为散点图中的每个点创建一个 CuboidMesh

List<Double> coordinates = Arrays.asList(x0,y0,z0,...); // n points
List<Color> colors = Arrays.asList(new Color(),...); // n colors

// create org.fxyz3d.geometry.Point3D for each cube with x,y,z,f (index of color)
List<Point3D> cubes = new ArrayList<>();

AtomicInteger i = new AtomicInteger();
colors.stream()
      .forEach(c -> cubes.add(new Point3D(coordinates.get(i.getAndIncrement()), 
                coordinates.get(i.getAndIncrement()), 
                coordinates.get(i.getAndIncrement()),
                colors.indexOf(c))));

// create scatterMesh from cubes, each cube with a size of 20 pixels
ScatterMesh scatterMesh = new ScatterMesh(cubes, 20);

// apply `CUBE` marker
scatterMesh.setMarker(MarkerFactory.Marker.CUBE);

// apply same `f` value to all 8 vertices of each cube
scatterMesh.setFunctionData(cubes.stream()
            .flatMap(p -> Collections.nCopies(8, p.f).stream()).collect(Collectors.toList()));

// Apply texture based on the list of colors 
scatter.setTextureModeVertices3D(new Palette.ListColorPalette(colors), p -> p.f);

通过这种方法,您将得到一个网格。可以使用 PickResult 和一些从给定坐标查找立方体的逻辑来访问立方体。

可以简化识别给定地形高度的立方体的另一个选项是每个给定高度使用ScatterMesh(将具有相同的颜色):

List<ScatterMesh> scatterMeshList = new ArrayList<>();

// Collect different heights
List<Float> heights = cubes.stream()
            .map(b -> b.z)
            .distinct()
            .collect(Collectors.toList());


scatterMeshList = heights.stream()
        .map(h -> {
            List<Point3D> cubesPerH = cubes.stream()
                    .filter(p -> p.z == h)
                    .collect(Collectors.toList());
            int colorIndex = (int)cubesPerH.get(0).f;

            ScatterMesh scatterMesh = new ScatterMesh(cubesPerH, 20);
            scatterMesh.setMarker(MarkerFactory.Marker.CUBE);
            scatterMesh.setTextureModeNone(colors.get(colorIndex));
            return scatterMesh;
        })
    .collect(Collectors.toList());

文物

就性能而言,使用单个或少量的散点网格而不是数百或数千个立方体网格显然会更好。

但是,这可能无法解决使用给定纹理渲染 JavaFX 3D 形状时出现的伪影问题。这是一个已知问题,但我没有发现它被归档,所以它绝对应该是 reported .

关于java - 如何将多个 3D 对象合并为单个网格以消除视觉故障?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59454190/

相关文章:

java - 非动态未排序数组列表的删除不会是 O(n) 吗?

java - 为什么这个 JavaFX 应用程序看起来与 SceneBuilder 中的应用程序有很大不同?

java - 如何创建具有正确宽度和高度的垂直标签?

c# - 平滑 3D 文件

java - 删除无响应的 channel - java

java - 元素在点不可点击。其他元素会收到点击 :

java - 尽管使用 @Primary,但两个同名的 bean 会导致 ConflictingBeanDefinitionException

java - 可以覆盖 Java webstart 对话框标题吗?

c++ - CGAL - boost 创建无向图

algorithm - 阅读网格算法和网格库