I’m using my own instancing implementation (apart from InstancedNode) to do meshed particles. I’ve succeeded in making the instancing work, but for whatever reason, the shading is all messed up.
This should illustrate the problem (sorry for the poor quality).
The instances are rotating as expected, but the shading does not change with the rotation, which makes me think normals/tangents are not being properly updated for each instance.
Here’s the related code:
// in subclass of Geometry
@Override
public void updateLogicalState(float tpf) {
if (capacity != group.capacity()) {
initBuffers();
}
VertexBuffer ivb = mesh.getBuffer(VertexBuffer.Type.InstanceData);
FloatBuffer instances = (FloatBuffer)ivb.getData();
instances.clear();
if (!group.isEmpty()) {
// write transform matrix per particle
for (ParticleData p : group) {
MeshUtils.writeMatrix4(instances, p.transform.toTransformMatrix(), false);
}
} else {
// at least one matrix needs to be written
MeshUtils.writeMatrix4(instances, Matrix4f.IDENTITY, false);
}
instances.flip();
ivb.updateData(instances);
mesh.updateCounts();
mesh.updateBound();
}
private void initBuffers() {
capacity = group.capacity();
FloatBuffer ib = BufferUtils.createFloatBuffer(capacity * 16);
VertexBuffer vb = MeshUtils.initializeVertexBuffer(mesh,
VertexBuffer.Type.InstanceData,
VertexBuffer.Usage.Stream,
VertexBuffer.Format.Float,
ib, 16
);
vb.setInstanced(true);
}
public static VertexBuffer initializeVertexBuffer(Mesh mesh, Type type, Usage usage, Format format, Buffer data, int components) {
VertexBuffer buf = mesh.getBuffer(type);
if (buf != null) {
buf.updateData(data);
} else {
buf = new VertexBuffer(type);
buf.setupData(usage, components, format, data);
mesh.setBuffer(buf);
}
return buf;
}
public static void writeMatrix4(FloatBuffer fb, Matrix4f matrix, boolean rowMajor) {
float[] mat = new float[16];
matrix.get(mat, rowMajor);
fb.put(mat);
}