How to fill a JavaFX Sphere with two Colors

5.6k Views Asked by At

How can I fill in JavaFX a 3D Sphere with a linear gradient like a 2d Circle? I work with the JavaFX Scene Builder.

enter image description here

enter image description here

2

There are 2 best solutions below

0
On BEST ANSWER

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):

diffuse image

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:

sphere

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:

Sphere FXyz

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.

0
On

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: enter image description here

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.