Can't change opacity of points in particle system

I’ve set all of the options for transparency and opacity in the renderer, scene, and my texture. I’m slowly reducing each point’s opacity but the appearance is unaffected.

    const opacities = this.particleSystem.geometry.attributes.opacity.array;

    if (Date.now() > this.duration) {
        this.fadingOut = true;
    }

    if (this.fadingOut) {

        const fadeSpeed = 0.005;

        let allFadedOut = true;
        for (let i = 0; i < this.particleCount; i++) {
            opacities[i] -= fadeSpeed; 
            if (opacities[i] > 0) {
                allFadedOut = false;
            } else {
                opacities[i] = 0;
            }
        }

        this.particleSystem.geometry.attributes.opacity.needsUpdate = true;

        if (allFadedOut) {
            this.stop();
            return;
        }
    }

Post your material setup and how you create your geometry.

Make sure you have .transparent=true on your material.

I’ve never seen “opacity” used as a separate attribute channel, so I don’t know if that is “a thing” or not.

I’ve seen the use of a separate “color” attribute that is either vector3 or vector4 (if you want alpha)

const targetPosition = target || new THREE.Vector3(5, -5, 0);

const particleCount = 1000;
const particles = new THREE.BufferGeometry();
const positions = new Float32Array(particleCount * 3);
const speeds = new Float32Array(particleCount);
const distances = new Float32Array(particleCount);
const directions = new Float32Array(particleCount * 3);
const opacities = new Float32Array(particleCount);

const particleMaterial = new THREE.PointsMaterial({
    color: 0xffffff,
    size: 5,
    transparent: true,
    opacity: 1
});

for (let i = 0; i < particleCount; i++) {
    positions[i * 3] = targetPosition.x - (Math.random() - 0.5) * 10;
    positions[i * 3 + 1] = targetPosition.y - (Math.random() - 0.5) * 10;
    positions[i * 3 + 2] = targetPosition.z - (Math.random() - 0.5) * 10;
    speeds[i] = Math.random() * 0.02 + 0.01;
    distances[i] = Math.random() * .2 + 1;
    directions[i * 3] = Math.random() - 0.5;
    directions[i * 3 + 1] = Math.random() - 0.5;
    directions[i * 3 + 2] = Math.random() - 0.5;
    opacities[i] = 1.0;
}

particles.setAttribute('position', new THREE.BufferAttribute(positions, 3));
particles.setAttribute('speed', new THREE.BufferAttribute(speeds, 1));
particles.setAttribute('distance', new THREE.BufferAttribute(distances, 1));
particles.setAttribute('direction', new THREE.BufferAttribute(directions, 3));
particles.setAttribute('opacity', new THREE.BufferAttribute(opacities, 1));


const particleSystem = new THREE.Points(particles, particleMaterial);
scene.add(particleSystem);

I don’t think speeds, distances, directions, or opacities are being used for anything, by the default PointsMaterial

Are you putting the pointsmaterial through some kind of particle system injection or library?

That’s the extent of my setup for using the PointsMaterial and gradually reducing particle opacity. I’ve set transparent on everything I could find. I thought maybe there was a trick I was missing.But no, no libraries, just updating positions in the animate loop.

Ahh i see. ok then you don’t need to make those other arrays as attributes.
Only the color array is really observed by the shader.
Just make them arrays and use them as you are now.
You only need them as attributes if you are doing your animation inside the shader.
For color… look at how this example sets up the color attributes:

For per particle transparency, I think you can use Vector4 instead of Vector3 for the color and get alpha that way.

Thank you for your replies, I appreciate your help. I’ve decided to just remove them in a random pattern at the end of their animation for a different kind of fade-out effect.

1 Like