Jump to content

Particle System Shader Effect Errors and Warnings


Recommended Posts

I have noticed that when using a Particle System with a custom shader effect (which is working great like in playground: http://www.babylonjs-playground.com/#1ASENS)

but if you add a second particle system to the scene (even WITHOUT a custom effect... it reports several errors):


I made a playground to show the problem: http://www.babylonjs-playground.com/#1ASENS#40

Basically just add another particle system after 5 seconds:

// Create second particle system
        var emitter1 = BABYLON.Mesh.CreateBox("emitter1", 0.1, scene);
        emitter1.isVisible = true;
        emitter1.position.x += 1;

        // More Particles
        var particleSystem1 = new BABYLON.ParticleSystem("particles", 4000, scene, null);
        particleSystem1.particleTexture = new BABYLON.Texture("textures/flare.png", scene);
        particleSystem1.minSize = 0.1;
        particleSystem1.maxSize = 1.0;
        particleSystem1.minLifeTime = 0.5;
        particleSystem1.maxLifeTime = 5.0;
        particleSystem1.minEmitPower = 0.5;
        particleSystem1.maxEmitPower = 3.0;
        particleSystem1.emitter = emitter1;
        particleSystem1.emitRate = 100;
        particleSystem1.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
        particleSystem1.direction1 = new BABYLON.Vector3(-1, 1, -1);
        particleSystem1.direction2 = new BABYLON.Vector3(1, 1, 1);
        particleSystem1.color1 = new BABYLON.Color4(1, 1, 0, 1);
        particleSystem1.color2 = new BABYLON.Color4(1, 0.5, 0, 1);
        particleSystem1.gravity = new BABYLON.Vector3(0, -1.0, 0);

    }, 5000);


Yo @Deltakosh ... Can you check this out... Please :)


Note: If I don't use a custom effect at all... it works fine... Like in playground: http://www.babylonjs-playground.com/#1ASENS#42

Link to comment
Share on other sites

1 hour ago, Deltakosh said:

This is because the "effect" that you use in the renderLoop is the wrong one :)


Btw, do you plan to release the doc for the unity exporter?

The original demo using the effect returned from engine create particles call:

Source: http://www.babylonjs-playground.com/#1ASENS

// Effect
    var effect = engine.createEffectForParticles("myParticle", ["time"]);

    // Particles
    var particleSystem = new BABYLON.ParticleSystem("particles", 4000, scene, effect);
    particleSystem.particleTexture = new BABYLON.Texture("textures/flare.png", scene);
    particleSystem.minSize = 0.1;
    particleSystem.maxSize = 1.0;
    particleSystem.minLifeTime = 0.5;
    particleSystem.maxLifeTime = 5.0;
    particleSystem.minEmitPower = 0.5;
    particleSystem.maxEmitPower = 3.0;
    particleSystem.emitter = emitter0;
    particleSystem.emitRate = 100;
    particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
    particleSystem.direction1 = new BABYLON.Vector3(-1, 1, -1);
    particleSystem.direction2 = new BABYLON.Vector3(1, 1, 1);
    particleSystem.color1 = new BABYLON.Color4(1, 1, 0, 1);
    particleSystem.color2 = new BABYLON.Color4(1, 0.5, 0, 1);
    particleSystem.gravity = new BABYLON.Vector3(0, -1.0, 0);

    var time = 0;
    var order = 0.1;

    scene.registerBeforeRender(function () {
        // Waiting for effect to be compiled
        if (!effect) {

        effect.setFloat("time", time);

        time += order;

        if (time > 100 || time < 0) {
            order *= -1;


Note the second particle system used in the previous demo to show the error, does not even use ANY effect at all.

How should I get the proper effect to use to call the setFloat on :)

BTW... Yes I will have documentation ... Just getting back into BabylonJS after medical problems with my neck, arms and hands :)


Link to comment
Share on other sites

14 hours ago, Deltakosh said:

Sorry I was totally unclear.

Here is a better answer: https://www.babylonjs-playground.com/#1ASENS#43



That was it... I should have known you can't just call the setFloat all 'Willy Nilly' at any time during. It must be called during the shader life cycle 'binding' just like ANY other shader material binding code... I have a nice UniversalParticleSystem class using from the toolkit that wraps all that up nicely...

Thanks @Deltakosh

BTW... I see some post that have a RED TAG that says solved instead of just manyaluu the topic tied '[SOLVED]'

How do I do that when I want to mark my topic solved?


Link to comment
Share on other sites

On 7/21/2017 at 7:14 AM, Deltakosh said:

Sorry I was totally unclear.

Here is a better answer: https://www.babylonjs-playground.com/#1ASENS#43



Yo @Deltakosh ... Setting the float values in the effect on bind works great... 


The only problem comes into play when I try to use the same effect on two particle system instances on the screen at the same time...

the effect.onBind is only called on the first instance... so the set float value for the second instance never gets called...


As a work a around... I make SEPERATE COPIES of the particle shader fragment shader and add a copy of the shader fragment (shaderName + instanceId)

into the shader store so it actually creates a new effect for each instance copy of the shader program...


I am worried about overhead on the shader store... If I make separate copy for each instance the shader store :

BABYLON.Effect.ShaderStore[someInstanceID] = 'blah blah blah'


how do I remove the instance from the shader store so my BABYLON.Effect.ShaderStore does end up with wit a bunch of shader copies when I dispose an instance...

if I go 'BABYLON.Effect.ShaderStore[someInstanceID] = null'


I will still have a KEY/VALUE pair on the ShaderStore object ... just set to null...


How do I properly handle multiple particle systems on the screen each using the same actual shader programs... The only way I can see now is to make a copy of the base shader program for each instance, ensure a different shader fragment name for each instance... Is that the best way to go about that ???

Link to comment
Share on other sites

Yo @Deltakosh .. I found out out I can just use 'delete BABYLON.Effect.ShaderStore[effectFragmentName]'

to remove from shader store just fine... But is that the only way for more than one particle system on the screen at the same time to use the same effect shader program... The work around of making a copy of the shader for each instance is working but I wonder if that the BEST or ONLY way to do that:


Example for copying shader store fragments per instance

this._shader = this.mesh.name + "_" + (new Date().getTime() / 1000).toString().replace(".", "") + "_" + Math.random().toString().replace(".", "") + "_Particle";

var me:any = this;
var sourceFragment:string = shader + "FragmentShader";
var effectFragment:string = this._shader + "FragmentShader";

BABYLON.Effect.ShadersStore[effectFragment] = BABYLON.Effect.ShadersStore[sourceFragment];

this._effect = this.engine.createEffectForParticles(this._shader, uniforms, samplers, joiners);
this._effect.onBind = (eff:BABYLON.Effect)=>{ me.bindParticleSystemEffect(me, eff); };


Then in object disposal:

if (this._shader != null && this._shader !== "") {
  var effectFragment:string = this._shader + "FragmentShader";
  if (BABYLON.Effect.ShadersStore[effectFragment]) {
     delete BABYLON.Effect.ShadersStore[effectFragment];


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...