Почему 3d-модель рендерится в SubScene иначе, чем в Scene

Отрисовывается с флагом, установленным в значение true, камера устанавливается в подцену, а затем поворачивается:

Вынесено

Ксилофон отображается в SubScene:

Ксилофон отображается в SubScene

Ксилофон, представленный в сцене:

Ксилофон отображается в сцене

Используя пример Oracle Xylophone 3D, я столкнулся с любопытной проблемой. ( Xylophone.java) Когда он отображается в сцене, он выглядит правильно. Когда он отображается в SubScene, это не так. Кто-нибудь сталкивался с этим? Есть ли решение или обходной путь?

Вот модифицированный код, который создает SubScene:

final SubScene sub = new SubScene(camOffset, 800,600, false, SceneAntialiasing.BALANCED);
    AnchorPane pane = new AnchorPane();
    pane.setDepthTest(DepthTest.ENABLE);
    pane.getChildren().add(sub);
    final Scene scene = new Scene(pane, 800, 600, true);

1 ответ

Попробуйте установить для параметра DepthBuffer-flag (4-й параметр) значение true в своем конструкторе SubScene: final SubScene sub = new SubScene(camOffset, 800,600, true, SceneAntialiasing.BALANCED); В трехмерном сценарии глубинный буфер необходим для сортировки по глубине (см., Например, https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Scene.html). Более того (если это еще не сделано) камеру следует назначить для вспомогательной сцены, а не для сцены: sub.setCamera(new PerspectiveCamera()); Тогда все должно работать как положено.

Редактировать:
Кроме того, применение градиента к заливке подцены, похоже, не работает, см. https://bugs.openjdk.java.net/browse/JDK-8088605
https://www.youtube.com/watch?v=LGx4CV_K5U8&feature=youtu.be
Возможный обходной путь - применение градиента к панели, содержащей подцену.

В общем, в start-методе ксилофон-класса замените

final Scene scene = new Scene(camOffset, 800, 600, true);
scene.setFill(new RadialGradient(225, 0.85, 300, 300, 500, false,
                                  CycleMethod.NO_CYCLE, new Stop[]
                                  { new Stop(0f, Color.BLUE),
                                    new Stop(1f, Color.LIGHTBLUE) }));
scene.setCamera(new PerspectiveCamera());

с

final SubScene sub = new SubScene(camOffset, 800,600, true, SceneAntialiasing.BALANCED); // set depthBuffer = true
sub.setCamera(new PerspectiveCamera());
AnchorPane pane = new AnchorPane();
pane.setDepthTest(DepthTest.ENABLE);
pane.getChildren().add(sub);
final Scene scene = new Scene(pane, 800, 600, true);
// Shift the RadialGradient from the Scene to the AnchorPane (and NOT to the SubScene).
RadialGradient radialGradient = new RadialGradient(225, 0.85, 300, 300, 500, false,
                                                   CycleMethod.NO_CYCLE, new Stop[]
                                                   { new Stop(0f, Color.BLUE),
                                                     new Stop(1f, Color.LIGHTBLUE) });
pane.setBackground(new Background(new BackgroundFill(radialGradient, CornerRadii.EMPTY, Insets.EMPTY)));

Этот код работает на моей машине.

Другие вопросы по тегам