3

再会!我有以下问题。图形模型未正确显示:模型的某些应被正面隐藏的背面仍然可见。以下是一些需要澄清的例子:(等距)在此处输入图像描述

(问题)

在此处输入图像描述

在应用光和材料时,这个问题尤其显着。所以问题是如何为 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
            );
        }
    }

}
4

3 回答 3

3

我一直在玩你的样本,我想我已经找到了你的问题的原因。

首先,我检查了面的缠绕。它们都是逆时针的,所以它们的所有法线都向外,应该是这样。

然后我修改了其他顶点而不是最后一个。在某些情况下没有问题,在其他情况下,问题仍然存在。

基本上,当存在“凹”面时会出现问题,这意味着两个面的法线会交叉。当所有表面都是“凸的”时,它不会发生,这意味着它们的法线指向外面并且不会交叉。

这是从这里拍摄的两种网格的清晰图像:

在此处输入图像描述

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

问题

但是,如果我们不修改顶点#7,而是使#5 更大,我们有一个凸网格,没有渲染问题:

没有任何问题

显然,虽然这解决了渲染问题,但它会改变您的初始形状。

如果您想保留初始几何形状,另一种可能的解决方案是更改面,因此您没有任何凹面区域。

让我们看看面 5-1-3 和 5-3-7,假设我们现在要移动顶点 #1。

如果我们保留您的三角形,面 5-1-3 和 5-3-7 将定义一个要渲染的凹面(它们的法线将交叉),而如果我们将这些三角形更改为 5-1-7 和 1-3- 7,然后表面将是凸的(它们的法线不会交叉):

法线

回到你的初始形状,这两个面的变化将解决渲染问题。

解决了

虽然顶点相同,但几何形状略有不同。所以它需要一些细化(更多元素)。添加这些元素应该牢记这个凸概念。但是,正如您在此处看到的那样,问题并非微不足道。

于 2016-07-24T16:31:30.123 回答
1

Jose 的分析很好,但在我看来,OP 似乎只是忘记在他的这行代码中将宽度除以 2。

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

应该

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

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

于 2016-07-24T17:52:29.720 回答
0

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

Shape3D#cullFaceProperty

于 2016-07-24T08:57:57.163 回答