三角网格 - 背面面片可见

3

大家好!我遇到了以下问题。图形模型显示不正确:一些前面应该被后面隐藏的模型背面仍然可见。这里有一些示例以澄清问题:(等距投影)enter image description here

(问题)

enter image description here

应用光线和材料时,这个问题尤其明显。所以问题是如何解决JavaFX中的这个问题?

更新:

public class VertexTest extends Application {

    PerspectiveCamera camera;
    Cam cam = new Cam();
    double mouseOldX, mouseOldY, mousePosX, mousePosY, mouseDeltaX, mouseDeltaY;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        TriangleMesh mesh = new Shape3DRectangle(100, 100, 100);
        MeshView view = new MeshView(mesh);
        view.setDrawMode(DrawMode.LINE);
        view.setMaterial(new PhongMaterial(Color.RED));

        cam.getChildren().add(view);

        Scene scene = new Scene(cam, 1000, 1000, true);

        addEvents(view, scene);

        camera = new PerspectiveCamera();
        camera.setTranslateX(-500);
        camera.setTranslateY(-500);
        camera.setTranslateZ(1000);


        scene.setCamera(camera);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void addEvents(MeshView view, Scene s) {

        s.setOnMouseDragged(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent me) {
                mouseOldX = mousePosX;
                mouseOldY = mousePosY;
                mousePosX = me.getX();
                mousePosY = me.getY();
                mouseDeltaX = mousePosX - mouseOldX;
                mouseDeltaY = mousePosY - mouseOldY;
                cam.ry.setAngle(cam.ry.getAngle() - mouseDeltaX);
                cam.rx.setAngle(cam.rx.getAngle() + mouseDeltaY);
            }
        });
    }

    class Cam extends Group {
        Translate t = new Translate();
        Translate p = new Translate();
        Translate ip = new Translate();
        Rotate rx = new Rotate();
        {
            rx.setAxis(Rotate.X_AXIS);
        }
        Rotate ry = new Rotate();
        {
            ry.setAxis(Rotate.Y_AXIS);
        }
        Rotate rz = new Rotate();
        {
            rz.setAxis(Rotate.Z_AXIS);
        }
        Scale s = new Scale();

        public Cam() {
            super();
            getTransforms().addAll(t, p, rx, rz, ry, s, ip);
        }
    }



    public class Shape3DRectangle extends TriangleMesh {

        public Shape3DRectangle(float Width, float Height, float deep) {

            this.getPoints().setAll(-Width / 2, Height / 2, deep / 2, // idx p0
                    Width / 2, Height / 2, deep / 2, // idx p1
                    -Width / 2, -Height / 2, deep / 2, // idx p2
                    Width / 2, -Height / 2, deep / 2, // idx p3
                    -Width / 2, Height / 2, -deep / 2, // idx p4
                    Width / 2, Height / 2, -deep / 2, // idx p5
                    -Width / 2, -Height / 2, -deep / 2, // idx p6
                    Width, -Height / 2, -deep / 2 // idx p7
            );

            this.getTexCoords().addAll(0.0f, 0.0f);

            this.getFaces().addAll(5, 0, 4, 0, 0, 0 // P5,T1 ,P4,T0 ,P0,T3
                    , 5, 0, 0, 0, 1, 0 // P5,T1 ,P0,T3 ,P1,T4
                    , 0, 0, 4, 0, 6, 0 // P0,T3 ,P4,T2 ,P6,T7
                    , 0, 0, 6, 0, 2, 0 // P0,T3 ,P6,T7 ,P2,T8
                    , 1, 0, 0, 0, 2, 0 // P1,T4 ,P0,T3 ,P2,T8
                    , 1, 0, 2, 0, 3, 0 // P1,T4 ,P2,T8 ,P3,T9
                    , 5, 0, 1, 0, 3, 0 // P5,T5 ,P1,T4 ,P3,T9
                    , 5, 0, 3, 0, 7, 0 // P5,T5 ,P3,T9 ,P7,T10
                    , 4, 0, 5, 0, 7, 0 // P4,T6 ,P5,T5 ,P7,T10
                    , 4, 0, 7, 0, 6, 0 // P4,T6 ,P7,T10 ,P6,T11
                    , 3, 0, 2, 0, 6, 0 // P3,T9 ,P2,T8 ,P6,T12
                    , 3, 0, 6, 0, 7, 0 // P3,T9 ,P6,T12 ,P7,T13
            );
        }
    }

}

1
如果没有代码,我只能说:祝你好运 - ΦXocę 웃 Пepeúpa ツ
@ΦXocę웃Пepeúpa 谢谢祝福 ) - Peter Slusar
3个回答

3

我一直在使用你们的样例进行试验,我发现了你们出现问题的原因。

首先,我检查了面的绕向。它们所有都是逆时针方向绕的,所以它们的法向量指向外部,符合要求。

然后我修改了最后一个顶点以外的其他点。在有些情况下没有问题,在其他情况下,问题仍然存在。

基本上,当存在“凹”表面时,也就是说两个面的法线将相交时,就会出现问题。而当所有表面都是“凸”的时候,也就是它们的法线指向外部并且不会相交时,则不会出现问题。

这是两种网格类型的清晰图像,取自这里

enter image description here

回到你的示例,你正在定义一个凹面网格:

issue

但是,如果我们不修改顶点#7,而是将#5变大,那么我们就会得到一个凸多边形网格,没有渲染问题:

no issue

显然,这样修复了渲染问题,但会改变原始形状。
如果您想保持初始几何形状,则另一个可能的解决方案是更改面部,以便您没有任何凹面区域。
让我们看一下5-1-3和5-3-7的面孔,假设现在我们要移动顶点#1。
如果我们保留三角形,则面5-1-3和5-3-7将定义一个凹面(它们的法线会交叉),而如果我们将这些三角形更改为5-1-7和1-3-7,则表面将是凸面(它们的法线不会交叉):

normals

回到初始形状,对这两个面的更改将解决渲染问题。

Solved

虽然顶点是一样的,但几何形状有些不同。因此需要进行一些细化(增加更多元素)。添加这些元素时应该牢记这个凸概念。问题并不简单,如你所见here


我想感谢您对JavaFx技术相关问题的所有回答。不幸的是,我需要处理的对象由数百万个面和复杂形状组成。最重要的是,我在您的回复中找到了正确的方向,特此致谢。 - Peter Slusar
很高兴能够帮到您,我发现了这个问题是基于您的问题和示例代码,之前我没有想到过也没有在其他地方找到过。可能应该在文档中提到... - José Pereda

1
Jose做出了不错的分析,但在我看来,OP只是忘记在代码中这一行将宽度除以2。
Width, -Height / 2, -deep / 2 // idx p7

应该是

Width / 2, -Height / 2, -deep / 2 // idx p7

这个类被称为Shape3DRectangle,但由于这个错误,几何形状不再是矩形了。

也许这是个笔误,但原帖清楚地询问了背面面的问题。这是一个可能的场景,你有一个立方体并开始扭曲它的顶点创建其他的3D形状,不总是均匀且凸面的。 - José Pereda
mipa @José Pereda 是正确的。类名来自之前的测试...我的错... - Peter Slusar

0
您可以为每个Shape3D设置cullFaceProperty。我猜这是您所需要的,但我不确定我是否准确理解了您的问题。

Shape3D#cullFaceProperty


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接