关于Android平台PointLight无法正确照亮JavaFX 3D场景的问题咨询
I totally get the frustration here—dealing with 3D lighting inconsistencies across platforms can be a real headache. I've run into similar snags when working with Gluon Mobile and JavaFX 3D on Android, so let's break down what might be going on and how to fix it.
First, to clarify the core issue: When running a Gluon Mobile app on Android, PointLight fails to properly illuminate the 3D scene. While the app uses Gluon's framework, the root cause is likely tied to javafxport's implementation of JavaFX 3D on mobile.
Here's a complete, reproducible code snippet (I filled in the missing pieces to make it functional):
import com.gluonhq.charm.glisten.application.MobileApplication; import com.gluonhq.charm.glisten.control.AppBar; import com.gluonhq.charm.glisten.mvc.View; import com.gluonhq.charm.glisten.visual.MaterialDesignIcon; import javafx.animation.Interpolator; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.SceneAntialiasing; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.Box; import javafx.scene.transform.Rotate; import javafx.scene.PerspectiveCamera; import javafx.scene.PointLight; import javafx.util.Duration; public class LightingDemoView extends View { public LightingDemoView(String name) { super(name); // 3D Scene setup Group root = new Group(); Scene scene = new Scene(root, 300, 300, true, SceneAntialiasing.BALANCED); scene.setFill(Color.BLACK); // Create a cube to test lighting Box cube = new Box(50, 50, 50); cube.setMaterial(new PhongMaterial(Color.LIGHTGRAY)); // Add rotation to see all faces Timeline rotateTimeline = new Timeline( new KeyFrame(Duration.ZERO, new KeyValue(cube.rotationAxisProperty(), Rotate.Y_AXIS)), new KeyFrame(Duration.seconds(3), new KeyValue(cube.rotateProperty(), 360, Interpolator.LINEAR)) ); rotateTimeline.setCycleCount(Timeline.INDEFINITE); rotateTimeline.play(); root.getChildren().add(cube); // Add PointLight PointLight pointLight = new PointLight(Color.WHITE); pointLight.setTranslateX(80); pointLight.setTranslateY(80); pointLight.setTranslateZ(80); root.getChildren().add(pointLight); // Set up camera PerspectiveCamera camera = new PerspectiveCamera(true); camera.setTranslateZ(-250); scene.setCamera(camera); setCenter(scene); } @Override protected void updateAppBar(AppBar appBar) { appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> MobileApplication.getInstance().showLayer(MobileApplication.MENU_LAYER))); appBar.setTitleText("3D Lighting Test"); } }
Possible Causes & Fixes
JavaFX 3D Support Gaps on Android
javafxport's mobile implementation of JavaFX 3D isn't as fully featured as the desktop version. Lighting calculations, especially forPointLight, might be partially unimplemented or optimized differently for Android GPUs.Fix: Ensure you're using the latest stable versions of Gluon Mobile and javafxport—newer releases often patch mobile-specific 3D bugs. Update your Gradle dependencies:
dependencies { implementation 'com.gluonhq:charm:6.2.0' androidRuntime 'org.javafxports:jfxdvk:11.0.13' }Incorrect Material Type
PointLightrelies on Phong shading to render proper specular and diffuse lighting. If you're usingLambertMaterial(which only handles diffuse) or a custom material, the light might appear unresponsive.Fix: Stick with
PhongMaterialfor objects that need to react toPointLight:cube.setMaterial(new PhongMaterial(Color.LIGHTGRAY));Light or Camera Positioning Issues
If the light is positioned inside your 3D mesh, or the camera is too close/far, the lighting effect might be invisible entirely.Fix: Adjust the light's translation values to ensure it's outside the object bounds, and verify your camera is positioned to capture the lit surfaces:
// Move light away from the cube pointLight.setTranslateX(80); pointLight.setTranslateY(80); pointLight.setTranslateZ(80); // Position camera to view the cube clearly PerspectiveCamera camera = new PerspectiveCamera(true); camera.setTranslateZ(-250); scene.setCamera(camera);Test on Desktop First
Run the exact same code on a desktop platform (Windows/macOS/Linux). If the lighting works perfectly there, the issue is definitely Android-specific. In that case, you can file a detailed bug report with the javafxport or Gluon Mobile teams, including your reproducible code.
Final Notes
If none of the above fixes work, you might need to work around the issue by using alternative lighting setups (like multiple directional lights) or adjusting the material's specular/diffuse properties to compensate for the missing PointLight effect on Android.
内容的提问来源于stack exchange,提问作者Fabrice Bouyé

