Now solid particles can be given different materials from the other ones.
Like for standard meshes, first create your MultiMaterial :
var mat1 = new BABYLON.StandardMaterial("m1", scene);
var mat2 = new BABYLON.StandardMaterial("m2", scene);
var mat3 = new BABYLON.StandardMaterial("m3", scene);
mat2.diffuseColor = BABYLON.Color3.Red();
mat1.diffuseColor = BABYLON.Color3.Green();
mat3.diffuseColor = BABYLON.Color3.Yellow();
var mat = new BABYLON.MultiMaterial("mm", scene);
mat.subMaterials.push(mat1);
mat.subMaterials.push(mat2);
mat.subMaterials.push(mat3);
Then create a SPS with the parameter enableMultiMaterial
set to true
and assign this multimaterial to its mesh like you would do for any other BJS mesh :
var sps = new BABYLON.SolidParticleSystem("sps", scene, { enableMultiMaterial: true});
var model = BABYLON.MeshBuilder.CreateBox("m", {}, scene);
sps.addShape(model, 1000);
sps.buildMesh();
var particles = sps.mesh;
particles.material = mat;
Now, you can assign a different material from the MultiMaterial object to each particle with the particle property materialIndex
.
Then instead of manually creating the submeshes, just call computeSubMeshes()
once the particle values are set with setParticles()
:
// particle initialization function
var initParticle = function(particle) {
particle.position.x = areaSize * (Math.random() - 0.5);
particle.position.y = areaSize * (Math.random() - 0.5);
particle.position.z = areaSize * (Math.random() - 0.5);
particle.materialIndex = (Math.random() * mat.subMaterials.length)|0;
};
// init particles
sps.updateParticle = initParticle;
sps.setParticles(); // sets the particle locations
sps.computeSubMeshes(); // creates the submeshes from the particle materialIndex values
The SPS geometry is then recomputed so particle vertices and indices are grouped by materials in order to reduce the number of draw calls to its possible minimum (one by used material generally).
This feature also works with an expandable SPS, so you can add, remove or store particles with materials.
It doesn’t work (doesn’t crash but leads to weird visible results) with the particle depth sort when you use transparent materials because particles can’t be sorted in the same time by material AND by the distance to the camera.
You can change the materials, the multimaterial object (example : add some other new materials) or each particle materialIndex
value at any time. Just call sps.computeSubMeshes()
to actually update the particle materials on the screen.
As this method sorts the all the particles, recompute the whole mesh geometry and allocate new arrays and new buffers each call, it’s probably not a good idea to call it each frame.
PG Examples and documentation to come soon, once the PG engine is upgraded.