In the meantime, you can test a couple of things:
- try to put
engine.getCaps().instancedArrays = false;
very early in your code and see if it helps. It disables instancing support, so the particle system will use another code path than the standard one
- put back
engine.getCaps().instancedArrays = true;
(or better, remove it) and add this code in your project:
BABYLON.ParticleSystem.prototype._createVertexBuffers = function () {
this._vertexBufferSize = this._useInstancing ? 10 : 12;
if (this._isAnimationSheetEnabled) {
this._vertexBufferSize += 1;
}
if (!this._isBillboardBased || this.billboardMode === BABYLON.ParticleSystem.BILLBOARDMODE_STRETCHED) {
this._vertexBufferSize += 3;
}
if (this._useRampGradients) {
this._vertexBufferSize += 4;
}
let engine = this._engine;
this._vertexData = new Float32Array(this._capacity * this._vertexBufferSize * (this._useInstancing ? 1 : 4));
this._vertexBuffer = new BABYLON.Buffer(engine, this._vertexData, true, this._vertexBufferSize);
let dataOffset = 0;
var positions = this._vertexBuffer.createVertexBuffer(BABYLON.VertexBuffer.PositionKind, dataOffset, 3, this._vertexBufferSize, this._useInstancing);
this._vertexBuffers[BABYLON.VertexBuffer.PositionKind] = positions;
dataOffset += 3;
var colors = this._vertexBuffer.createVertexBuffer(BABYLON.VertexBuffer.ColorKind, dataOffset, 4, this._vertexBufferSize, this._useInstancing);
this._vertexBuffers[BABYLON.VertexBuffer.ColorKind] = colors;
dataOffset += 4;
var options = this._vertexBuffer.createVertexBuffer("angle", dataOffset, 1, this._vertexBufferSize, this._useInstancing);
this._vertexBuffers["angle"] = options;
dataOffset += 1;
var size = this._vertexBuffer.createVertexBuffer("size", dataOffset, 2, this._vertexBufferSize, this._useInstancing);
this._vertexBuffers["size"] = size;
dataOffset += 2;
if (this._isAnimationSheetEnabled) {
var cellIndexBuffer = this._vertexBuffer.createVertexBuffer("cellIndex", dataOffset, 1, this._vertexBufferSize, this._useInstancing);
this._vertexBuffers["cellIndex"] = cellIndexBuffer;
dataOffset += 1;
}
if (!this._isBillboardBased || this.billboardMode === BABYLON.ParticleSystem.BILLBOARDMODE_STRETCHED) {
var directionBuffer = this._vertexBuffer.createVertexBuffer("direction", dataOffset, 3, this._vertexBufferSize, this._useInstancing);
this._vertexBuffers["direction"] = directionBuffer;
dataOffset += 3;
}
if (this._useRampGradients) {
var rampDataBuffer = this._vertexBuffer.createVertexBuffer("remapData", dataOffset, 4, this._vertexBufferSize, this._useInstancing);
this._vertexBuffers["remapData"] = rampDataBuffer;
dataOffset += 4;
}
var offsets;
if (this._useInstancing) {
//var spriteData = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
var spriteData = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);
this._spriteBuffer = new BABYLON.Buffer(engine, spriteData, false, 2);
offsets = this._spriteBuffer.createVertexBuffer("offset", 0, 2);
} else {
offsets = this._vertexBuffer.createVertexBuffer("offset", dataOffset, 2, this._vertexBufferSize, this._useInstancing);
dataOffset += 2;
}
this._vertexBuffers["offset"] = offsets;
}
BABYLON.ParticleSystem.prototype._render = function (blendMode) {
var effect = this._getEffect(blendMode);
var engine = this._engine;
// Render
engine.enableEffect(effect);
var viewMatrix = this.defaultViewMatrix ? this.defaultViewMatrix : this._scene.getViewMatrix();
effect.setTexture("diffuseSampler", this.particleTexture);
effect.setMatrix("view", viewMatrix);
effect.setMatrix("projection", this.defaultProjectionMatrix ? this.defaultProjectionMatrix : this._scene.getProjectionMatrix());
if (this._isAnimationSheetEnabled && this.particleTexture) {
var baseSize = this.particleTexture.getBaseSize();
effect.setFloat3("particlesInfos", this.spriteCellWidth / baseSize.width, this.spriteCellHeight / baseSize.height, this.spriteCellWidth / baseSize.width);
}
effect.setVector2("translationPivot", this.translationPivot);
effect.setFloat4("textureMask", this.textureMask.r, this.textureMask.g, this.textureMask.b, this.textureMask.a);
if (this._isBillboardBased && this._scene) {
var camera = this._scene.activeCamera;
effect.setVector3("eyePosition", camera.globalPosition);
}
if (this._rampGradientsTexture) {
if (!this._rampGradients || !this._rampGradients.length) {
this._rampGradientsTexture.dispose();
this._rampGradientsTexture = null;
}
effect.setTexture("rampSampler", this._rampGradientsTexture);
}
const defines = effect.defines;
if (this._scene) {
if (this._scene.clipPlane || this._scene.clipPlane2 || this._scene.clipPlane3 || this._scene.clipPlane4 || this._scene.clipPlane5 || this._scene.clipPlane6) {
BABYLON.ThinMaterialHelper.BindClipPlane(effect, this._scene);
}
}
if (defines.indexOf("#define BILLBOARDMODE_ALL") >= 0) {
viewMatrix.invertToRef(BABYLON.TmpVectors.Matrix[0]);
effect.setMatrix("invView", BABYLON.TmpVectors.Matrix[0]);
}
engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);
// image processing
if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {
this._imageProcessingConfiguration.bind(effect);
}
// Draw order
switch (blendMode) {
case BABYLON.ParticleSystem.BLENDMODE_ADD:
engine.setAlphaMode(BABYLON.Constants.ALPHA_ADD);
break;
case BABYLON.ParticleSystem.BLENDMODE_ONEONE:
engine.setAlphaMode(BABYLON.Constants.ALPHA_ONEONE);
break;
case BABYLON.ParticleSystem.BLENDMODE_STANDARD:
engine.setAlphaMode(BABYLON.Constants.ALPHA_COMBINE);
break;
case BABYLON.ParticleSystem.BLENDMODE_MULTIPLY:
engine.setAlphaMode(BABYLON.Constants.ALPHA_MULTIPLY);
break;
}
if (this._onBeforeDrawParticlesObservable) {
this._onBeforeDrawParticlesObservable.notifyObservers(effect);
}
if (this._useInstancing) {
//engine.drawArraysType(BABYLON.Constants.MATERIAL_TriangleStripDrawMode, 0, 4, this._particles.length);
engine.drawArraysType(BABYLON.Constants.MATERIAL_TriangleFanDrawMode, 0, 4, this._particles.length);
} else {
engine.drawElementsType(BABYLON.Constants.MATERIAL_TriangleFillMode, 0, this._particles.length * 6);
}
return this._particles.length;
}
It will put back the usage of triangle fans instead of triangle strips, which has been a late change to the particle system. I checked on the playground that the new and old way does still work, but…