Rendering single large mesh

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

Hello.

I’m making visualization which is a single (procedurally generated) mesh that consists of ~10’000’000 triangles.

The mesh itself is represented by a unit sphere located in origin (i.e. a sphere with radius 0.5with center in 0, 0, 0) and is an instance of MeshInstance3D. Mesh generation is performed via SurfaceTool by adding necessary vertices. Mesh is generated only once (in _Ready) and then it does not change.

Besides mesh itself, scene contains DirectionalLigth3D and Camera3D which is located at 0, 0, 2 with the FOV set to 75 (default), Near 0.05 and Far 2 so that camera only “sees” the front half (or front hemisphere) of the sphere.

Even with that setup I barely get 30 FPS. What is more important, even if I move camera closer to the sphere, so that only small part of the sphere is visible the FPS does not change.

Visual profiler shows that engine spends most of the time in Depth Pre-Pass and Opaque Pass, so I guess - drawing geometry?

To my understanding, it does not matter what is visible, the engine has to render the whole mesh, it cannot (at least, automatically) to draw only visible part of the mesh. Is there anything I can do about it? I’ve tried to use ArrayOccluder3D and I set vertices taken from mesh but it didn’t help.

If it matters, I’m using Windows 10 x64, Godot 4.0 rc5 mono x64 and C#.

I am currently thinking that I either need to split this single mesh into several chunks to benefit from culling or to render it to texture (via Viewport?) and then just render the texture on a much simple spherical mesh. Is there anything else I can do?

MichaelFang | 2023-02-28 13:09

:bust_in_silhouette: Reply From: Wakatta

Your thoughts are spot on.
In fact game developers 101 suggests when rendering large terrain or big objects (skyscrapers, giant robot cars, planets), you need sub-divide the mesh and then use view frustum culling on the scene’s camera.

Luckily for you Godot already does the latter automatically and the division of your mesh will really depend of its overall shape (sphere, square, Porygon)

For the texture have a look at splat mapping or create one very large image and sub-divide the same as the mesh applying to each “chunk”

Oh almost forgot for some reason Godot seems to move much faster with fewer nodes in scene (Go figure), so obviously having a scene with 1000+ objects that aren’t being rendered would consume some negligible FPS that would be more noticeable with more nodes.

With the above in mind would recommend creating some kind of manager to add / remove chunks based on its proximity to the camera’s frustum.

Additionally if you have the patience the above can be achieved with MultiMeshInstance or a shader

Wakatta | 2023-02-28 15:21