All points in point cloud have same color

I have following code to render point cloud:

var pointsWithColors = <array of objects where each object has x,y,z,r,g,b values>
const flArr = new Float32Array(pointsWithColors.length * 3);
var colors = new Float32Array(pointsWithColors.length * 3);
var sizes = new Float32Array(pointsWithColors.length);
var alphas = new Float32Array(pointsWithColors.length);
for (var i = 0; i < pointsWithColors.length; i++) {
	  flArr[i * 3 + 0] = pointsWithColors[i].x;
	 flArr[i * 3 + 1] = pointsWithColors[i].y;
	 flArr[i * 3 + 2] = pointsWithColors[i].z;
	 colors[i * 3 + 0] = pointsWithColors[i].red;
	 colors[i * 3 + 1] = pointsWithColors[i].green;
	 colors[i * 3 + 2] = pointsWithColors[i].blue;
	 sizes[i] = 0.1;
	 alphas[i] = 1;
   }
scene = new THREE.Scene();
geometry = new THREE.BufferGeometry();
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
geometry.setAttribute( 'position', new THREE.BufferAttribute( flArr, 3 ) );
geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3, true ) );
geometry.setAttribute( 'size', new THREE.BufferAttribute( sizes, 1 ) );
geometry.setAttribute( 'alpha', new THREE.BufferAttribute( alphas, 1 ) );
var pointCloud = new THREE.Points( geometry);

Points are rendered, but all points have same color.

What am I missing here?

This line needs to be something like this:
var pointCloud = new THREE.Points( geometry, new THREE.PointsMaterial( { vertexColors: true } ) );
:thinking:

I tried this too, but no change.

Any chance to provide a minimal working live code example, that demonstrates the issue?

What color are they coming out as?

I might be wrong about any of the following, but here it is:

How are your objects constructed, is it x,y,z,r,g,b or is it x,y,z,red,green,blue ? Maybe you should show one of the objects.

If you check the BufferAttribute documentation, it shows the itemSize in the constructor so depending on what you are aiming for it could be 3 for RGB or 4 for RGBA, and since you seem to be creating some custom alpha attribute maybe you should just switch to the following:

 colors[i * 4 + 0] = pointsWithColors[i].r; // or .red if marked as such
 colors[i * 4 + 1] = pointsWithColors[i].g; // or .green if marked as such
 colors[i * 4 + 2] = pointsWithColors[i].b; // or .blue if marked as such
 colors[i * 4 + 3] = 1.0; // alpha

 // then add it like this
 geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 4 ) );

You would need to pay attention to the length of the array you are creating.

Also, size is the property of the PointsMaterial and not really an attribute, so the final construction should be as the @prisoner849 suggested but with the size:

var pointCloud = new THREE.Points( geometry, new THREE.PointsMaterial( { size: 0.1, vertexColors: true } ) );

Assuming these are not huge, you can always log to the console all of the arrays, including the original point cloud array, and see what your code puts in each array and compare it to the original.

Object is as:

{
“x”: 378930,
“y”: 2048040,
“z”: 552.54,
“red”: 139,
“green”: 151,
“blue”: 148
}

It is always white.

image

Try dividing your color values by 255 since they show as unsigned integers.

3 Likes