Problem rendering Points depending on camera distance


I ahve found that sometimes it seems that rendering a Points object using gl_PointSize don’t render the points properly.

You can see the efect in this fiddle:

Just click at any point and zoom in, you will observ that sometimes the orbited selected point can be occluded by a point and in the next zoom in / out action it becames again visible.


and just zooming in:

You should be aware that points with a size greater one (pixels) tend to have an error-prone behavior.

Whether a point is drawn or not just depends on its center point. The extension of a point due to a size greater one is not honored by WebGL.

In WebGPU point clouds only can have a size of 1 pixel. So it’s better if you switch to instanced planes for your use case.

Hi Michael.

I have checked it with multiple graphic cardss and at least in my company in all cases the points are ren dered even if the center point is not at camera frustum.

This is not really the problem, the problem is that it seems that renderer is not sortering the points by z-buffer, starting from the most far away to the nearest ones.

For this reason sometimes points that sould occlude other points starts no behaving.

Instancing is not an option.

I want to use Points because I can render a 1M of points even in a slow laptop.

My idea is to use this mechanism is order to make my own occlussion culling mechanism for my scene.

My scene has 100k models (glb draco compressed and optimized) that are instanciated in a total amount of 1,5M instances with more than 1B of triangles. This is not feasible for any graphic card so I was thinking in using boundingSpheres for culling in multiple steps until no more meses will be required.

The idea is that each point will have the real boundingSphere using canvas size, camera fov and gl_PointSize using the double of radius of boundingSphere.

I have tested and readPixels take less than 30ms to read all pixels in my point scene so it’s feasible.

Each time the user changes camera
1.- render pointScene + realScene(initial empty)
- read attribute isLoaded and isVisible (if any of them is 1 the instance is invisible)
2.- extract pixel information (readpixel) and get instances group by model
3.- start to load required models and instanciate according point 2
4.- when a model is loaded all its instances are set to loaded (instanced isLoaded attribute)
5.- Proced again with point 1