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

时间:2018-06-21 19:41:05

标签: 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, CycleMethod.REPEAT, /*arbitrary/irrelevant color Stop objects*/));
    PhongMaterial pm = new PhongMaterial();
    pm.setDiffuseMap(pm);
    sphere.setMaterial(asdf);

现在显然该代码不起作用,但我想这就是我要尝试执行的操作的想法/流程。

1 个答案:

答案 0 :(得分:3)

您对一件事是正确的,PhongMaterialColor用作漫反射颜色,而不允许使用Gradient。为此,它应该接受Paint,但事实并非如此。

所以我们必须寻找不同的选择。

DiffuseMap

如果选中PhongMaterial,则可以将diffuse map设置为图像。这意味着您可以使用具有一定梯度的现有图像并将其应用于球体。

类似这样的东西:

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

将产生以下结果:

动态DiffuseMap

显然,这具有依赖静态图像的缺点。如果要动态修改该怎么办?

如果您生成径向渐变,则可以执行此操作,将其渲染到辅助场景上并对其进行快照。该快照返回一个WritableImage,您可以直接将其用作漫反射贴图。

类似这样的东西:

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,但是您必须创建自己的TriangleMesh并使用纹理坐标,或者您可以简单地使用开放源代码FXyz JavaFX 3D library,具有许多不同的基元和纹理选项。

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

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

请注意,这种情况下的功能仅基于z坐标,但是显然您可以根据需要进行修改。

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