As @ Jens-Peter-Haack shows, with Snapshot you can create any image you want and then apply this image as a diffusion map. To do this, you need to create several nodes, fill them with the required colors, group them in some container, and then take a picture.
There is a direct approach where you can create an image with a picture of colors using PixelWriter .
Say you want 256 colors, this method will return an image with 256 pixels, where each pixel has one of these colors. For simplicity, I added two simple ways to create a palette.
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); }
When you have an image object, you can install a diffuse map:
IcosahedronMesh mesh = new IcosahedronMesh(); PhongMaterial mat = new PhongMaterial(); mat.setDiffuseMap(colorPallete(256)); mesh.setMaterial(mat);
But you still need to ensure that the new texture is displayed correctly.
To do this, you need to match the vertices of the grid with a pixel in the image.
First, we need a way to map the colors to the texture coordinates on the grid. This method will return a pair of coordinates for a given color index:
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))}; }
Finally, we add these textures to m.getTextCoords() and to the faces of m.getFaces() , as shown here .
If we assign a color to each vertex in our icosahedron, we select a color from the entire palette (scaling up or down in the number of colors and vertices), and then set each face with 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 );
This will give us something like this:

EDIT
When playing with texture coordinates, instead of displaying a node with color, you can add some function and easily create a contour graph, for example:
