如何在 JavaFX 中为 3D Box 设置 LinearGradient
How to set LinearGradient for 3D Box in JavaFX
我找到了一些与我的问题类似的答案,但该解决方案专用于球体。不管怎样,我试过了,当然这不是我所期望的。
我使用的代码是:
Scene aux2 = new Scene(new StackPane(), 100, 100,
new LinearGradient(0, 0, 1, 0, true, CycleMethod.REFLECT,
new Stop(0, Color.GREEN), new Stop(0.3, Color.YELLOW),
new Stop(0.6, Color.BLUE), new Stop(0.9, Color.RED)));
WritableImage snapshot = aux2.snapshot(null);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(snapshot);
box.setMaterial(material);
效果在这里:https://imagizer.imageshack.com/img922/589/VEL43d.png
如何在盒子周围得到相同的填充(在椭圆形中)并用渐变的顶部颜色设置顶面?
您提到的球体 不适用于 3D 盒子,因为 built-in 盒子将对盒子的每个平面 6 面应用完全相同的漫反射图像.
另一个 为 3D 框使用自定义网格,因此您可以以不同的方式使用漫反射图像。
我们可以根据您的用例调整该解决方案,因为如果我做对了,您想要将具有线性渐变的同一图像应用于 4 个垂直面,同时保持 2 个水平面上的边框颜色.
所以我们需要这样的图片:
Scene aux2 = new Scene(new StackPane(), 10, 100,
new LinearGradient(0, 1, 0, 0, true, CycleMethod.REFLECT,
new Stop(0, Color.GREEN), new Stop(0.3, Color.YELLOW),
new Stop(0.6, Color.BLUE), new Stop(0.9, Color.RED)));
WritableImage snapshot = aux2.snapshot(null);
PhongMaterial material = new PhongMaterial(Color.WHITE);
material.setDiffuseMap(snapshot);
请注意,我设置了垂直线性渐变。如果您渲染该图像,您将得到如下内容:
现在需要生成一个长方体网格:
public MeshView createCuboid(float w, float h, float d) {
float hw = w / 2f;
float hh = h / 2f;
float hd = d / 2f;
float points[] = {
hw, hh, hd,
hw, hh, -hd,
hw, -hh, hd,
hw, -hh, -hd,
-hw, hh, hd,
-hw, hh, -hd,
-hw, -hh, hd,
-hw, -hh, -hd};
float tex[] = {
0.01f, 0.01f,
0.01f, 0.99f};
float normals[] = {
1f, 0f, 0f,
-1f, 0f, 0f,
0f, 1f, 0f,
0f, -1f, 0f,
0f, 0f, 1f,
0f, 0f, -1f,
};
int faces[] = {
0, 0, 0, 2, 0, 1, 1, 0, 0,
2, 0, 1, 3, 0, 1, 1, 0, 0,
4, 1, 0, 5, 1, 0, 6, 1, 1,
6, 1, 1, 5, 1, 0, 7, 1, 1,
0, 2, 0, 1, 2, 0, 4, 2, 0,
4, 2, 0, 1, 2, 0, 5, 2, 0,
2, 3, 1, 6, 3, 1, 3, 3, 1,
3, 3, 1, 6, 3, 1, 7, 3, 1,
0, 4, 0, 4, 4, 0, 2, 4, 1,
2, 4, 1, 4, 4, 0, 6, 4, 1,
1, 5, 0, 3, 5, 1, 5, 5, 0,
5, 5, 0, 3, 5, 1, 7, 5, 1};
TriangleMesh mesh = new TriangleMesh();
mesh.setVertexFormat(VertexFormat.POINT_NORMAL_TEXCOORD);
mesh.getPoints().addAll(points);
mesh.getTexCoords().addAll(tex);
mesh.getNormals().addAll(normals);
mesh.getFaces().addAll(faces);
return new MeshView(mesh);
}
如果你检查纹理坐标,我刚刚选择了两对坐标,一对几乎在漫反射图像的底部,一对几乎在顶部。 JavaFX 将完成剩下的工作,对给定图像的每个像素进行插值。我没有选择边框,以防止图像边框处出现不同颜色的任何可能问题。
faces 数组列出了每个三角形(最多 12 个)的三个顶点、三个法线和三个纹理坐标的索引。
例如,第一个三角形的顶点索引为 0、2、1,每个顶点的法线为 0,纹理索引为 0、1、0(底部 - 顶部 - 底部)。下一个三角形的索引为 2、3、1,相同的法线为 0,纹理索引为 1、1、0(顶部 - 顶部 - 底部)。请注意底部是红色,顶部是绿色(Y 坐标从图像的 top-left 角向下)。
索引为 4、5 的面的纹理索引为 0、0、0,因此它们将位于底部,而面 6、7 的索引为 1、1、1,因此它们将位于底部最佳。
所以现在我们需要的是:
MeshView mv = createCuboid(10, 100, 10);
mv.setMaterial(material);
Group cuboidGroup = new Group(mv);
Scene scene = new Scene(cuboidGroup, 400, 600, true, SceneAntialiasing.BALANCED);
结果如下:
希望这就是您要找的结果。否则,你可以玩渐变和网格来实现它。
我找到了一些与我的问题类似的答案,但该解决方案专用于球体。不管怎样,我试过了,当然这不是我所期望的。
我使用的代码是:
Scene aux2 = new Scene(new StackPane(), 100, 100,
new LinearGradient(0, 0, 1, 0, true, CycleMethod.REFLECT,
new Stop(0, Color.GREEN), new Stop(0.3, Color.YELLOW),
new Stop(0.6, Color.BLUE), new Stop(0.9, Color.RED)));
WritableImage snapshot = aux2.snapshot(null);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(snapshot);
box.setMaterial(material);
效果在这里:https://imagizer.imageshack.com/img922/589/VEL43d.png
如何在盒子周围得到相同的填充(在椭圆形中)并用渐变的顶部颜色设置顶面?
您提到的球体
另一个
我们可以根据您的用例调整该解决方案,因为如果我做对了,您想要将具有线性渐变的同一图像应用于 4 个垂直面,同时保持 2 个水平面上的边框颜色.
所以我们需要这样的图片:
Scene aux2 = new Scene(new StackPane(), 10, 100,
new LinearGradient(0, 1, 0, 0, true, CycleMethod.REFLECT,
new Stop(0, Color.GREEN), new Stop(0.3, Color.YELLOW),
new Stop(0.6, Color.BLUE), new Stop(0.9, Color.RED)));
WritableImage snapshot = aux2.snapshot(null);
PhongMaterial material = new PhongMaterial(Color.WHITE);
material.setDiffuseMap(snapshot);
请注意,我设置了垂直线性渐变。如果您渲染该图像,您将得到如下内容:
现在需要生成一个长方体网格:
public MeshView createCuboid(float w, float h, float d) {
float hw = w / 2f;
float hh = h / 2f;
float hd = d / 2f;
float points[] = {
hw, hh, hd,
hw, hh, -hd,
hw, -hh, hd,
hw, -hh, -hd,
-hw, hh, hd,
-hw, hh, -hd,
-hw, -hh, hd,
-hw, -hh, -hd};
float tex[] = {
0.01f, 0.01f,
0.01f, 0.99f};
float normals[] = {
1f, 0f, 0f,
-1f, 0f, 0f,
0f, 1f, 0f,
0f, -1f, 0f,
0f, 0f, 1f,
0f, 0f, -1f,
};
int faces[] = {
0, 0, 0, 2, 0, 1, 1, 0, 0,
2, 0, 1, 3, 0, 1, 1, 0, 0,
4, 1, 0, 5, 1, 0, 6, 1, 1,
6, 1, 1, 5, 1, 0, 7, 1, 1,
0, 2, 0, 1, 2, 0, 4, 2, 0,
4, 2, 0, 1, 2, 0, 5, 2, 0,
2, 3, 1, 6, 3, 1, 3, 3, 1,
3, 3, 1, 6, 3, 1, 7, 3, 1,
0, 4, 0, 4, 4, 0, 2, 4, 1,
2, 4, 1, 4, 4, 0, 6, 4, 1,
1, 5, 0, 3, 5, 1, 5, 5, 0,
5, 5, 0, 3, 5, 1, 7, 5, 1};
TriangleMesh mesh = new TriangleMesh();
mesh.setVertexFormat(VertexFormat.POINT_NORMAL_TEXCOORD);
mesh.getPoints().addAll(points);
mesh.getTexCoords().addAll(tex);
mesh.getNormals().addAll(normals);
mesh.getFaces().addAll(faces);
return new MeshView(mesh);
}
如果你检查纹理坐标,我刚刚选择了两对坐标,一对几乎在漫反射图像的底部,一对几乎在顶部。 JavaFX 将完成剩下的工作,对给定图像的每个像素进行插值。我没有选择边框,以防止图像边框处出现不同颜色的任何可能问题。
faces 数组列出了每个三角形(最多 12 个)的三个顶点、三个法线和三个纹理坐标的索引。
例如,第一个三角形的顶点索引为 0、2、1,每个顶点的法线为 0,纹理索引为 0、1、0(底部 - 顶部 - 底部)。下一个三角形的索引为 2、3、1,相同的法线为 0,纹理索引为 1、1、0(顶部 - 顶部 - 底部)。请注意底部是红色,顶部是绿色(Y 坐标从图像的 top-left 角向下)。
索引为 4、5 的面的纹理索引为 0、0、0,因此它们将位于底部,而面 6、7 的索引为 1、1、1,因此它们将位于底部最佳。
所以现在我们需要的是:
MeshView mv = createCuboid(10, 100, 10);
mv.setMaterial(material);
Group cuboidGroup = new Group(mv);
Scene scene = new Scene(cuboidGroup, 400, 600, true, SceneAntialiasing.BALANCED);
结果如下:
希望这就是您要找的结果。否则,你可以玩渐变和网格来实现它。