Jump to content

LOD performance tips


photo

Recommended Posts

Posted

Hello,

I have some questions related to performance (CPU usage) in computing LOD distances:

1) I am currently creating some big static meshes (made of many surfaces, few hundreds) as I am trying to collapse multiple objects into one. Now, this static mesh is supposed to have a LOD (to have its surface disappear after a distance). So for each of its surfaces I set setMaxVisibleDistance with the same distance. The max parent is left default, which I believe is 1, so this means that the same LOD distance is computed for all surfaces, relative to the static mesh common pivot. The main question being: is Unigine smart enough to compute this distance to camera only once, or does it compute the distance for each surface alone, redoing the same calculus over and over again per frame? By looking at the code, seems to be doing the computation only once, but please confirm that is doing this for all cases (normal visibility, shadowmap rendering etc).

If this is not the case, is there a better solution for this? Like for example creating some sort of common parent node and put the LOD distance on that, instead of each individual surface?

It also seems to be doing this distance computation in a separate thread. Is this correct?

2) The second question is again related to LOD max distance, but to clusters of objects. This time the distance is set globally, per cluster. Is this computed to the cluster center? If so I may need to break the cluster into multiple ones, just to control the LOD transition better, since my clusters are quite huge.

Kind Regards,

Adrian

Posted

AFAIK distance to each surface is computed separately, because such object can be really big and you setup LOD distance per each surface. 

Anyway I wouldnt recommend to create one huge mesh with hundreds of surfaces, because you cant use advantage of frustum culling (it is done per mesh, not per surface). There is no general rule, because it is always case by case (size of mesh, purpose of such mesh, detail of mesh, where is object placed, type of game...), so hard to give you any advice without knowing your use case, but generally: Split big mesh into more parts, merge all surfaces with same material into one. For higher LODs try to create texture atlases, as last LOD you can generate billboard. You can also use cascaded LOD ("LOD" on mesh level), for example in the first level you can have 100 objects (meshes), in second level 10 and in last level one.

 

 

 

 

 

Posted (edited)

Hi and thank you for the advices!

I've checked the source code and it seems that if you are using parent as reference for the LOD, the distance is computed once per all surfaces in that object. Can an Unigine dev confirm or not this?

Also, in my case, I need to collapse this in fewer objects since: they are mostly seen from far away, the object relative size is small so frustum culling is ok. We already have too many nodes in scene. Scene traversal is an issue for us. Also in the end I will collapse the geometry so I may not end up with so many surfaces per object, but it is good to know that even for few surfaces Unigine is doing as few distance computations as possible.

Regards,

Adrian

 

Edited by adrian.licuriceanu
Posted (edited)

If the object is far away, you could try something like this: https://www.texturebaking.com/features/ Hundreds of surfaces will eat performance significantly. Material change is expensive operation.

Edited by demostenes
Posted

Hello, thank you for the link, but unfortunately we cannot do any scene preprocessing whatsoever. All needs to be done in background, during streaming. We have other restrictions, trade-offs etc, but there are too many details to go into.

Again, I would very much like if someone from Unigine can confirm / disconfirm my initial questions about LOD:

1) When using multiple surfaces in an object, is Unigine smart enough to compute the LOD distance to camera only once, or does it compute the distance for each surface alone, redoing the same calculus over and over again per frame? Seems that way, but I would be interested if this is always the case (e.g. for shadows, for reflections, or any other cases).

2) Is the LOD distance computed to the object cluster center? Seems this way, while the fade distance is computed per element inside cluster (probably inside vertex shader?).

Regards,

Adrian

  • 3 weeks later...
Posted

Adrian, I'm sorry for the delay in response.

On 8/31/2018 at 4:04 PM, adrian.licuriceanu said:

When using multiple surfaces in an object, is Unigine smart enough to compute the LOD distance to camera only once

Usually yes, but it depends on circumstances. If the camera is static it will be computed once. Using your words, the engine is smart enough to skip unnecessary computing:) Describing all the nuances on how it's done will take a lot of time because different conditions enable different logic.

On 8/31/2018 at 4:04 PM, adrian.licuriceanu said:

 Is the LOD distance computed to the object cluster center?

LOD distance is computed per object in cluster. Did you mean center of each mesh in cluster or center of the cluster itself? You can do some experiments in Samples -> Mesh Cluster demo, it shows how fade and visibility distance works.

Regarding the original question about performance. After I spoke to our devs it was clear that computing distance to the LODs is one of the last things that should be concerned about. CPU can become a bottleneck in other cases, for instance, when you're changing transform of hundreds of objects. But we're ready to present an optimization for this case in 2.8.

If you experience some performance issues it's better to share a test scene so we can give you proper feedback.

Thank you!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Posted

Hello Morbid and thank you for all the info!

Indeed performance seems to be ok when computing LODs, it is not currently something that shows-up high in our profiling.

About cluster, after some debugging, it seems that the distance is indeed computed hierarchically for the internal split nodes created by the engine for that cluster (it creates a tree down to a min number of instances per leaf) which is very good for our case. I did had some issues in our code that indicated me that somehow the LOD was computed only once for the entire cluster, which luckily is not the case.

I may come later with some tests for our cases. Probably removing and adding nodes in a hierarchy of many nodes it will be a bottleneck in the future.

Kind Regards,

Adrian

×
×
  • Create New...