How can I fill in JavaFX a 3D Sphere with a linear gradient like a 2d Circle? I work with the JavaFX Scene Builder.
The way to achieve gradient-like effects on 3D shapes is by applying lighting material and lighting position. You can't simply apply two colours that gradually transform into each other. I cooked for you a small app that shows just how to achieve this.
public class ShadedSphere extends Application {
public void start(Stage stage) {
StackPane layout = new StackPane();
layout.setPrefSize(300, 300);
Scene scene = new Scene(layout);
createScene(scene);
stage.setScene(scene);
stage.show();
}
private void createScene(Scene scene) {
PhongMaterial material = new PhongMaterial();
material.setDiffuseColor(Color.ORANGE);
material.setSpecularColor(Color.BLACK);
Sphere sphere = new Sphere(100);
sphere.setMaterial(material);
Pane root = (Pane) scene.getRoot();
root.getChildren().add(sphere);
}
public static void main(String[] args) {
launch(args);
}
}
Which will give you this:
If you change the location of the sphere (e.g., using setTranslateX()
and same for Y
and Z
), you should notice different effects of lighting on it; so the next thing for you to grasp is how to control location of lighting fixtures. Also, lights can have colour! Which means you can achieve even Northern Lights effects if you want to see cool stuff.
To learn a bit more about lighting, camera and effects, see this link.
As @mohsenmadi has pointed out, the diffuse color doesn't allow you using other than one single color.
But you can have different colors on the sphere by using an image as a diffuse map.
Based on your first image, I've created this texture image (called diffuse.jpg
, and placed under the same folder as the JavaFX class):
You can create now your bicolored sphere:
@Override
public void start(Stage primaryStage) throws Exception {
// 3D
Sphere sphere = new Sphere(5);
PhongMaterial phongMaterial = new PhongMaterial();
phongMaterial.setDiffuseMap(new Image(getClass().getResource("diffuse.jpg").toExternalForm()));
sphere.setMaterial(phongMaterial);
...
}
So you will see this:
Note that you may have some side effects on the poles.
You can also have a look at the FXyz project, a library with aditional JavaFX 3D complex shapes, and also complex texture options.
For instance, you can use a density map to create the same effect you want, but without providing the texture image.
Under org/fxyz/shapes/primitives
you can find several primitives like SegmentedSphereMesh
.
Like an sphere you can create one giving the number of divisions, the crop divisions (0 in this case for x and y), the radiuos, and the center:
SegmentedSphereMesh sphere = new SegmentedSphereMesh(200,0,0,100,new Point3D(0f,0f,0f));
Now you can define the function:
Function<Point3D, Number> dens = p->p.y>0?1:0;
and apply it, with the number of colors (2 in this case):
sphere.setTextureModeVertices3D(2,dens);
Now you will have this:
Now you won't have side effects on the poles, and you could modify this function easily to other cases.
Note that you can add create your own palette of colors or play with the HSB function under org/fxyz/utils/Palette
.