Azure / azure-remote-rendering

SDK and samples for Azure Remote Rendering
MIT License
106 stars 38 forks source link

[Question] Object count limitations/recommendations #56

Closed WikkidEdd closed 2 years ago

WikkidEdd commented 2 years ago

We just came across a model which isn't rendering very smoothly. The poly count isn't that high and will render on a standard instance, but we noticed that the CPU time is really high when rendering the model.

We noticed that it has a really high number of nodes/objects. I presume in this scenario if we switched to scene graph mode static or none it would yield better performance?

Is there any recommendation for the object count for scene graph mode dynamic?

Here is the conversion info


 "inputStatistics": {
        "numVertices": 4226885,
        "numFaces": 1960400,
        "numMaterials": 111,
        "numFacesSmallestMesh": 1,
        "numFacesBiggestMesh": 64881,
        "numNodes": 84909,
        "numMeshes": 29238,
        "numMeshUsagesInScene": 115952,
        "maxNodeDepth": 11,
        "numTextures": 0
    },
    "materialOverrides": {
        "numOverrides": 0,
        "numOverriddenMaterials": 0
    },
    "outputInfo": {
        "conversionToolVersion": "367c801e91005bd4ef4effdc4ff315a90e6d2dc2",
        "conversionHash": "1B7E19BD8A89C985"
    },
    "outputStatistics": {
        "numMeshPartsCreated": 115928,
        "numMeshPartsInstanced": 18978,
        "numMaterials": 119,
        "recenteringOffset": [
            0.0,
            0.0,
            0.0
        ],
        "boundingBox": {
            "min": [
                -12.228811264038086,
                -0.30000001192092898,
                -9.719191551208496
            ],
            "max": [
                39.85186004638672,
                3.946549654006958,
                6.004221916198731
            ]
        }
    },
    "inputFileSizes": {
        "sizeOfFilesDownloaded": 8284694212,
        "countOfFilesDownloaded": 122,
        "sizeOfFilesUsed": 136628812,
        "countOfFilesUsed": 1
    }```
FlorianBorn71 commented 2 years ago

Hi Edd, I assume indeed that the part count is the bottleneck here. There is no hard limit on that count, however, by default they are all treated as fully dynamic and thus CPU perf degrades linearly with the number. A much better conversion setting for models with large number of individual parts is to mark the scene graph as 'static'. See detailed information here:

Configure model conversion

...where 'static' rather means that objects inside the scene graph cannot be re-parented. But they can be transformed individually. If you don't need to distinguish the parts at all, then scene graph mode 'none' would even be more performant. But you should already see a significant speedup with the 'static' setting, assuming the limitations work for your use case.

'Static' is the best mode for most use cases, but unfortunately we cannot make it the default without introducing a breaking change for existing conversion settings.

WikkidEdd commented 2 years ago

ok thanks. We'll switch our conversion over to static by default. I can't imagine we'll ever want to reparent objects in the hierarchy.

What kind of object numbers have you had when running internal benchmarks? just so I can get a ballpark idea?

FlorianBorn71 commented 2 years ago

For the fully dynamic mode, there are multiple factors that matter. Most importantly, whether you also have physics for raycasts enabled. Also 'standard' vs. 'premium' SKU makes a difference. That said, usually ~100k objects is where you start seeing perf issues with a fully dynamic scene graph. With a static scene graph on the other hand, memory and loading time is the only limit. Note that all nodes have to be sent over to the client. The fully dynamic scene graph had been designed with use cases like explosion animations in mind, where all parts move simultaneously.

FlorianBorn71 commented 2 years ago

+1 for switching to static SG mode ;-)

FlorianBorn71 commented 2 years ago

Looking at your conversion info file, there is something unrelated I'd like to raise here. If you look at this section: "inputFileSizes": { "sizeOfFilesDownloaded": 8284694212, "countOfFilesDownloaded": 122, "sizeOfFilesUsed": 136628812, "countOfFilesUsed": 1

...you'll notice that only a small fraction of files is used (both number of files and total # bytes). Not a big deal, just a low hanging fruit to improve upload times a bit.

WikkidEdd commented 2 years ago

Ah, thanks for the heads up. I'd never paid attention to that section of the conversion info.

This is the crucial bit in the documentation that we missed :)

Only Blobs starting with this prefix will be downloaded to perform the conversion. Optional. If not provided, all Blobs from the container will be downloaded.

So every time we add a new file to our input container it will take longer and longer to download and convert.

We'll get it fixed up so every file ends up with it's own blob prefix so this doesn't happen

FlorianBorn71 commented 2 years ago

The conversion service emits a warning to the user when only a 'small' portion of the data size is used, where 'small' is based on a heuristic that depends on the overall size. So it's always good to pay attention to warnings returned by the conversion.