正如@Jens-Peter-Haack 建议的那样,使用Snapshot,您可以创建任何您想要的图像,然后将该图像应用为扩散贴图。为此,您需要创建一些节点,用您需要的颜色填充它们,将它们分组到某个容器中,然后拍摄快照。
有一种直接的方法,您可以使用PixelWriter 构建具有颜色图案的图像。
假设您想要 256 种颜色,此方法将返回 256 像素的图像,其中每个像素具有其中一种颜色。为简单起见,我添加了两种构建调色板的简单方法。
public static Image colorPallete(int numColors){
int width=(int)Math.sqrt(numColors);
int height=numColors/width;
WritableImage img = new WritableImage(width, height);
PixelWriter pw = img.getPixelWriter();
AtomicInteger count = new AtomicInteger();
IntStream.range(0, height).boxed()
.forEach(y->IntStream.range(0, width).boxed()
.forEach(x->pw.setColor(x, y, getColor(count.getAndIncrement(),numColors))));
// save for testing purposes
try {
ImageIO.write(SwingFXUtils.fromFXImage(img, null), "jpg", new File("palette.jpg"));
} catch (IOException ex) { }
return img;
}
private Color getColor(int iColor, int numColors){
// nice palette of colors
java.awt.Color c = java.awt.Color.getHSBColor((float) iColor / (float) numColors, 1.0f, 1.0f);
return Color.rgb(c.getRed(), c.getGreen(), c.getBlue());
// raw palette
//return Color.rgb((iColor >> 16) & 0xFF, (iColor >> 8) & 0xFF, iColor & 0xFF);
}
一旦有了图像对象,就可以设置漫反射贴图了:
IcosahedronMesh mesh = new IcosahedronMesh();
PhongMaterial mat = new PhongMaterial();
mat.setDiffuseMap(colorPallete(256));
mesh.setMaterial(mat);
但您仍然必须提供到新纹理的正确映射。
为此,您需要将网格的顶点映射到图像中的像素。
首先,我们需要一种将颜色与网格上的纹理坐标进行映射的方法。此方法将返回给定颜色索引的一对坐标:
public static float[] getTextureLocation(int iPoint, int numColors){
int width=(int)Math.sqrt(numColors);
int height=numColors/width;
int y = iPoint/width;
int x = iPoint-width*y;
return new float[]{(((float)x)/((float)width)),(((float)y)/((float)height))};
}
最后,我们将这些纹理添加到m.getTextCoords() 和面m.getFaces(),如here 所示。
如果我们为二十面体中的每个顶点分配一种颜色,我们会从所有调色板中选择一种颜色(根据颜色和顶点的数量放大或缩小),然后将每个面设置为 t0=p0, t1=p1, t2=p2:
IntStream.range(0,numVertices).boxed()
.forEach(i->m.getTexCoords()
.addAll(getTextureLocation(i*numColors/numVertices,numColors)));
m.getFaces().addAll(
1, 1, 11, 11, 7, 7,
1, 1, 7, 7, 6, 6,
1, 1, 6, 6, 10, 10,
1, 1, 10, 10, 3, 3,
1, 1, 3, 3, 11, 11,
4, 4, 8, 8, 0, 0,
5, 5, 4, 4, 0, 0,
9, 9, 5, 5, 0, 0,
2, 2, 9, 9, 0, 0,
8, 8, 2, 2, 0, 0,
11, 11, 9, 9, 7, 7,
7, 7, 2, 2, 6, 6,
6, 6, 8, 8, 10, 10,
10, 10, 4, 4, 3, 3,
3, 3, 5, 5, 11, 11,
4, 4, 10, 10, 8, 8,
5, 5, 3, 3, 4, 4,
9, 9, 11, 11, 5, 5,
2, 2, 7, 7, 9, 9,
8, 8, 6, 6, 2, 2
);
这会给我们这样的东西:
编辑
使用纹理坐标,而不是使用颜色映射节点,您可以添加一些功能并轻松创建等高线图,如下所示: