I am trying to color a geometry using vertex coloring based on a a file that has multiple colors see below:
Basically, I want to change the color of different objects with similar form (identical mesh) where they all use the same material. Instead of creating a material for each, I decided to just change the color of their meshes. After reading the documentation on advanced custom meshes I was able to write the code below. However, the code does not do where objects are not getting colored.
public static void changeColor(Mesh mesh, AnimationUVMapping color){
float[] texCoord = new float[mesh.getVertexCount() * 2];
// color from file
float yTexel = color.getV();
for(int i=0; i<texCoord.length; i++) {
texCoord[i] = yTexel;
}
// clear texture coordinates buffer
mesh.clearBuffer(Type.TexCoord);
// fill buffer with new texture coordinates from atlas file
mesh.setBuffer(Type.Color, 2, BufferUtils.createFloatBuffer(texCoord));
mesh.updateBound();
}
There are a few things that we must assume because we can’t see the rest:
we must assume that you have a custom shader because of course this won’t work with any of the default shaders. We can’t see that so it could be broken too.
we must assume that the model is not sharing vertexes that would need different colors. Since we don’t know the source of the mesh this is also a pretty big assumption but if you are coloring whole objects then it should be ok. If you are trying to color just particular faces then it requires that those faces have their own vertexes (not shared by adjacent faces of different colors).
Also, since we don’t see the picture of what “wrong” looks like we must assume a lot from your description. It’s mildly humorous the number of times people go to great lengths to describe something on here where a picture would work fine. Though in your case, the description is straight forward it still leaves some room for interpretation. Seeing what you want next to what you get would be clearer if possible.
@pspeed you’re right I should have posted a picture, and I apologize for not being specific.
See below. The issue is that no colors are being assigned at all. @david_bernard_31 I tried different things including what you suggested with no luck.
I am using this material for all of them (and yes I am coloring - or attempting to color - the whole object)
mat= new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md");
mat.setTexture("DiffuseMap", assetManager.loadTexture("/Materials/atlasColors.png"));
mat.setFloat("Shininess", 5f);
mat.setColor("Specular", ColorRGBA.White);
Below are the objects (cuboids) that I am trying to color using the same material.
Also, am I over complicating this? Is there a simpler way to color objects using the same material?
You should set the text coordinates to the texture coordinate buffer. Lighting.j3md has no idea what to do with your Color buffer that is actually texture coordinates.
@david_bernard_31 that is what I had initially but that also meant every time I called the changeColor() method it assigned a new material for the object. Since I have a large number of these objects, my plan was to use the same material for all of them but when I need to change the color I will just use that file I created to point to the right yTexel from it and change the color accordingly.
float[] texCoord = new float[mesh.getVertexCount() * 2];
// default pod color
float yTexel = color.getV();
for(int i=0; i<texCoord.length; i++) {
texCoord[i] = yTexel;
}
// clear texture coordinates buffer
mesh.clearBuffer(Type.TexCoord);
// fill buffer with new texture coordinates from atlas file
mesh.setBuffer(Type.TexCoord, 4, BufferUtils.createFloatBuffer(yTexel));
mesh.updateBound();
I tried it and still didn’t work. Again I apologize if I am doing something stupid here, I went over the documentation again just to make sure, and for me it seems my code is correct (but obviously I am wrong)
You can have one material per object. they share the same material definition : Lighting.j3md (the “heavy” part)
your changeColor(), will use getMaterial().setColor(“Diffuse”, mycolor)
About your custom approach.
the error is in using your yTexel and filling color. It should be something like :
in your sample the size and the content of the buffer is wrong.
And IMHO to set the same color everywhere, your custom approach will require more resources : to set the value on CPU and to transfert GPU, where it will use more memory (to store one color per vertex vs one color per mesh)
Oups I don’t see you switch to Type.TexCoord, in this case you should send 2 coord (U,V) with values between [0,1], and you send (V,V) if I understand correctly your code.
anyway use one material per object, it’s made for this : storing parameters of a MaterialDefinition.
if I choose one material per object the performance drops significantly. I tried 2 test cases one with all of them using one material and another case with each having its own material. SIGNIFICANT difference!
@pspeed I will double check,as you said my intent is to batch them together and then change the colors.
Out of curiosity is this possible if the objected were not batched? Can I assign one material to all the objects and change their colors without having them batched?
No, but if you already had separate objects then you might as well have separate materials. The slowness with multiple objects comes from having multiple objects not multiple materials.
Note: he’s indexing into a single column texture… so while it’s strange that he uses the same value for texCoord x and y, it’s not wrong in this case.