[Solved] Importing Vertex Colored mesh from blender?

So I’ve been looking around for the past few hours and there is a shockingly small amount of information regarding vertex colors on the forum and wiki.

So, once and for all, how would one import a vertex painted mesh from blender into jme and change its colors in java code later on?

What I’m working with:

I’m resonably sure there isn’t much material on the topic, but correct me if I’m wrong.

Why not doing a texture and paint it onto the object
Then you could easily change the white color

Because this would potentially make it possible to change “uvmaps” at runtime and produce less color banding.

You change the colours by changing the data in the Color buffer.
Here is an example that reads vertex colors and modifies them to simulate directional light.

public static void dirLight(Mesh mesh, Vector3f dir, float minI, float intensity) {
        VertexBuffer color = mesh.getBuffer(VertexBuffer.Type.Color);
        if(color.getData() instanceof FloatBuffer) {
            throw new IllegalArgumentException();
        }
        else 
            dirLight(mesh.getFloatBuffer(VertexBuffer.Type.Normal),
                (ByteBuffer)color.getData(), color.getNumComponents(), dir, minI, intensity);
    }
    public static void dirLight(FloatBuffer normal, FloatBuffer color, final int colorCompNum, Vector3f dir, float minI, float intensity) {
        //assume 3 components per col
        Vector3f v1 = new Vector3f();
        color.rewind();
        normal.rewind();
        float i, j;
        while(color.hasRemaining()) {
            v1.set(normal.get(), normal.get(), normal.get());
            i = v1.dot(dir);
            if(i < minI) i = minI;
            for(j = 0; j < 3; j++)
                color.put(i*color.get(color.position()));
            if(colorCompNum == 4) color.get();
        }
    }

You can obtain Mesh from Geometry, which is attached to a Node, which you load through asset manager. :chimpanzee_amused:

Yeah it turns out that I’ve been a bit of an idiot again. I was trying to set the “UseVertexColor” parameter on Unshaded in jme and it didn’t exist so I presumed that the switching was automatic via some #ifdef. Then when nothing worked no matter what I did, I checked it and found out that the parameter is actually “VertexColor”.

It works perfectly now:

And very minimal color banding up close.

For the color change I decided to just nuke what blender exported and replace it with a new buffer. The mesh’s inner edge loop has a radius of one unit.

	VertexBuffer index = mesh.getBuffer(Type.Position);
	float [] vertices = new float[index.getNumElements()*4];
	
	for(int i = 0, j = 0; j < index.getNumElements(); i+=4, j++) {
		Vector3f pos = new Vector3f(0,0,0);
		pos.x = (float) index.getElementComponent(j, 0);
		pos.y = (float) index.getElementComponent(j, 1);
		pos.z = (float) index.getElementComponent(j, 2);
		
		if(pos.length() > 1.1f){
			vertices[i] = vertices[i+1] = vertices[i+2] = vertices[i+3] = 0;
		}else if (pos.length() < 0.1f){
			vertices[i] = vertices[i+1] = vertices[i+2] = vertices[i+3] = 1;
		}else{
			vertices[i] = center.r;
			vertices[i+1] = center.g;
			vertices[i+2] = center.b;
			vertices[i+3] = center.a;
		}
	}
	
	m.setBuffer(Type.Color, 4, BufferUtils.createFloatBuffer(vertices));
    
    Material mat = new Material(CPU.game.getAssetManager(),"Common/MatDefs/Misc/Unshaded.j3md");
    mat.setBoolean("VertexColor", true);
    mat.setTransparent(true);
    mat.getAdditionalRenderState().setDepthTest(true);
    mat.getAdditionalRenderState().setDepthWrite(false);
    mat.getAdditionalRenderState().setBlendMode(BlendMode.AlphaAdditive);
    mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
    
    Geometry g = new Geometry("",mesh);
    g.setMaterial(mat);        
    g.setQueueBucket(Bucket.Transparent);
    attachChild(g);

Also, dragging out the outer circle has a very cool effect and I’ll couple that with a vert shader to make it deform slightly over time.

2 Likes