使用JavaFX将渐变应用于球体对象

使用JavaFX将渐变应用于球体对象,javafx,javafx-8,gradient,radial-gradients,javafx-3d,Javafx,Javafx 8,Gradient,Radial Gradients,Javafx 3d,我在JavaFX中为一个类工作,我试图对一个球体应用一个渐变,但是(很明显),我不知道怎么做。我被卡住了,因为我知道一个球体是一个物体,所以它需要一个材质,但是(就颜色而言),一个PhongMaterial只需要一种颜色,所以它不需要渐变,因为渐变是一个颜色范围。所以基本上我想说的是: Sphere sphere = new Sphere(50); RadialGradient rg = new RadialGradient(0, 0, 0, 0, 5, true, CycleM

我在JavaFX中为一个类工作,我试图对一个球体应用一个渐变,但是(很明显),我不知道怎么做。我被卡住了,因为我知道一个球体是一个物体,所以它需要一个材质,但是(就颜色而言),一个PhongMaterial只需要一种颜色,所以它不需要渐变,因为渐变是一个颜色范围。所以基本上我想说的是:

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

现在很明显,这个代码不起作用,但我想这就是我想做的想法/流程。

有一点你是对的,
PhongMaterial
颜色
作为漫反射颜色,这不允许
渐变。为此,它应该接受
Paint
,但事实并非如此

因此,我们必须寻找不同的选择

扩散图

如果选中“PhongMaterial”
,则可以使用图像设置。这意味着您可以使用具有某种渐变的现有图像,并将其应用于球体

大概是这样的:

Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image("http://westciv.com/images/wdblogs/radialgradients/simpleclorstops.png"));
sphere.setMaterial(material);
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);
将产生以下结果:

动态扩散图

显然,这有依赖于静态图像的缺点。如果您想动态地修改它呢

您可以这样做,如果生成径向渐变,则在第二个场景中渲染它并对其进行快照。此快照返回一个
可写图像
,可直接用作漫反射贴图

大概是这样的:

Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image("http://westciv.com/images/wdblogs/radialgradients/simpleclorstops.png"));
sphere.setMaterial(material);
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);
您现在将拥有:

密度图

还有另一个选项可以使用数学函数生成密度贴图,颜色将通过映射到该函数而给出

为此,您不能使用内置的
球体
,但您必须创建自己的
三角网格
并使用纹理坐标,或者您可以简单地使用FXyz,一种开源JavaFX 3D,具有许多不同的基本体和纹理选项

对于这种情况,您可以从Maven Central(
org.fxyz3d:fxyz3d:0.3.0
)获取库,使用
SegmentedSphereMesh
控件,然后选择纹理模式“Vertices3D:

SegmentedSphereMesh sphere = new SegmentedSphereMesh(100);
sphere.setTextureModeVertices3D(1530, p -> p.z);
注意:本例中的函数仅基于
z
坐标,但显然您可以根据需要进行修改

检查库(有一个采样器),以探索其他选项