[update] I managed to improve the culling jobs by using Unity.Mathematics. It was previously 1ms, now it is down to 0.5ms. I also tested twice the amount, as in 18 million objects, and still got the same result, except it takes a little longer to setup at start.
Greetings,
I have been looking at a way to handle large scale GPU-instancing (using Graphics.DrawMeshInstanced()) and found that using the Job System for culling worked well for my project. I am down to an average of 0.5ms thread-time handling over 9.1 million instanced objects placed on the meshes of the terrain. Hereby follows how it works:
This is an overview of the camera which all the lines connect to (they show visible triangles), and the triangles which has GPU-instanced objects on them. There are several scheduled Jobs in place, the first one being based on area distance alone, the others are per area. This way I can split up the batches needed for DrawMeshInstanced() per area, and process less objects per update as they all get handled from a list generated by the visibility received from the first Job System. The jobs are scheduled based on size and time, as they do not need to be called every frame. Currently the first job system works at most once per second, and the per-triangle ones once work at most every 0.2 seconds.
Here is how the culling works from the ground level. Currently the max distance is set to 4096 units which is the same as the far clipping plane of the camera, and the per-triangle area distance is set to 1024 units. The viewing angle is set to 135 degrees. With distance/frustum-culling only at most a few thousand objects are rendered at once.
This is what it looks like from the game camera. Sorry about the terribly low capture-rate FPS, this runs much better.
The main Update()-logic is a for-loop within a for-loop that runs over lists populated with the Matrix4x4s of the visible objects gathered from comparisons performed in the Job Systems. Due to large batches being an issue on WebGL (this game is made for that platform) I’ve had to include another for-loop for them as well, as I have only been able to get this to work with smaller batches under 100 per batch so far. The system is far from perfect, and lots of improvements can be done.
My next version of this will include man-made structures as well, and once I get ECS in, almost anything moving that will be needed to be drawn in large quantities.
You can see a live version of it if you are interested. Due to it being a very early tech-demo, the game will hang a bit at the start as it populates the 9.1 million instances, and I haven’t come as far as including that in the initial start-up loading: