我正在使用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);
现在显然该代码不起作用,但我想这就是我要尝试执行的操作的想法/流程。
答案 0 :(得分:3)
您对一件事是正确的,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);
将产生以下结果:
动态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
坐标,但是显然您可以根据需要进行修改。
检查库(有一个采样器),以探索其他选项。