Does THREE.ShaderMaterial create one shader per particle? I'm not sure how it works, If yes, how can I share/update data between each particles shader

Viewed 39

I would like to create a shader that simulates gravity between 2 particles. For this, each particle must know the position of the other particles, update its position accordingly, and therefore "share" its new position with the other particles.

If I understand correctly, when I do:

material = new THREE.ShaderMaterial({
         depthWrite: false,
         blending: AdditiveBlending,
         vertexColors: true,
         vertexShader: galaxyVortexShader,
         fragmentShader: galaxyFragmentShader,
         uniforms: {
             uTime: {value: 0},
             uSize: { value: 10 * renderer.getPixelRatio()},
             uPositions: { value: positionsVec3}
         }
     });

I create a shader for each particle ? The problem is that I send the position of all the particles once in "uPositions", but if each particle has its own shader, how can they update their position in the uPositions array to share it to other particles ?

1 Answers

What you're describing is demonstrated in the official protoplanets demo. It basically

  1. Calculates all velocities in a shader that is output as a 64x64 Texture.
  2. This Texture gets passed to a second shader that uses it to calculate all positions. This way each particle has access to all velocities.
  3. Then when rendering the planets onscreen, they all have access to both velocities & positions textures, so each vertex can access all data for their adjacent vertices. Using 64x64 textures gives you data for 4096 unique particles.
Related