Point/Point material color?

Hi everyone!

I am trying to change the color for each one of the points through Points & PointsMaterial. But first I need to understand why is the colour not even changing statically; it is always on the default white. I tried changing the property “colors” in and “color” in and tried HEX, RGB, writing the color as I would do in CSS… Can somebody point me in the right direction? Thank you!:

import { useState, useRef, Suspense } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { Points, PointMaterial, Preload } from "@react-three/drei";
import * as random from "maath/random/dist/maath-random.esm";

const Stars = (props) => {
  const color3 = new THREE.PointsMaterial("rgb(255, 0, 0)");
  const numPoints = 5000
  const ref = useRef();
  const [sphere] = useState(() => random.inSphere(new Float32Array(numPoints), { radius: 1.2 }));
  
  // const colours = new Float32Array(numPoints * 3);
  // const availableColours = [ 0xAE / 255, 0xB2 / 255, 0xFD / 255, // #AEB2FD
  //                             0x85 / 255, 0xE7 / 255, 0xFF / 255, // #85E7FF
  //                             0xFC / 255, 0xBF / 255, 0x43 / 255, // #FCBF43
  //                             0x47 / 255, 0xA5 / 255, 0x6D / 255, // #47A56D
  //                           ];
  // for(let i = 0; i < numPoints; i++) {
  //   const colourIndex = Math.floor(Math.random() * 4);
  //   colours[i * 3] = availableColours[colourIndex * 3];
  //   colours[i * 3 + 1] = availableColours[colourIndex * 3 + 1];
  //   colours[i * 3 + 2] = availableColours[colourIndex * 3 + 2]
  // }

  // useFrame((state, delta) => {
  //   ref.current.rotation.x -= delta / 10;
  //   ref.current.rotation.y -= delta / 15;
  // });

  return (
    <group rotation={[0, 0, Math.PI / 4]}>
      <Points ref={ref} positions={sphere} stride={3} frustumCulled colors={color3} {...props}>
        <PointMaterial
          // transparent
         color={color3}
          size={0.002}
          sizeAttenuation={true}
          depthWrite={false}
        />
      </Points>
    </group>
  );
};

const StarsCanvas = () => {
  return (
    <div className='w-full h-auto absolute inset-0 z-[-1]'>
      <Canvas camera={{ position: [0, 0, 1] }}>
        <Suspense fallback={null}>
          <Stars />
        </Suspense>

        <Preload all />
      </Canvas>
    </div>
  );
};

export default StarsCanvas;

I suspect color3 should be an array of 0 to numStars*3 of floats 1,0,0 for red
[1,0,0, 1,0,0, 1,0,0,…] perhaps? or maybe an array of THREE.Color?

1 Like

points are instanced, colors are set with vertex attributes. materials have a prop called “vertexColors” for that use case.

declarative THREE.Points + changing colors
https://codesandbox.io/p/sandbox/point-cloud-zsyu9?file=%2Fsrc%2FApp.js%3A7%2C25

declaratie drei/points + changing colors
https://codesandbox.io/p/sandbox/r3f-points-eq7sc?file=%2Fsrc%2FApp.js%3A39%2C34

use THREE.Points for vast amounts of points. use drei if you need declarative nesting, grouping, adding other stuff to individual points.

2 Likes

Thank you so much. You’re a legend!