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

Apply gradient to sphere object with JavaFX

我在 JavaFX 中工作 class,我正在尝试将渐变应用于球体,但(很明显)我不知道该怎么做。我被卡住了,因为我知道球体是一个对象,所以它需要有一个 material,但是(就颜色而言),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);

现在显然这段代码不起作用,但我想这是我正在尝试做的 idea/flow。

有一件事你是对的,PhongMaterial 采用 Color 作为漫反射颜色,而这不允许 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);

将产生以下结果:

动态漫反射贴图

显然,这有依赖于静态图像的缺点。如果你想动态修改它怎么办?

你可以做到这一点,如果你生成你的径向渐变,在次要场景上渲染它并拍摄它的快照。此快照 returns 一个 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 控件,然后 select 纹理模式`Vertices3D:

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

请注意,本例中的函数仅基于 z 坐标,但显然您可以根据需要对其进行修改。

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