glTF in Unity optimization - 0. Introduction
I see some optimization potentials for my glTF loading library glTFast for Unity. I decided to document the process and results in a mini-series:
- 0. Introduction
- 1. Buffers, Accessors and Primitives
- 2. Avoid Tangents and Normals Calculation
- 3. Parallel Jobs
- 4. New Mesh API - The Failed Attempt
- 5. New Mesh API - The Refactor
- 6. Asynchronous Programming
- 7. Performance Tests
- 8. Asynchronous Scene Instantiation
History of glTFast
glTF, in a nutshell, is an open 3D asset format that is striving to become a standard, the "Jpeg of 3D".
Early 2018 I was investigating in possibilities to load glTF files at run-time in a Unity project. Back then the only option was UnityGLTF, the official importer/exporter from the Khronos Group.
While on the surface it seems to work nicely pretty much out of the box I noticed that it's not very fast 😦
First of all, the WebGL build's JS/WebAssembly file was big, so starting the project took long. Loading glTF files also wasn't blazing fast.
During investigation the thing that stood out to me was UnityGLTF is using Newtonsoft's Json.NET library for parsing. From previous projects I knew that feature-wise it's a great, flexible library, but it takes its toll by pulling in a lot of dependencies which eventually bloat the build by some mega bytes.
I also knew Unity has its own JSON parser, which is less powerful but:
- It's fast
- It does not use a lot of memory
- It's already built-in (or nowadays: a package)
So in ~May 2018 I started tinkering with my own solution based on that parser. Initial results were promising. This is a screenshot (made in May 2018) of WebGL builds of UnityGLTF and glTFast loading the same asset.
Admitted, this is an old screenshot and not a meaningful, significantly measured test result. The test wasn't repeated/averaged and I cannot reconstruct the exact setting. But still, loading 56% quicker seems pretty good to me.
Over time I kept on improving:
- Speed up due to threading via C# Job system
- Using custom shaders that can consume glTF textures without re-processing
- Improved standard feature compliance with official sample files
- Added support for official extensions like Draco or mesh quantization
Future
Topics I want to tackle in the future that may be worth a post
- Treating Buffers and Accessors correctly
- Parallel jobs
- Unity Math and Burst
- New Mesh API
- Speed up tangent calculations
- DOTS
- Coroutines vs. async
- Custom DownloadHandler
- Streaming support
- Draw call reduction due to Material batching (Property blocks)
- Comparisons with recent alternatives and benchmarks.
Stay tuned!
Follow me on twitter or subscribe the feed to not miss updates on this topic.
If you liked this read, feel free to