Most efficient way to represent lots of 3D points in a scene?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By dodgyville

If I have a list of points with x,y,z coordinates and want to draw/render/place them in a 3D scene what would be the best way to do it? Especially if there are a lot of points (100k+).

Thanks for any suggestions!

:bust_in_silhouette: Reply From: MysteryGM

Point clouds, you will probably want to look at OpenGl tutorials and Godot shaders.

The concept is simple. Every point has 2 values, a vector and a color; making it the most efficient point.
Then to render large worlds you will want to do some octree sorting, to only render what is seen.
Simple octree explanation: https://www.gamedev.net/articles/programming/general-and-gameplay-programming/introduction-to-octrees-r3529/

:bust_in_silhouette: Reply From: dodgyville

Ok, I got some results using ImmediateGeometry. But the dots are tiny and strobe in and out (even with AA switched on).

var im = ImmediateGeometry.new()
add_child(im)
var m = SpatialMaterial.new()
im.set_material_override(m)
im.clear()
im.begin(Mesh.PRIMITIVE_POINTS, null)
for vector in pts:
    im.add_vertex(vector)
im.end()

You could create small cubes or billboarded planes instead of using OpenGL primitive points (which are very limited). However, Godot doesn’t support mesh batching out of the box (unless you use something like MultiMesh), so you would have to implement it yourself to keep the number of draw calls to a reasonable value.

Calinou | 2018-10-13 10:46

Couldn’t you just increase the point size?

SIsilicon | 2018-10-13 13:53

Yeah, I don’t know how to increase the point size of ImmediateGeometry

dodgyville | 2018-10-13 20:53

If you’re using a SpatialMaterial then just set the point_sizein the parameter tab section.
If you’re using a ShaderMaterial on the other hand, then set this variable POINT_SIZE in the vertex shader to whatever you want.

SIsilicon | 2018-10-14 02:36

Perfect! Thank you so much!

Had to also set flags_use_point_size to true. In case anyone else needs it:

var point_size = 5
var im = ImmediateGeometry.new()
add_child(im)
var m = SpatialMaterial.new()
m.flags_use_point_size = true
m.params_point_size = point_size
im.set_material_override(m)
im.clear()
im.begin(Mesh.PRIMITIVE_POINTS, null)
for p in pts: #list of Vector3s
    im.add_vertex(p)
im.end()

dodgyville | 2018-10-16 08:29