Changing particle opacity individually

So I am working on a project where I want to create a sort of “flashlight”-effect with the mousecursor. I have the coloring, relative to the distance to the raycast (casted from camera through mouse) done, but now I would like to make the particles that are way out of range of the raycast fully transparent. How can I achieve that? I am quiet confused because it seems like the color and opacity are completely seperated (color is stored in geometry and opacity is stored in material)

Here is a preview, for better understanding of my problem:

And here is the code how my points object is created:

function createParticles() {
    const particleGeometry = new THREE.BufferGeometry();
    const particlePositions = [];
    const particleColors = [];
    const particleCount = 10000;

    const sprite = new THREE.TextureLoader().load('../assets/circle512.png');

    for (let i = 0; i < particleCount; i++) {
        particlePositions.push(getRandomValue(-750, 750), getRandomValue(-750, 750), getRandomValue(-750, 750));
        const color = new THREE.Color(
            0,
            0,
            0
        );
        particleColors.push(color.r, color.g, color.b);
    }

    const particlePositionsBuffer = new Float32Array(particlePositions);
    const particleColorsBuffer = new Float32Array(particleColors);

    particleGeometry.setAttribute(
        "position",
        new THREE.BufferAttribute(particlePositionsBuffer, 3)
    );

    particleGeometry.setAttribute(
        "color",
        new THREE.BufferAttribute(particleColorsBuffer, 3)
    );

    const particleMaterial = new THREE.PointsMaterial({
        size: getRandomValue(25, 25),
        fog: true,
        map: sprite,
        vertexColors: true,
        transparent: true,
        alphaTest: .5
    });

    const particlePoints = new THREE.Points(
        particleGeometry,
        particleMaterial
    );

    scene.add(particlePoints);
}

I didn’t get an answer hahah but thats okay, i managed to do it without writing my own shader. In r127 they introduced vertexAlpha, so now you can use [nameOfYourGeometry].setAttribute ‘color’ with 4 Values (r,g,b,a) for each vertex (thank you to the devs <3)
Here is the updated code for anyone in the future:

function createParticles() {
    const particleGeometry = new THREE.BufferGeometry();
    const particlePositions = [];
    const particleColors = [];
    const particleCount = 10000;

    const sprite = new THREE.TextureLoader().load('../assets/circle512.png');

    for (let i = 0; i < particleCount; i++) {
        particlePositions.push(getRandomValue(-750, 750), getRandomValue(-750, 750), getRandomValue(-750, 750));
        particleColors.push(1, 1, 1,1);
    }

    const particlePositionsBuffer = new Float32Array(particlePositions);
    const particleColorsBuffer = new Float32Array(particleColors);

    particleGeometry.setAttribute(
        "position",
        new THREE.BufferAttribute(particlePositionsBuffer, 3)
    );

    particleGeometry.setAttribute(
        "color",
        new THREE.BufferAttribute(particleColorsBuffer, 4)
    );

    const particleMaterial = new THREE.PointsMaterial({
        size: 3,
        map: sprite,
        vertexColors: true,
        vertexAlphas: true,
        transparent: true,
        depthWrite: false,
        blending: THREE.AdditiveBlending,
    });

    const particlePoints = new THREE.Points(
        particleGeometry,
        particleMaterial
    );

    scene.add(particlePoints);
}

Do you need vertexAlpha with the latest release, as in the current r151 vertex colors can be 4-bytes.

Reference: vertexColors.

1 Like