如何将多个3D对象合并为单个网格,以消除视觉上的毛刺? [英] How to merge multiple 3D objects as a single Mesh in order to remove a visual glitch?

查看:240
本文介绍了如何将多个3D对象合并为单个网格,以消除视觉上的毛刺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用JavaFX 3D进行了大量体素地形生成.出于某种原因,每当生成景观时,景观的右侧将始终具有这些怪异的黑线.我试过更改PerspectiveCamera的近和远剪辑值,但是它们似乎没有作用.如果需要,我的近场剪辑值设置为0.1,而我的远场剪辑值设置为100000.0.

I've been doing a lot of voxel terrain generation with JavaFX 3D. For some reason, whenever I generate a landscape, the right side of the landscape will always have these weird black lines. I've tried changing the PerspectiveCamera's near and far clip values, but they seem to have no effect. In case you need it, my near clip value is set to 0.1 and my far clip value is set to 100000.0.

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

Here is a picture of my program, as you can see, there are clear visual glitches present mainly on the right side of the landscape.

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

I'm pretty sure the visual glitch is caused by the fact that each cube is its own object. So in the image above, I create 22500 cube objects and placed them with adjusted colors to form the landscape.

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

Is there a way to create a massive Mesh to replace my large amounts of cube objects, while still retaining the colors?

感谢您的所有帮助!

推荐答案

合并多维数据集

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

With the use of ScatterMesh from the FXyz library you can merge all the individual meshes from your cube objects (I take each cube is a Box), into one single big triangle mesh, while keeping their unique color.

鉴于您有一组3D坐标,每个坐标定义一个立方体,并且每个坐标(立方体)具有给定的颜色,因此此小代码段演示了如何进行此操作.它基于CUBE标记的使用,将在散点图中的每个点创建一个CuboidMesh.

Given that you have a set of 3D coordinates, each one defining a cube, and a given color per coordinate (cube), this small code snippet demonstrates how to do it. It is based on the use of CUBE markers that will create a CuboidMesh per each point in the scatter plot.

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和一些逻辑从给定坐标中找到多维数据集来访问多维数据集.

With this approach you will have as a result a single mesh. Accessing the cubes can be done with PickResult and some logic to find the cube from the given coordinates.

可以简化标识给定地形高度的多维数据集的另一种方法是在每个给定高度使用ScatterMesh(颜色相同):

Another option that could simplify identifying cubes of a given terrain height is to use a ScatterMesh per given height (that will have the same color):

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());

工件

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

Having a single or a small number of scatter meshes instead of hundreds or thousands of cube meshes is obviously better in terms of performance.

但是,这可能无法解决渲染具有给定纹理的JavaFX 3D形状时出现的工件问题.这是一个已知问题,但是我没有找到它,因此绝对应该已报告.

However, this might not solve the issue with the artifacts that appear when rendering a JavaFX 3D shape with a given texture. This is a known issue, but I didn't find it filed though, so it should definitely be reported.

这篇关于如何将多个3D对象合并为单个网格,以消除视觉上的毛刺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆