Way back in 2014, PlayCanvas was the first WebGL Engine to integrate PBR (Physically Based Rendering). To mark the event, we built the Star-Lord tech demo:
In the intervening 6 or so years, PlayCanvas has moved on dramatically. So we decided to leverage all of the latest engine features and republish it.
The most significant improvements are related to load time. Let’s start out by comparing some key stats:
|Preload Transfer (MB)
|Total Transfer (MB)
|Total Resources (MB)
|Load Time (s) *
* Cache disabled on 100Gbps connection
Those are some pretty significant wins! So what are the differences between the two builds of the demo? Let’s step through them one by one.
Convert JSON Meshes to GLB
In October 2020, PlayCanvas officially switched from JSON to glTF 2.0 (GLB) for storing all model and animation data. While gzipped GLB is reasonably similar in size to gzipped JSON, it is up to an order of magnitude faster to parse a GLB file once it has been downloaded. Plus, a GLB file occupies less system memory than the equivalent JSON file. Converting all of the assets from JSON to GLB is a simple process. First, flip the project setting ‘Convert to GLB’ in the ‘Asset Tasks’ group to true:
Now, simply reupload all FBX files and a .glb asset will be generated rather than a .json asset. The last step is to use the Replace command in the right-click context menu to replace the .json asset with the .glb asset (plus any materials as well).
You can then delete the old JSON asset (plus any unreferenced related materials).
Basis Compress Textures
Last month, we announced the integration of Basis texture compression into the Editor. Star-Lord was originally configured to use DXT, PVR and ETC compressed textures. A download size comparison is as follows:
|Download Size (MB)
This explains much of the download savings in the updated version.
Fortunately, applying Basis compression to the app’s textures is literally a two-click operation:
Prefilter Cubemaps in the Editor
When PBR first arrived in PlayCanvas, the Editor could not prefilter cubemaps. This conversion had to be performed externally with RGBM format cubemap faces being added to the Editor:
Each cubemap had 6 mip levels with 6 faces for each level. And with 5 different cubemaps, that meant 180 of the demo’s 220 HTTP requests were for these PNGs!
These days, the Editor makes is super easy to import 6 HDR cubemap faces, build a cubemap and then prefilter it.
So instead of loading 180 PNGs, the demo now loads just 5 DDS files. Much faster. 🚀
Asynchronously Load Assets
To achieve an optimal load time, it is important to only load what is required to make your app functional. It is arguable that music is not strictly a necessary precondition for your app to start. Therefore, the demo now asynchronously loads the mp3 asset that contains the music track and auto-plays it as soon as it is downloaded. It is 3.9MB which accounts for nearly 40% of the app’s payload! So be sure to carefully audit your app for assets that can be streamed instead of preloaded.
Read more about preloading and streaming of assets in the User Manual.