GPU Particle Custom Effect Sprite Index

Hello, and I am trying to attach a custom effect to a particle system in ES6 (ts with treeshaking), but can’t seem to access shader attributes (per particle). I have copied the code into the following playground where it runs without issue (playground). It uses a copy of the babylon particle code as a custom effect.

When the same code runs in a packed project the sprite settings are not passed to the vertex shader. I can see that the attributes have been shared correctly, but they are not being used in the shader.

I have tried importing:

import '@babylonjs/core/Helpers/sceneHelpers';
import '@babylonjs/core/Materials/Node/Blocks';
import '@babylonjs/core/Particles/particleSystemComponent';
import '@babylonjs/core/Particles/webgl2ParticleSystem';

Thanks for any help,
r

Trying to narrow down the problem, does it work when using the CPU particle system? Also, I assume it works with the GPU particle system if you don’t set a custom particle effect?

The sprite sheet uvs disappear when I attach a custom effect for both CPU and GPU particle systems. The full texture appears instead, without alpha multiplication, until it dies at the correct per-particle lifetime.

Without attaching the custom effect the particles render as expected (with alpha and sprite animation).

r

When looking with Spector, do you have the #define ANIMATESHEET line in the vertex/fragment shader of the draw call that renders the particle system? If so, maybe a repro somewhere will help us better understand what may be wrong.

1 Like

Hey, and thanks for pointing me to Spector, as it helped me to uncover the issue I was causing.

The defines need to be passed to the custom shader at the time an instance is generated for both vertex and fragment. There is a customShader parameter on the particleSystem, which hosts the defines which are currently being used.

This helped me to solve the issue with defines:

  const defines: string[] = [];
  particleSystem.fillDefines(defines, particleSystem.blendMode);

  const effect = engine.createEffectForParticles(
    'customParticleShader',
    [],
    [],
    defines.join('\n'),
    undefined,
    undefined,
    undefined,
    particleSystem
  );

// ensure the current blend mode is our target
particleSystem.setCustomEffect(effect, particleSystem.blendMode);

r

1 Like