JavaFX8 Z缓冲区问题

JavaFX8 Z缓冲区问题,java,javafx,javafx-8,javafx-3d,Java,Javafx,Javafx 8,Javafx 3d,我的问题是javafx3d中的Z-Buffer,它似乎不能在我的机器上正常工作 我知道一些问题: 和 但是,我确实启用了Z缓冲区,节点仍然按照添加到场景图的顺序进行渲染 也许我缺少了一些依赖关系或其他什么 我正在发布代码,希望有人能帮我。我正在创建一个转换,在椭圆路径上围绕另一个节点移动节点 提前谢谢你 public class OrbitExp extends Application { Group root = new Group(); Scene scene = new Scene(ro

我的问题是javafx3d中的Z-Buffer,它似乎不能在我的机器上正常工作

我知道一些问题: 和

但是,我确实启用了Z缓冲区,节点仍然按照添加到场景图的顺序进行渲染

也许我缺少了一些依赖关系或其他什么

我正在发布代码,希望有人能帮我。我正在创建一个转换,在椭圆路径上围绕另一个节点移动节点

提前谢谢你

public class OrbitExp extends Application {
Group root = new Group();
Scene scene = new Scene(root, 800, 600, true, SceneAntialiasing.BALANCED);
PerspectiveCamera camera = new PerspectiveCamera();
@Override
public void start(Stage primaryStage) {
    root.setDepthTest(DepthTest.ENABLE); 
//Tried to set Depthtest explicitly. Assumed maybe it did not inherit:S
    System.out.println(
        "3D supported? " +
        Platform.isSupported(ConditionalFeature.SCENE3D)
    );    // returns true

    System.out.println("root z-buffer: " + root.getDepthTest());
    initCamera();
    Box 
            box1 = new Box(50,50,50),
            box2 = new Box(10,10,10);
    root.setTranslateX(scene.getWidth()/2);
    root.setTranslateY(scene.getHeight()/2);
    PhongMaterial 
            pmat = new PhongMaterial(Color.BLUE),
            pmat2 = new PhongMaterial(Color.RED);
    box1.setMaterial(pmat);
    box2.setMaterial(pmat2);
    scene.setFill(Color.LIGHTGREEN);
    root.getChildren().addAll(box1,box2);
    SequentialTransition sqt = orbit(box1, box2, 40, 40, Duration.seconds(3), 360);
    sqt.play();
    scene.setOnMouseClicked(click->{
        Node node = (Node)(click.getPickResult().getIntersectedNode());
        System.out.println("Tx: "+node.getTranslateX());
        System.out.println("Ty: "+node.getTranslateY());
        System.out.println("Tz: "+node.getTranslateZ());
    }); 
// just for debugging, but coords does seem to be alright
    primaryStage.setScene(scene);
    primaryStage.show();
}
public static void main(String[] args) {
    launch(args);
}
private void initCamera() {
    camera.setTranslateZ(-50);
    camera.setTranslateY(20);
    camera.setFarClip(5000);
    camera.setNearClip(0);
    scene.setCamera(camera);
}
SequentialTransition orbit(Node node1, Node node2,double a, double b, Duration totalDuration, int N) {
    SequentialTransition sqt = new SequentialTransition();
    Duration dur = new Duration(totalDuration.toMillis()*(1.0d/N));
    node2.setTranslateX(a+node1.getTranslateX());
    node2.setTranslateZ(node1.getTranslateZ());
    for (int i = 1; i < N; i++) {
        TranslateTransition tt = new TranslateTransition(dur, node2);
        double 
                angle = i*(360.0d/N),
                toX = (Math.cos(Math.toRadians(angle))*a)+node1.getTranslateX(),
                toZ = (Math.sin(Math.toRadians(angle))*b)+node1.getTranslateZ();
        tt.setToX(toX);
        tt.setToZ(toZ);
        tt.setInterpolator(Interpolator.LINEAR);
        sqt.getChildren().add(tt);
        System.out.println("angle = " + angle + "\nangle in rads: " + Math.toRadians(angle) + "\ntoX = " + toX + "\ntoZ = " + toZ);
    }
    sqt.setCycleCount(Timeline.INDEFINITE);
    return sqt;
}
公共类OrbitExp扩展应用程序{
组根=新组();
Scene Scene=新场景(root,800600,true,sceneatialiasing.BALANCED);
透视摄影机=新透视摄影机();
@凌驾
公共无效开始(阶段primaryStage){
root.setDepthTest(DepthTest.ENABLE);
//试图显式设置Depthtest。假定它可能没有继承:S
System.out.println(
“是否支持3D?”+
平台支持(ConditionalFeature.SCENE3D)
);//返回true
System.out.println(“根z缓冲区:+root.getDepthTest());
initCamera();
盒子
框1=新框(50,50,50),
框2=新框(10,10,10);
root.setTranslateX(scene.getWidth()/2);
root.setTranslateY(scene.getHeight()/2);
语音材料
pmat=新的语音材料(颜色为蓝色),
pmat2=新的语音材料(颜色为红色);
框1.设置材料(pmat);
框2.设置材料(pmat2);
场景。设置填充(颜色。浅绿色);
root.getChildren().addAll(框1、框2);
顺序转换sqt=轨道(框1,框2,40,40,持续时间。秒(3),360);
sqt.play();
scene.setOnMouseClicked(单击->{
Node Node=(Node)(单击.getPickResult().getIntersectedNode());
System.out.println(“Tx:+node.getTranslateX());
System.out.println(“Ty:+node.getTranslateY());
System.out.println(“Tz:+node.getTranslateZ());
}); 
//只是为了调试,但是coords看起来还不错
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
专用照相机(){
照相机.setTranslateZ(-50);
摄像机。setTranslateY(20);
相机。setFarClip(5000);
摄像头。设置近夹(0);
场景。设置摄像机(摄像机);
}
顺序过渡轨道(节点1,节点2,双a,双b,持续时间totalDuration,int N){
顺序转换sqt=新的顺序转换();
Duration dur=新的持续时间(totalDuration.toMillis()*(1.0d/N));
node2.setTranslateX(a+node1.getTranslateX());
node2.setTranslateZ(node1.getTranslateZ());
对于(int i=1;i
}


顺便说一句,这是我的第一篇文章:)

如果您使用矩形检查您提供的代码,深度缓冲区工作正常

将矩形更改为使用三维长方体也可以

问题是如何定义一个框与另一个框相关的旋转,因此,我没有像您一样使用
RotateTransition
TranslateTransition
SequentialTransition
,而是对红色框应用了
Rotate
变换,将轴设置在蓝色框的中心,并使用
AnimationTimer
修改旋转角度以创建“环绕”效果

您甚至可以在大盒子上使用透明度(因为8u60)来查看它下面的小盒子

private final Group shapes = new Group();
private long lastTimerCall;
private AnimationTimer timeline;

@Override
public void start(Stage stage) throws Exception {
    Scene scene = new Scene(createRotatingShapes(), 400, 300,
            true, SceneAntialiasing.BALANCED);
    scene.setFill(Color.LIGHTGREEN);
    final PerspectiveCamera camera = new PerspectiveCamera();
    camera.setRotationAxis(Rotate.X_AXIS);
    camera.setRotate(10);
    camera.setTranslateZ(200);
    scene.setCamera(camera);

    stage.setScene(scene);
    stage.show();
}

private Group createRotatingShapes() {
    final Box box1 = new Box(50, 50, 50);
    // Transparency in box1: last node of the group
    box1.setMaterial(new PhongMaterial(Color.web("#0000FF80")));

    box1.setTranslateZ(50);

    final Box box2 = new Box(10, 10, 10);
    box2.setMaterial(new PhongMaterial(Color.RED));

    box2.setTranslateZ(-50);

    shapes.getChildren().addAll(box2, box1);

    shapes.setTranslateX(200);
    shapes.setTranslateY(150);

    rotateAroundYAxis(box2);

    return shapes;
}

private int count = 0;
private void rotateAroundYAxis(Node node) {
    Rotate r = new Rotate(0, 0, 0, 100, Rotate.Y_AXIS);
    node.getTransforms().add(r);
    lastTimerCall = System.nanoTime();
    timeline = new AnimationTimer() {
        @Override public void handle(long now) {
            if (now > lastTimerCall + 100_000_000l) {
                r.setAngle((count++)%360);
            }
        }
    };
    timeline.start();
}


@Override
public void stop() {
    timeline.stop();
}
在盒子前面:

蓝色盒子后面:

编辑

如果您查看了摄像头JavaDoc的
nearClip

指定距离的近剪裁平面的眼睛的距离 这台相机位于眼睛坐标空间中。 不绘制比nearClip更靠近眼睛的对象。 nearClip被指定为大于零的值。没有价值 大于或等于零被视为非常小的正数

(黑体字是我的)

因此,代码的问题在于这一行:

camera.setNearClip(0);
只需将其更改为:

camera.setNearClip(0.01);

它将如您所期望的那样工作。

感谢您的快速回答,我确实看到您的解决方案运行良好,我很乐意接受它作为一个答案。但是,我不明白为什么在我的程序中,cube1在cube2之后仍然在cube2之前呈现,请澄清“如何定义一个框与另一个框的旋转”。万分感谢!旋转r
使用两个框之间的距离
pivotZ=100
,因此只需旋转红色框即可。使用深度缓冲区时,组中框的顺序无关,只需在蓝色框中设置透明度。如果您切换顺序,它将工作,但蓝色框将不透明。请检查您的相机设置并更改此设置:
camera.setNearClip(0.01)。你的代码现在可以工作了。我用这个编辑了我的答案。错误的剪辑设置很微妙。我在中也偶然发现了这一点,在那里我调试了一段时间并提出了一个解决方案,但最后,我注意到询问者只是设置了错误的剪裁平面。(在以后关于~“JavaFX中的奇数渲染问题”的问题中,我将首先检查剪裁平面…)+顺便说一句谢谢,现在一切都好了。一切都在按原意呈现。我不知道将camera nearClip设置为0可能会导致问题。文档中说:“小于或等于