I'm new to three.js and am trying to figure out the best way to add a 1000 particles each being a different size and color. The texture for each particle is created by drawing a canvas. By using a ParticleSystem all the particles are the same color and size. Creating a ParticleSystem for each particle is very inefficient. Is there an efficient way to handle this?
Asked
Active
Viewed 3,454 times
2
-
I haven't used Three much, but I'm pretty sure I've seen examples with a single ParticleSystem that has multiple colors. – Asad Saeeduddin Aug 15 '13 at 17:28
-
Do you have any existing code? I think I know how this can be done. – Asad Saeeduddin Aug 15 '13 at 17:34
-
See http://threejs.org/examples/webgl_custom_attributes_particles2.html – WestLangley Aug 15 '13 at 19:16
1 Answers
4
The best way to go about this, in my experience, is to create a customized shader material; you can then include attributes, which are properties that vary from particle to particle. Your shader code would look something like this:
Vertex shader:
attribute vec3 customColor;
attribute float customSize;
varying vec3 vColor;
void main()
{
vColor = customColor; // set color associated to vertex; use later in fragment shader
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = customSize * ( 300.0 / length( mvPosition.xyz ) );
gl_Position = projectionMatrix * mvPosition;
}
Fragment shader:
uniform sampler2D texture;
varying vec3 vColor; // colors associated to vertices; assigned by vertex shader
void main()
{
// calculates a color for the particle
gl_FragColor = vec4( vColor, 1.0 );
// sets particle texture to desired color
gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
}
For a similar live example, check out:
http://stemkoski.github.io/Three.js/ParticleSystem-Attributes.html

Stemkoski
- 8,936
- 3
- 47
- 61
-
2also see the [ShaderParticleEngine](https://github.com/squarefeet/ShaderParticleEngine) based on the work of @lee-stemkoski – dennis Aug 28 '13 at 18:02
-
+1: The link in the above comment runs 10x faster due to clever use of the GPU. – Stemkoski Aug 29 '13 at 01:15
-
meanwhile, threejs doesnt support material-attributes anymore, they're now in the geometry, and moreover, `Geometry.colors` is a standard array that can be filled, resulting in an attribute `color` passed to the shader. – N4ppeL Jan 21 '21 at 14:20