In order to serve GLTFs more efficiently using less CPU in runtime, they are converted by a background process from GLTFs to Unity Asset Bundles when a scene is deployed.
Currently, the Asset Bundles Converter code lives inside unity-renderer repo. Eventually we'll probably move it to its own repo.
The most relevant classes are:
- unity-renderer/Assets/ABConverter/Core.cs
- Downloads assets (and their dependencies) and flags them to be converted
- Converts downloaded assets to AB
- Triggers visual tests check after conversion
- unity-renderer/Assets/ABConverter/SceneClient.cs
- Entrypoint for converting scenes and their assets
- Uses the Core to trigger different type of conversions (Scene, Asset)
- Has the batch-mode entrypoint for converting a scene (
ExportSceneToAssetBundles()
)
- unity-renderer/Assets/ABConverter/WearablesCollectionClient.cs
- Entrypoint for converting wearable collections
- Uses the Core to trigger wearable and wearable collection conversions
- Target assets are downloaded into a folder for each asset (folder names are the asset hashes), Unity editor imports each asset (constructs materials for the GLTFs, etc.) and those folders are flagged for Asset Bundle conversion (
Core.DumpAssets()
) - A depmap json file is created inside each folder and then the flagged folders are all converted in one pass (
Core.BuildAssetBundles()
) (In a previous version of the converter we generated the depmaps as an external json file "assethash.depmap", we don't do this anymore but the depmaps loading system has a fallback to keep working with those old depmaps for old asset bundles) - Target assets are visually-tested against their asset bundle version (
VisualTests.TestConvertedAssets()
)- GLTF assets are instantiated in the current scene (disabled)
- Each GLTF GameObject is enabled at a time and a snapshot is taken for each asset
- Asset Bundle assets are instantiated in the current scene (disabled)
- Each Asset Bundle GameObject is enabled at a time, taking a snapshot for each asset and generating the "diff" image for the assets that don't look exactly the same in both asset versions. When that happens, the failed Asset Bundle file is deleted from the output folder, so it's not uploaded to the S3.
- The final asset bundles will end up in the output folder at
unity-renderer/unity-renderer/AssetBundles/
0 = SUCCESS
1 = UNDEFINED
2 = SCENE_LIST_NULL
3 = ASSET_BUNDLE_BUILD_FAIL
4 = SOME_ASSET_BUNDLES_SKIPPED
For dumping/converting assets locally we use our Decentralanad →Asset Bundle Builder menu items.
Those menu items can be edited at [Assets/ABConverter/AssetBundleMenuItems.cs](https://github.com/decentraland/unity-renderer/blob/master/unity-renderer/Assets/ABConverter/AssetBundleMenuItems.cs)
Another option is to call the converter locally from the terminal in headless mode as it’s done in the converter service e.g. /Applications/Unity/Hub/Editor/2020.3.0f1/Unity.app/Contents/MacOS/Unity -batchmode -projectPath "/Users/pravus/git/unity-renderer/unity-renderer" -batchmode -executeMethod DCL.ABConverter.SceneClient.ExportSceneToAssetBundles -sceneCid "QmXMzPLZNx5EHiYi3tK9MT5g9HqjAqgyAoZUu2LfAXJcSM" -output "/Users/pravus/git/unity-renderer/unity-renderer/AssetBundles"
Normally for scene-related dumping we need the scene id and asset hashes, this can be found by checking the scene mappings json, for example (coords -17, -122): [https://peer.decentraland.org/content/entities/scene/?pointer=-17,-122](https://peer.decentraland.org/content/entities/scene/?pointer=-17,-122)
Since there are LOTS of wearable collections, right now the only way to dump them manually is by updating the initialCollectionIndex
and lastCollectionIndex
variables inside WearablesCollectionClient.DumpAllNonBodyshapeWearables()
The best way to test the ABs conversion went fine is the following sequence:
- Check out the visual test results for each asset at
unity-renderer/unity-renderer/TestResources/VisualTests/CurrentTestImages/
- start a webserver at the asset bundles output folder at port
1338
for example withnpx serve --cors -l 1338
(other options could behttp-server -p 1338
orpython -m SimpleHTTPServer 1338
), to serve those newly created asset bundles - Go back to Unity Editor and select the DebugConfig GameObject in the InitialScene unity scene. Check the "Use Custom Content Server" toggle and make sure the custom content server url is
http://localhost:1338/
- Clear the editor's Asset Bundles cache by going to the menu item at Decentraland → Clear Asset Bundles Cache
- Enter the world running the explorer from the editor, and make sure the pertinent loaded meshes name doesn't say "GLTF:HASH" that way you can make sure it's an asset bundle that's being loaded (the parent of the mesh GameObject may say GLTFShape but that's fine since that's the SDK component name)
Specific optimizers for explorer assets - RFC
In runtime the GLTF/AssetBundle loading pipeline goes through the RendereableAssetLoadHelper.Load()
from there you can follow the loading flow (RendereableAssetLoadHelper.LoadAssetBundle()
and RendereableAssetLoadHelper.LoadGltf()
).