First beta is up. GitHub - Corollarium/babylonjs-vat: Vertex Animation Texture implementation for BabylonJS It’s a PoC with some hardcoded data for the animation data (see below), but should be good enough for evaluation before moving to a fork of BabylonJS (and then adding automatic tests).
It works for the spider model (http://localhost:8080/) but the models are distorted for the shark model (http://localhost:8080/?scene=sharkVAT), which uses a PBR material. Certainly overriding the shader is not doing nice things to the poor shark.
Proposed API:
// load our model
const importResult = await SceneLoader.ImportMeshAsync(
"",
"https://raw.githubusercontent.com/RaggarDK/Baby/baby/",
"arr.babylon",
scene,
undefined
);
// create a VAT for it
const vat = new VAT(
"VATspider",
scene,
importResult.meshes[0] as Mesh,
importResult.skeletons[0],
[]
);
// bake VAT.
vat.bakeVertexData().then(() => {
vat.mesh.setEnabled(false);
// create instances
for (let i = 0; i < 20; i++) {
const instance = vat.mesh.createInstance("spider" + i);
instance.position.x += (i - 10.0) * 2;
// set our animation parameters.
instance.instancedBuffers.VATanimation = new Vector4(
0, // start
100, // end
i * 2, // offset
30.0 // speed in frames per second
);
}
// Register a render loop to repeatedly render the scene
const startTime = new Date().getTime();
engine.runRenderLoop(() => {
const endTime = new Date().getTime();
const timeElapsed = (endTime - startTime) / 1000.0; // in s
vat.updateTime(timeElapsed);
scene.render();
});
});
There is a way to save the baked texture (actually, the vertex data Float32Array
), serializing it to a JSON with a trick to keep it not too big (about 1.3x the size of the original array). Perhaps some utility using Puppeteer or something like it can be written later to bake models from the command line.
There’s one lingering problem that I’m not sure how to tackle. I thought I could always get the animations from the AnimationGroups
, but that doesn’t seem to be the case. Is there some automatic way to get them? Or should we expect the user to send a [{name, startFrame, endFrame}]
array of objects instead?
Also, on babylonjs-vat/vat.ts at master · Corollarium/babylonjs-vat · GitHub
mat.onBindObservable.add(() => {
// TODO: this should run only once
mat.getEffect()
.setFloat("singleFrameUVPer", 1 / this.frameCount)
.setTexture("boneSampler1", this.boneTexture);
});
Could this code be ran only once (and if so how) or does it need to be ran on every frame?
Looking forward to your feedback so we can integrate this soon