Apply gradient to sphere object with JavaFX

泪湿孤枕 提交于 2019-12-23 17:00:50

问题


I'm working in JavaFX for a class, and I'm trying to apply a gradient to a sphere, but (obviously), I can't figure out how to do it. I'm stuck because I know that a sphere is an object, and so it needs to have a material, but (as far as colors go), a PhongMaterial only takes one color, and so it won't take a gradient because a gradient is a range of colors. So basically what I'm trying to is the following:

    Sphere sphere = new Sphere(50);
    RadialGradient rg = new RadialGradient(0, 0, 0, 0, 5, true, CycleMethod.REPEAT, /*arbitrary/irrelevant color Stop objects*/));
    PhongMaterial pm = new PhongMaterial();
    pm.setDiffuseMap(pm);
    sphere.setMaterial(asdf);

Now obviously this code doesn't work, but I guess it's the idea/flow of what I'm trying to do.


回答1:


You are right about one thing, PhongMaterial takes a Color as diffuse color, and that doesn't allow a Gradient. For that, it should accept Paint, but that is not the case.

So we have to look for different alternatives.

DiffuseMap

If you check PhongMaterial, you can set the diffuse map with an image. That means that you can use an existing image with some gradient and apply it to the sphere.

Something like this:

Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image("http://westciv.com/images/wdblogs/radialgradients/simpleclorstops.png"));
sphere.setMaterial(material);

will produce the following result:

Dynamic DiffuseMap

Obviously, this has the disadvantage of depending on a static image. What if you want to modify that dynamically?

You can do that, if you generate your radial gradient, render it on a secondary scene and take a snapshot of it. This snapshot returns a WritableImage that you can use directly as diffuse map.

Something like this:

Scene aux = new Scene(new StackPane(), 100, 100, 
        new RadialGradient(0, 0, 0.5, 0.5, 1, true, CycleMethod.REPEAT, 
                new Stop(0, Color.GREEN), new Stop(0.4, Color.YELLOW), 
                new Stop(0.6, Color.BLUE), new Stop(0.7, Color.RED)));
WritableImage snapshot = aux.snapshot(null);

Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(snapshot);
sphere.setMaterial(material);

You will have now:

Density Map

There is still another option to use a mathematical function to generate a density map, and the colors will be given by a mapping to that function.

For that you can't use the built-in Sphere, but you have to either create your own TriangleMesh and play with the texture coordinates, or you can simply use FXyz, an open source JavaFX 3D library with a number of different primitives and texture options.

For this case, you can get the library from Maven Central (org.fxyz3d:fxyz3d:0.3.0), use a SegmentedSphereMesh control, and then select the texture mode `Vertices3D:

SegmentedSphereMesh sphere = new SegmentedSphereMesh(100);
sphere.setTextureModeVertices3D(1530, p -> p.z);

Note the function in this case is just based on the z coordinate, but obviously you can modify that as needed.

Check the library (there is a sampler), to explore other options.



来源:https://stackoverflow.com/questions/50976389/apply-gradient-to-sphere-object-with-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!