Java 如何将多个3D对象合并为单个网格以消除视觉故障?
我已经用JavaFX3D做了很多体素地形生成。出于某种原因,每当我生成一幅风景画时,风景画的右侧总是有这些奇怪的黑线。我尝试更改透视摄影机的“近”和“远”剪辑值,但它们似乎没有效果。如果需要,我的近片段值设置为Java 如何将多个3D对象合并为单个网格以消除视觉故障?,java,javafx,mesh,terrain,javafx-3d,Java,Javafx,Mesh,Terrain,Javafx 3d,我已经用JavaFX3D做了很多体素地形生成。出于某种原因,每当我生成一幅风景画时,风景画的右侧总是有这些奇怪的黑线。我尝试更改透视摄影机的“近”和“远”剪辑值,但它们似乎没有效果。如果需要,我的近片段值设置为0.1,远片段值设置为100000.0 这是我的程序的一张图片,正如你所看到的,有明显的视觉故障主要出现在画面的右侧。 我很确定这个视觉小故障是由每个立方体都是它自己的对象这一事实造成的。因此,在上图中,我创建了22500个立方体对象,并用调整后的颜色放置它们,以形成景观 有没有办法创建
0.1
,远片段值设置为100000.0
这是我的程序的一张图片,正如你所看到的,有明显的视觉故障主要出现在画面的右侧。
我很确定这个视觉小故障是由每个立方体都是它自己的对象这一事实造成的。因此,在上图中,我创建了22500个立方体对象,并用调整后的颜色放置它们,以形成景观
有没有办法创建一个巨大的网格来替换我的大量立方体对象,同时仍然保留颜色
谢谢你的帮助 合并多维数据集 使用from,您可以将立方体对象中的所有单个网格(我认为每个立方体都是一个
框
)合并到一个大三角形网格中,同时保持其唯一的颜色
假设您有一组三维坐标,每个坐标定义一个立方体,每个坐标(立方体)有一个给定的颜色,这个小代码片段演示了如何执行此操作。它基于使用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);
工件
在性能方面,使用单个或少量散射网格而不是数百或数千个立方体网格显然更好
但是,这可能无法解决使用给定纹理渲染JavaFX 3D形状时出现的瑕疵问题。这是一个已知的问题,但我没有发现它已归档,因此它肯定会归档。您启用深度缓冲区了吗?这看起来像是距离摄影机较远的物体被渲染在距离较近的物体之上…@fabian在
场景的构造函数中启用深度缓冲后,结果仍然相同。检查FXyz库,有一个用于合并网格的实用程序类。每个立方体都可以保留颜色数据,以便以后可以使用它轻松生成纹理贴图。每个立方体将是一个三角形网格
(例如,您可以使用长方体网格
),因为需要访问网格数据(长方体不会导出它)。基本上,每个体素所需的只是其中心的3D坐标和一个可以映射到调色板的浮点值(当然还有体素的大小)。你的项目是OSS吗?我问你的项目是否是开源的,所以我可以帮你(也许你也愿意为FXyz做贡献)。否则,当我有时间时,我将尝试添加一个关于如何管理纹理的答案。
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());