10

I'm creating loads of particles (80.000 to be exact) and I have set a transparent map, though, not all particles are transparent.

I'm using a transparent PNG image: particle.png (it's barely visible but it's there alright) as the material map, though it shows a black background as seen here:

particles

If you look closely, some particles blend together well (no overlapping black edges) though some do not. Could it be because there are so many overlapping transparent objects or shouldn't this be an issue?

Here's the snippet responsible for the generation of my particles:

// load the texture
var map = THREE.ImageUtils.loadTexture('img/particle.png');

// create temp variables
var geometry, material;

// create an array with ParticleSystems (I need multiple systems because I have different colours, thus different materials)
var systems = [];

// Loop through every colour
for(var i = 0; i < colors.length; i++) {
    // Create a new geometry
    geometry = new THREE.Geometry();

    // create a new material
    material = new THREE.ParticleBasicMaterial({
        color: colors[i],
        size: 20,
        map: map, // set the map here
        transparent: true // transparency is enabled!!!
    });

    // create a new particle system
    systems[i] = new THREE.ParticleSystem(geometry, material);

    // add the system to the scene
    scene.add(systems[i]);
}

// vertices are added to the ParticleSystems' geometry here

Why do some of the particles have a black background?

gman
  • 100,619
  • 31
  • 269
  • 393
Tim S.
  • 13,597
  • 7
  • 46
  • 72
  • I have a quite similar issue aiming at removing the background [http://stackoverflow.com/questions/20742809/three-js-invisible-background-for-background-and-png-particles](http://stackoverflow.com/questions/20742809/three-js-invisible-background-for-background-and-png-particles) – gronaz Dec 31 '13 at 12:37

4 Answers4

20

You can set the alphaTest property of the material instead of transparency. For example,

material.alphaTest = 0.5;
material.transparent = false;

three.js no longer sorts particles; they are rendered in the order they appear in the buffer.

three.js r.85

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • 1
    The actual solution to this specific problem is in the comments of the other answer, however your solution is great as well! In my case I had to use this because I'm dealing with so many particles. The "proper" way really screwed up my FPS though I would recommend it as answer in most cases. Much appreciated anyway! – Tim S. Aug 06 '12 at 12:53
  • Same, with 100k particles I keep my 60fps with your solution while in the solution in comments of Roest's answer I get 30fps. – Tib Jun 03 '14 at 20:32
  • I ALSO AM EXCITED ABOUT THIS ANSWER THANK YOU! – Andy Aug 18 '17 at 19:12
12

Those particles with black corners are rendered before anything behind them. So GL doesn't know yet there is something behind to blend. In order to make it look right you have to render these particles in the order of their z coordinates from back to front.

Roest
  • 826
  • 6
  • 16
  • How can I tell `THREE.WebGLRenderer` to render from back to front? It's a 3D environment where you can move around so the z-index will be variable. – Tim S. Aug 06 '12 at 12:27
  • To be honest I have no idea if three.js could add some magic to do that for you. My answer was generally about rendering transparent objects and yes, in the 3d environment, if the camera moves, you transform your coordinates and sort the objects again. An alternative would be using another technique for transperancy like depth peeling. – Roest Aug 06 '12 at 12:32
  • 15
    I had to set the material's `depthWrite` property to `false`! – Tim S. Aug 06 '12 at 12:34
  • 10
    Oh and I had to set the property `ParticleSystem.sortParticles` to `true` as well. – Tim S. Aug 06 '12 at 12:46
  • 1
    Could you post a link to a complete working example of your code, please? It would be most helpful. Thanks! – Stemkoski Jun 11 '13 at 19:28
1

Disable the depthWrite attribute on the material.

// create a new material
material = new THREE.ParticleBasicMaterial({
    color: colors[i],
    size: 20,
    map: map,
    transparent: true,
    depthWrite: false,
});
hughes
  • 5,595
  • 3
  • 39
  • 55
0

Try webgl_particles_billboards.html. If I'm right it does the same thing you expect.

Fract
  • 323
  • 1
  • 6
  • 22