We are trying to develop a cross platform application that should render objects created at runtime dynamically. Case 1: 1 Million Unique geometries (meshes). Case 2: 300 Million Triangles in a single mesh.
Both these cases results in worst FPS and Memory when rendered using MeshRenderer and Graphic.DrawMesh with API.
Graphic.DrawMeshInstanced, Graphic.DrawMeshInstancedIndirect and other instancing API will not work in our case as we have unique geometries.
Even though above instancing APIs doesnât fulfill our requirements we tried those out of curiosity. Graphic.DrawMeshInstanced produced below par FPS. Graphic.DrawMeshInstancedIndirect doesnât support in WebGL.
What is maximum triangles and meshes count that can be rendered with target FPS as 30 ?
Any other suggestion which can fulfill the above requirement ?
It does not work like that. You can drop fps to single digits with one triangle if you use the right shader.
In this scenario youâre likely aiming too high.
I canât find the most recent data on number of meshes per second the most recent GPS can process, but thereâs a suggestion RTX 3XXX can go up to 20 billion triangles per second. With your 300 million triangles that SHOULD produce 60 fps, but in practice it wonât, because for that youâd need to render the mesh only once, and in the scene the mesh will be rendered several times. For example, in forward rendering mode it may be rendered extra time for additional lights, it WILL be again for each shadowcaster and so on.
When the lighting is involved, youâre increasing number of triangles effectively being drawn.
So in your scenario youâll need to start cutting corners. First see if you can even render it with unlit shader, no lights and shadows disabled.
If you canât, thatâs it - end of the line.
Most likely youâd need to introduce impostors in scenario #1 and try to split mesh #2 and calculate occlusion data for it.
Also youâd need to spend time in frame debugger to see what is eating your framerate the most.
You need to trick the player that he sees a high detailed world but in reality he does only see a small part of it. LODs, impostors, streaming etc. Also the upcoming nano tech asset will probably help
I know this is a Unity forum, but if you might also want to research Unreal engine 5âs nanite feature. Apparently itâs a software system that automatically bakes multiple optimizations for large. densely-triangled environements. I donât know if they need to be static meshes or not.
I would test the performance of case 2 (a 300 million triangles mesh) with a non dinamically generated mesh and if that is good make it procedural, if not lower the requirements.
Anyway, I was going to say that 1 million unique (!) meshes is a terrifying amount! Consider investing in a server farm that handles the rendering.
Seriously, it would help to know where these (insane) requirements come from and what these meshes are, what they represent, what the goal of the app is. Maybe you are rather looking for a break-through idea that makes the whole thing a lot easier rather than the brute-force everything is a mesh approach.
For example, point cloud rendering is one way to achieve highly detailed photo-realistic real world scans in realtime 3D but at the cost of extremely high memory usage and some visual oddities. Voxelization is another alternative, but with similar drawbacks. Or maybe you simply donât need every mesh to be unique. Maybe it could be done with textures or shaders instead?
In this forum thread, the creator is making a Nanite equivalent for Unity; it answers most your questions. Albeit, Invertex, explained, after I asked (having heard Nanite is space disk dependent), the reasoing, that it can increase the size of your game drastically (depending if organic or hard surfaces), an UE5 dev had said that it was 10x times bigger with Nanite on. Invertex said it is 1.5x-100x bigger; so that dev said a 10GB Nanite-using game would be 100GB roughly. I donât think hard drive space is such a problem today; with 10-15TB drives available (but still not SSDs/NVMesâŚfast onesâŚ) but old SATA mechanical/platters drivesâŚspace is there if you get a old tech SATA drive. Soon, SSDs/NVMes will also be several TBs; so in that sense, the problem is moot (gamers lacking hard drive space to install many âhugeâ games requiring 150-300GBâŚor more even; like COD requiring such; of course, it often means extreme high quality assets and oftenly little or no compression/less optimization per asset, and hundreds of thousands of these assets); What Iâm saying is thatâŚif your game is not huge, Nano tech is a great tool to have (as it does what Nanite does, but in Unity) and will save you a ton of time (of not having to do these optimizations to make your game playable (in fps) on lower hardware too).
If your game is hugeâŚthen itâs more problematic; because, you will Eat hard drive space, if using Nano tech. You will have to Design your game to use more âorganicâ shapes that cost little in Nanite space (instead of hard surface that are costly and wasteful for Nanite space disk demand). More so, than if you Donât use any Nanite/Nano techâŚyou could optimize your assets and it would take Less space than if converting your assets to be Nano-tech ready (because from what I understood it is not an ON/OFF switch/script (that applies this effect on everything realtime)âŚ
you must âpreconvertâ the 3d models-- to Nano-tech formatâto have Nanotech scriot read the assets/work.
So that is extra-work.
Itâs the same as using Impostors (as others said)/and/or LODsâŚ(check also that your impostors have shadowsâŚthis is crucial I found many impostorsâŚwith no shadow possibiliy, and especiall, Self-shadowing, very important. or else your objects impostereedâŚreceiveâ no shadows on theirselves)
One thing I do recommend the Nanotech or the ImpostorsâŚover LODs, is in âthe distanceââŚit is Visible in the distance that some models reduce in detail (using LODs) and it shows; quite clearly. I mean, the model is far in the distance, so is small (in terms of % size on the total rendererd image), but, it still shows in some models;
It means, that you canât Reduce polygon count - Too QuicklyâŚor it shows. Like, the model becomes blocky, with distance; but if too quick; itâs not quite visible. So, the best is to a gradual reduction of polys with distance; so itâs not evident. Like I was watching a scenery with very low poly LODs in the mid-to-far distanceâŚand it looked Very Low ResâŚlike PS2 graphicsâŚnot kidding. So, if you reduce the poly count too quickly - graphic LOD âdistanceâ - will make a game look much more âlast genâ; because you donâT see far in the distance/and/or the models in the distance are too low res/chunky.
This is where the Impostors shine; but itâs a long tedious thing but done with/in combinatino with LODs, itâs the best; and you combine that with (as you said) GPU instancing; or use âmesh combiningâ (but careful with this; mesh combining a ton of modelsâŚto make 1 Big modelâŚis greatâŚexcept it can explodwe memory demand; like thatâs what I read from devs who said they combined 100,000 thousand little modelsâŚto 1 modelâŚand it was just way too much memory demand - GBs RAMâŚthat single model (comprosing all the models - combined as 1) ate the memory);
So you have some tools, that do âregional combining/local combining/sector combining/cell combiningâ; where like, objects are combinedâŚbut âin cells/chunksââŚin a 3d gridâŚso itâs not 100% 1 mesh, itâs rather, letâs say 5 partsâŚand these 5 parts (represent the 100,000 objectS, combined as 5).
Impostors are not 100% solutionâŚlike, at close-up, it shows; you need at least 4K res for âclose-upâ of ImpostorsâŚor they look âFlat cardsâ (like old 2.5D build gamesâŚDuke Nukem 3dâŚetcâŚ) facing the camera no matter its angleâŚ
2d billboards.
At 8K, now they are quite sharp/detailed and quasi the same as regular 3d model; but rendering 8K impostorsâŚis long.
You must do this (once, only) and then itâs done. but this will take substantial hard drive space (these 8K texute impostors are not small; you must optimize them; like using âcrunch/compressionâ on the image itself; using like DX5 or BC7 compression, tha reduces their space disk size); but, still, as said, it is not as good as The 3d model itself; but, in the distance, it is better; because it is the Exact same detail of the model Close - or - Far from the camera;
while LODs always reduce poly count; and thus, make chunky low res models in the distance.
My take; a combination of these techs is best. And it depends of your needs/what you wish;
do you Need to âpreserve model detailâ â in the distanceâŚor you donâT careâŚand low res in the distance doesnât matter -itâs farâŚso who caresâŚ
(in my case, I care; becaeuse I noticed it and AAA games rarely have this Low res in the distance look; like the models do you use LODs but itâs not Drastic reduction neither).
As other said; you have no choice but to show only âa parcelâ of the world at any time; but only showing a little chunk; you reduce resources; so âhide/unhideâ; use occlusion (GPU occlusingâŚCPU occlusion is not cheap); frustum culling⌠etcâŚtricks that âhideâ everything friom view; but, also, can Remove from memory so not just hide; but Deactivate;
like, removing the asset from memory and then Reloading it - upon seen. So this way you reduce memory need (because âhidingâ the objectyâŚdoes not remove it from memoryâŚonly hides itâŚyou have to âunload assetâ but then you have to âreload assetâ so that itâs back in memoryâŚdepending- if in view/needed or not).
1 million objectsâŚwill liklely need serious optimizations (if not using the DOTS/ECS techsâŚ); like mesh combining; lods, texture compression; occlusion; culling; unload/load - depending distance/view; hide/unhide; make only a small peripheryâŚof any active/in view assetsâŚ
I wish to add; AAA games, I noticed, have Far view; like you can oftenly see in the distance they use tricks like âfogâ in the distance and âcamera cutting endâ; like after a certain distance, objects disappear there is nothing else; âcamera distance clippingâ;
And, oftenly, I noticed; in smaller games; that âcut-offâ is wayy too close (along with low poly models in distance); and this can feel claustrophobic or is a sign the game is not AAA; because AAA game âpush the distanceâ you can see far;; and that means using LODs/impostor for that to preserve the models in teh far distance; look at a game like assassinâs creed origins or red dead redemption 2; they have a very far LOD distance and the game runs well despite so; âseeing farâ is a sign of AAA game; even Escape from Tarkov (a Unity game) has very far LOD distance and you can see âmilesâ in the distance. Thatâs not âfreeâ in resources, itâs very taxing to have this far objects be seen clearly in the distance.
Hence, the trick is âfogâ to âhide it in the distanceâ and thus make a much âcloserâ âcamera clipping/endâ. But, as said, games that do that, are either going for claustrophobic look or are doing it on purpose (canât âview too farâ in the distance â too demanding in hardware resources/the engine canât). The other trick is to make, as said, a more claustrophobic-design gameâŚmostly 'hallways/corridor (âcorridor-shooterâ); where there is No âoutdoors/wide spaceââŚ
itâs all happening inside/in hallwaysâŚetcâŚyou donâT need to see farâŚwalls block the view.
Just 2 cents.
PS: There is more good to using Nanotech, than not. Your gamers will need hard drive space, buy New hard drive that has many TBs (SATA)âŚand if they buy ultra-fast NVMe/SSDsâŚwell your game will fit in itâŚand thatâS about it (you will eat the space on it; since itâs oftenly only 1-2TB); they will have to play 'install/uninstall/install/uninstallâŚas they will have to âpick&chooseâ between which big games to install).
PPS: One more thing, it was said, Nanotech/Nanite is still hard for non-static stuff (like great for buildings/non moving stuffâŚbut still not great for vegetation or any moving thing); like this âvirtual texturing/virtual modelâ tech is still too slow; and in that sense, it forces needing a NVMe/SSDâŚlike you need it because it is âmodel streamingâ techâŚand as such you drive must have very fast reading (like a NVMeâŚnot an old SATA). This will cause âmomentary catch-up/low-res texturesâ as the scene displays and âupdates itself/textures are readâŚand become hi-resâŚas they are readââŚjust like virtual texturing does; it catches up --as it reads/the stream (of the textures) on the disk. But, the Great thing about that is Memory cost (RAM); is it Much low RAM costâŚusing virtual texturing than using regular texture - put on GPU VRAM memory; still, if you compress/using compressing/crunching tech like BC7 or DX5 texture formatâŚplus lossy âcruchingââŚyou save a lot of VRAM space need (and stick to 4K resâŚinstead of 8K textures). But, it still, not as good as using virtual texturing tech; or, for 3d modelsâŚusing Nanotech. Thatâs what Invertex explained, you are trading memory spaceâŚfor disk space. So, thatâs the big caveat, itâs disk space and speed of reading; for Nanotech.
PPPS: Others mentioned shadow casters, very important, shadow casters/pixel lighting can tank frame rate, and
also shader complexity; use Defered mode, better for that (more pixel lights possible); check shadow caster count;
check Batch count and Draw call count; these will increase very rapidly and overwhelm the engine; stillâŚthereâs no magic button to make them lower; several AAA games - have 50,000 drawcallsâŚand they work/they made it work somehow. (problably using ECS/DOTS tech etcâŚ). Plus, use DSS, âimage resolution scaling/dynamic scalingââŚlike reduce complexity of everything depending the hardware and/or redude the Rendered Resolution.
Thatâs only if their geometry can even be processed by nanite. The whole thing smells like something weird or a special use case, like polygonizing a CT scan or displaying some sort of external data.
Because a videogame normally would not need this kind of numbers.
Whatâs your target hardware? Is the geometry being generated procedurally or is it being imported at runtime? Do you actually need that high poly density? If youâre trying to push 300,000,000 polygons to render, thatâs the equivalent of rendering a polygon for every pixel of a 1080p display nearly 150 times over.
Youâre not giving nearly enough information here.
Exactly, it sounds like visualizing some infrastructure project with raw data coming from CAD engineers. There itâs no surprise to go above 100M triangles per model.
I took from a presentation of the company that developed their ârendering codecâ and all toolset on the top of Unreal to handle such datasets. Theyâre presenting a visualization of ITER reactor construction.
And it seems like a reasonable solution. Even with Nanite, as engine rendering can handle huge meshes, tooling might not be prepared for such an insane triangle count. Just importing a few million triangle meshes to the engine can take a lot of time.
(Ignore stupid presentation name, it actually has nothing to do with metaverse blablabla, pure engineering talk)
I am a rookie in Unity, apologies for incomplete data in the OP and I will try to provide a detailed explanation on the requirement why we are doing this.
We are not building a game here but trying to build POC using unity that renders CAD 2D data.
Mostly these data are lines but a lot of them will come based on the size of building.
A very very small region of floor plan example that needs to be rendered is attached below as screenshot.
As the data source is from external application we have no control on the maximum meshes or lines that needs to be rendered. We are not expecting to render whatever input that is thrown at the application (certainly the amount of triangles/Lines rendered will be dependent on how good the hardware is) but at least we need to know the correct way/approach to render this in Unity.
Initially we tried out rendering these data using LineRenderer and MeshRenderer (with topology as lines) but we faced a lot of Memory overhead due to Game Objects with Renderer component.
Test Results: GPU - AMD Radeon R7 450 4GB Case 1:
No of Triangle: 100,000
MeshRenderer Used: 1
FPS: 1 Case 2:
No of Triangle: 50,000
MeshRenderer Used: 1
FPS: 2 Case 3:
No of Triangle: 50,000
MeshRenderer Used: 5
FPS: 15
Then to simplify things we just rendered a chunk of Line Geometry (100K Lines, Mesh Topology) inside a single Unity.Mesh with Graphics.DrawMesh API our memory issues were solved but we still faced issues with FPS.
We got better results in Graphic.DrawMeshInstancedIndirect but unfortunately the data that we get doesnât allow instantiation to work as it is unique Geometries. We understand 300 Million is too much for any GPU based on your feedback and its not realistic to render 300 Million Lines we agree that. But we are only looking for the best approach that can render the maximum amount of unique lines.
Youâre doing something strange here. With only 100k triangles, unity should run circles around it.
Profile the application, see what is happening. Line renderer is not really good for drawing lines (it is meant to be for drawing WIDE lines), plus thereâs a chanc that it is updating every frame. For wireframe rendering youâd need to be using line primitives, really.