I am trying to use JavaFX3D to display 3D shapes but there is a problem with them rendering. The light is not working properly, filling darker sides with solid black color. I am using Sonoma 14.2.1 on MacBook Air M2 and JAVAFX sdk 21.0.1. I tried using both Java JDK 20 and 17.
The code I used is from this tutorial and expected this result: properly working box render
Instead I result in this: my box render
The same happens to the sphere shape: my sphere render
This is a code I used:
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Transform;
import javafx.stage.Stage;
/**
* @author afsal villan
* @version 1.0
*
* http://www.genuinecoder.com
*/
public class DrawingBox extends Application {
private static final int WIDTH = 1400;
private static final int HEIGHT = 1000;
private double anchorX, anchorY;
private double anchorAngleX = 0;
private double anchorAngleY = 0;
private final DoubleProperty angleX = new SimpleDoubleProperty(0);
private final DoubleProperty angleY = new SimpleDoubleProperty(0);
@Override
public void start(Stage primaryStage) {
Box box = new Box(100, 20, 50);
PhongMaterial material = new PhongMaterial();
material.setDiffuseColor(Color.AQUA);
box.setMaterial(material);
SmartGroup group = new SmartGroup();
group.getChildren().add(box);
Camera camera = new PerspectiveCamera();
Scene scene = new Scene(group, WIDTH, HEIGHT);
scene.setFill(Color.SILVER);
scene.setCamera(camera);
group.translateXProperty().set(WIDTH / 2);
group.translateYProperty().set(HEIGHT / 2);
group.translateZProperty().set(-1500);
initMouseControl(group, scene);
primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
switch (event.getCode()) {
case Z:
group.translateZProperty().set(group.getTranslateZ() + 100);
break;
case X:
group.translateZProperty().set(group.getTranslateZ() - 100);
break;
case S:
group.rotateByX(10);
break;
case W:
group.rotateByX(-10);
break;
case D:
group.rotateByY(10);
break;
case A:
group.rotateByY(-10);
break;
}
});
primaryStage.setTitle("Genuine Coder");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initMouseControl(SmartGroup group, Scene scene) {
Rotate xRotate;
Rotate yRotate;
group.getTransforms().addAll(
xRotate = new Rotate(0, Rotate.X_AXIS),
yRotate = new Rotate(0, Rotate.Y_AXIS)
);
xRotate.angleProperty().bind(angleX);
yRotate.angleProperty().bind(angleY);
scene.setOnMousePressed(event -> {
anchorX = event.getSceneX();
anchorY = event.getSceneY();
anchorAngleX = angleX.get();
anchorAngleY = angleY.get();
});
scene.setOnMouseDragged(event -> {
angleX.set(anchorAngleX - (anchorY - event.getSceneY()));
angleY.set(anchorAngleY + anchorX - event.getSceneX());
});
}
public static void main(String[] args) {
launch(args);
}
class SmartGroup extends Group {
Rotate r;
Transform t = new Rotate();
void rotateByX(int ang) {
r = new Rotate(ang, Rotate.X_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
void rotateByY(int ang) {
r = new Rotate(ang, Rotate.Y_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
}
}
Edit: We tested it on two other MacBooks, one with Sonoma installed, and one with the older - Ventura version. The Ventura version worked just fine, while Sonoma failed the same way.
Mesh rendering correctly on a M1 Mac running Mac OS 13.6.3
Mesh Rendering issue on M2 Mac running Mac OS 14.2.1
I also have JavaFX 21 Mesh PointLight/AmbientLight rendering issues on a M2 MacBookPro running Mac OS 14.2.1 (Sonoma) but NOT on an M1 MacBookAir running Mac OS 13.6.3. So this may be a Sonoma 14.2.1 issue. My example program, is from pages 254-267 of the Apress book "JavaFX 8 Introduction by Example", 2014, by C Dea, M. Heckler. G. Grunwald, J. Pereda, and S. Phillips.