Sign in to follow this  
Evalum

Offset for individual particle

Recommended Posts

Hello! I am playing around with particle system and I am using UV scrolling to animate textures of particles. I am able to provide time into custom shader to offset UV coordinates but I would also like to have random but persistent offset for each individual particle. Does anyone know how to do that?

vec2 uv = vUV + vec2(0.0, time + particleUniqueOffset);

Where time is provided as global uniform (accessible for all the particles) and particleUniqueOffset is random value created when the particle was initialized and stays persistent throughout its lifetime.

I'll provide the code snippet that I use for now

BABYLON.Effect.ShadersStore["myParticleFragmentShader"] =
"#ifdef GL_ES\n" +
"precision highp float;\n" +
"#endif\n" +

"varying vec2 vUV;\n" +                     // Provided by babylon.js

"uniform sampler2D diffuseSampler;\n" +     // Provided by babylon.js
"uniform float time;\n" +                   // This one is custom so we need to declare it to the effect

"void main(void) {\n" +
	"vec4 a = texture2D(diffuseSampler, vUV);\n" +
	"vec4 b = texture2D(diffuseSampler, vUV + vec2(0.0, -time * 0.3));\n" +
    "gl_FragColor = a * b;\n" +
"}\n" +
"";

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

// Particles
var particleSystem = new BABYLON.ParticleSystem("particles", 4000, scene, effect);
particleSystem.particleTexture = new BABYLON.Texture("wood_wraith_poison.png", scene);
particleSystem.minEmitBox = new BABYLON.Vector3(0.3, 1.0, 0.3);
particleSystem.maxEmitBox = new BABYLON.Vector3(-0.3, 3.0, -0.3);
particleSystem.minSize = 2.0;
particleSystem.maxSize = 3.0;
particleSystem.minLifeTime = 100;
particleSystem.emitter = BABYLON.Vector3.Zero();
particleSystem.manualEmitCount = 3;
particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_STANDARD;
particleSystem.direction1 = BABYLON.Vector3.Zero();
particleSystem.direction2 = BABYLON.Vector3.Zero();
particleSystem.start();

effect.onBind = function () {
    effect.setFloat("time", time);
};

 

Share this post


Link to post
Share on other sites

Hello,

This would require to add a custom attribute which is not supported by the particles custom shaders. As @Deltakosh told me you might be able to use the particles animation sheets instead ?

I bet he might come in as soon as he ll be available to add more precision to the thread 🙂

 

Share this post


Link to post
Share on other sites

I think I'll write extension to particles to include particle instance attributes to add more variability to individual particles. I am thinking of attaching hook to particle emit event where I'll attach instance attribute(s) or do more individual stuff for particle.

Share this post


Link to post
Share on other sites

I got it "hacky" fixed currently as I can not afford to spend any more time on this. I am taking advantage of vColor in fragment shader and I am storing my random offsets in color.

BABYLON.Effect.ShadersStore["myParticleFragmentShader"] =
"#ifdef GL_ES\n" +
"precision highp float;\n" +
"#endif\n" +

"varying vec2 vUV;\n" +                     // Provided by babylon.js
"varying vec4 vColor;\n" +

"uniform sampler2D diffuseSampler;\n" +     // Provided by babylon.js
"uniform float time;\n" +                   // This one is custom so we need to declare it to the effect

"void main(void) {\n" +
	"vec4 a = texture2D(diffuseSampler, vUV + vec2(vColor.b * 0.5 - 0.25, 0.0));\n" +
	"vec4 b = texture2D(diffuseSampler, vUV + vec2(0.0, -(time + vColor.r)*(0.05 + vColor.g * 0.15)) * (1.0 + vColor.b));\n" +
    "b.a *= vColor.a; \n" +
    "gl_FragColor = a * b;\n" +
"}\n" +
"";

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

// Particles
var particleSystem = new BABYLON.ParticleSystem("particles", 400, scene, effect);
particleSystem.particleTexture = new BABYLON.Texture("wood_wraith_poison.png", scene);
particleSystem.minEmitBox = new BABYLON.Vector3(0.5, 1.5, 0.5);
particleSystem.maxEmitBox = new BABYLON.Vector3(-0.5, 1.5, -0.5);
particleSystem.minSize = 3.0;
particleSystem.maxSize = 5.0;
particleSystem.minLifeTime = 999;
particleSystem.maxLifeTime = 999;
particleSystem.emitter = avatar;//new BABYLON.Vector3(4.2, 3.0, 0.0);
particleSystem.manualEmitCount = 5;
particleSystem.direction1 = new BABYLON.Vector3(0.0, 0.0, 0.0);
particleSystem.direction2 = new BABYLON.Vector3(0.0, 0.0, 0.0);
particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_STANDARD;
particleSystem.color1 = new BABYLON.Color4(0.0, 0.0, 0.0, 1.0);
particleSystem.color2 = new BABYLON.Color4(1.0, 1.0, 1.0, 1.0);

particleSystem.start();

effect.onBind = function () {
    effect.setFloat("time", time);
	
};

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.