How to merge multiple 3D objects as a single Mesh in order to remove a visual glitch?

◇◆丶佛笑我妖孽 提交于 2020-01-15 08:55:50

问题


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.

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?

Thanks for all your help!


回答1:


Merging cubes

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.

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

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.

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

Artifacts

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.

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.



来源:https://stackoverflow.com/questions/59454190/how-to-merge-multiple-3d-objects-as-a-single-mesh-in-order-to-remove-a-visual-gl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!