1
\$\begingroup\$

I am developing an opengl 4.0 app which is showing a point cloud. In the other hand, I have an array "pos" where I have some x,y,z positions:

pos[number of pos][3] , where 3 refers to [0]:x [1]:y [2]:z

I would like to show only the points of the point cloud which are inside of a sphere of radius R for any of the positions I have in the array pos. I was thinking in sending the array pos to the vertex shader that draws my cloud point and there, do a loop for each position and check if the distance between any of the positions and the vertex is less than a radius R. If so, I put an alpha colour of 1.0. If not, an alpha colour of 0. Something like:

Vertex:

#version 460

uniform mat4 viewMatrix, projMatrix;
uniform float Radius;

in vec4 position;
in vec3 pos[N];

in vec3 color;

float d;

out float Color;
out float AlphaC;

void main()
{
    Color = color;
    AlphaC = 0.0;

    for ( int i = 0; i < pos[i].length; i++ ) {
        d = distance(vec4(pos[i],1),position);
        if (d<Radius) {
            AlphaC = 1.0;
            break;
        }
    }

    gl_Position = projMatrix * viewMatrix * position ;
}

Fragment:

#version 460

in float Color;
in float AlphaC;

out vec4 outColor;

void main()
{
    outColor = vec4(Color, AlphaC);
}

But I am not sure how to send this pos array since this matrix is an Nx3 with N depending in the file of positions that I am using. Any idea? Does N has to be defined before compiling?

\$\endgroup\$
  • \$\begingroup\$ You want to send the whole array to the shader and call it once per draw call? Then iteratively go through the points? That defeats the purpose of the gpu. The shader should only handle a single point. Checking its distance. Then it can be done in parallel. \$\endgroup\$ – Andrew Wilson Feb 3 '18 at 21:33
  • \$\begingroup\$ My cloud point have always same positions but colours are different each frame and I want to show less transparent the points of the cloud around some positions that also change in each frame. How would you do it? \$\endgroup\$ – Learning from masters Feb 3 '18 at 22:02
  • \$\begingroup\$ Make your vertex shader accept only a single vertex and check if it's valid. If the positions don't change though you may want to consider not validating them every time you draw them. IE: Before the program even starts get the points in the sphere out throw them in a vertex buffer and draw. \$\endgroup\$ – Andrew Wilson Feb 3 '18 at 22:26
0
\$\begingroup\$

It sounds like you want to have points that are more than a certain distance from all other points not be drawn, right? If so, I would recommend using something like an Octree data structure to store your points.

With an octree you generate a bounding box around all your points. You then break that up into 8 smaller boxes (cutting the big box in half along each axis). You continue cutting the boxes in half until it gets down to the size of the maximum allowed distance between points.

Next you insert your points into the octree. Each point gets filtered down into the smallest box that contains it. Once all the points are in, you can walk the tree. For each leaf box in the tree, if it contains more than 1 point, then all points in that box should be added to the list of points to draw, because they are by definition all within the maximum allowed radius.

For leaf boxes that contain a single point, you need to compare that point to the points in the neighboring 26 leaf boxes to see whether it's within the maximum allowed distance. As soon as you find 1 point that it's close enough to, you know to include that point in the list of points to draw.

Finally draw only the points in the list you built.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.