Point cloud rendering more than 2m points. Distance between points and colors

I am trying to render a point cloud data from a huge array I have containing very big numbers (jovial-volhard-n3vfxm - CodeSandbox). This is just an example.

But nothing I do to change the distance between and colors based on a colormap value works here and I just dont know what I can do anymore…

Could you tell me what am I doing wrong here?

it’s quite unclear what you’re tying to do + the outcome you desire from this breif description, any chance you could you elaborate on what you’re looking to achieve?

at first glance it doesn’t seem like you’re feeding any color data to the fragmentShader, for example if you simply change the color values you can achieve an overall different color to the shaderMaterial you’re assigning to the points…

export const fragmentShader = `
uniform vec2 resolution;
varying float vSize;
void main() {
    vec2 cxy = 2.0 * gl_PointCoord - 1.0;
    cxy.y *= resolution.y / resolution.x;

    float r = max(abs(cxy.x), abs(cxy.y));

    if(r > vSize) {
        discard;
    }
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                      //^^r, ^^g, ^^b, ^^a
}
`;

if you wanted to apply a colormap you’d need to feed that data into the fragment shader and apply it to the FragColor.

also the same applies for any distance between the positions, again you’d most likely want to feed a uniform into the vertexShader and modify the scaling of the positions, here’s a basic example of how you could achieve this…

export const vertexShader = `
attribute float size;
varying float vSize;

void main() {
    vSize = size;

    vec4 mvPosition = modelViewMatrix * vec4(position.x * 6.0,position.y * 6.0,position.z * 6.0, 1.0);
                                                 //^^posX * 6,      ^^posY * 6 ,     ^^posZ * 6
    gl_Position = projectionMatrix * mvPosition / 1.5;
    gl_PointSize = vSize * (300.0 / -mvPosition.z);
}
`;
1 Like

Yes, I know I went very unclear here, but anything I was trying wouldn’t change anything.

Thank you for your response.

So what I meant was to apply colors based in the values I was passing, but really nothing would work.
My goal is to apply colors based on the density values and display it in a heat colormap.

I have the colormap values already and it should render in each point, but doesnt work…

export const colormap = [
	300, //hsl(300, 100%, 50%)

	270, //hsl(270, 100%, 50%)

	240, //hsl(240, 100%, 50%)

	210, // hsl(210, 100%, 50%)

	180, //hsl(180, 100%, 50%)

	150, //hsl(150, 100%, 50%)

	120, //hsl(120, 100%, 50%)

	90, //hsl(90, 100%, 50%)

	60, //hsl(60, 100%, 50%)

	30, //hsl(30, 100%, 50%)

	0, //hsl(0, 100%, 50%)
];

I’ve managed to do it, but the colors seems a little weird to me. you can check it here:

I’m not really sure how the colors are supposed to look so i wouldn’t be able to say, i can guess what you mean by this is that the more dense points would be colored red and the less dense green? In which case yes they don’t seem to be quite correct as there are sparse points adopting a red color :thinking:

do you notice in PointCloud.tsx, the line…

  const sizes = groupedPoints.flatMap(({ relativeDensity }) => [
    relativeDensity * pointSize
  ]);

if you remove relativeDensity from the equation and just keep pointSize that the colors somehow seem to be evaluating more correctly (from what i’d imagine)? maybe the relativeDensity is either missing or not quite right in the calculations of the colors somehow?

another thing to note is that the hue value of hsl has 0 to 359 degrees of rotation, in the same file, you’re only dividing the initial color value by 300, maybe that’s your intention but you’d likely want to divide this by 359 for more accurate colors overall…

if (color || color === 0) {
  const h = color / 359;
  return hslToRgb(h, 1, 0.5);
}

EDIT: one thing I also noticed is that the scale of the sparse / blue points are simply too small to see, you may want to compress / scale the sizes’ so the highest and lowest values are both closer to 1 (or a common screen space scale) to make smaller less dense points visible…

Im sorry again.
Yes, the most dense would be red and the less would be green. It means that density coming from the data the closest to the lower number green and so on. The problem with removing the density is that the size is related to it, like the point size should follow this, but as you could see, the numbers are very low, so I put the pointSize in the equation to make it bigger in case of user needs.

I mean, actually the colors should follow this map. But its also not working properly I think, because the hsl(300, 100,50) should be the most dense.

export const colormap = [
	300, //hsl(300, 100%, 50%)

	270, //hsl(270, 100%, 50%)

	240, //hsl(240, 100%, 50%)

	210, // hsl(210, 100%, 50%)

	180, //hsl(180, 100%, 50%)

	150, //hsl(150, 100%, 50%)

	120, //hsl(120, 100%, 50%)

	90, //hsl(90, 100%, 50%)

	60, //hsl(60, 100%, 50%)

	30, //hsl(30, 100%, 50%)

	0, //hsl(0, 100%, 50%)
];

the point sizes can get very low yes, does it help visualize things a bit better with a more linearly mapped array of sizes?

it looks so much better, but then when I apply a pointSize multiplication by the outputNumber, the pixels looked very inconsistent, if I could say this way. Because this is a feature that should allow the ui to increase / decrease the pointSize depending on their needs.

But it looked really really better, and the points seems very close to the desired look and feel.

OK yeah if you wanted to include pointsize you just have to play with and adjust the minOutput and maxOutput values of mapToRange

const minOutput = 0.7;
const maxOutput = 4;