Basis Universal Texture Format Introduction
TL;DR: Basis Universal is the image format for cross platform/API usage in graphics/GPU contexts.
It is also super useful for creating a platform/API/framework agnostic 3D content format. For textures, it is the missing piece in that puzzle.
Intro
It's pretty straightforward to put an image on a website. Save it as a Jpeg or PNG, add an <img>
tag to your HTML and it'll work on all browsers across all platforms.
Some people (me included) also want to do this in graphics applications (e.g. 2D/3D game) that run on GPUs. To do this, you need the texture in a special format, the graphics API and GPU can work with.
The objectives are:
- Images/Textures to load as fast as possible
- Small file/download/storage size
- Small runtime load overhead
- Straightforward content creation pipeline
GPU texture formats
GPUs can handle only certain types of texture data.
Apart from uncompressed formats (bitmaps; huge in size) there are a couple of compressed formats, also called GPU-friendly formats. They have a lossy compression and thus are small in size (~8 times smaller than bitmaps), yet GPU texture units are able to access them very efficiently (random access). Examples are DXT1/BC1[1], PVRTC[2], ETC2[3] or ASTC[4].
Unfortunately there isn't a single compressed GPU texture format that is supported throughout all GPUs and graphic APIs.
If you want to provide a broad range of target devices/platforms with their respective ideal format choice, you have to encode every texture into a bunch of different formats.
To make matters worse, I'm not aware of a single encoding tool that supports all or most formats, so you'll also need to install a handful of encoders.
Note: If you're using a game engine or graphics framework (like Unity3D), chances are it assists you with automatic conversions by abstracting them away...maybe not always in the most efficient way.
Decoding / Encoding at runtime
If your GPU does not support the format you have directly, you have the option to convert it at runtime. For example decode a PNG file into an uncompressed texture. The smaller PNG gives you a decent download size, but it has two downsides:
- Decoding is slow
- The decompressed bitmap will use a lot of video RAM at the end
The second point could be fixed if you encode the bitmap into a supported GPU-friendly format after decoding, but that would make the loading process even slower.
Enter Basis Universal and Transcoding
Basis Universal is a supercompressed intermediate texture format. BasisU files can be transcoded into GPU friendly formats at runtime.
The transcoding is quite fast and it does not create an interim bitmap.
For technical details, jump right to the repository/code[5] or read this related paper[6].
So BasisU fulfills all requirements
- Small file sizes for storage/download (compression)
- Fast transcoding
- Low video RAM usage (due to GPU-friendly formats)
Seriously, these benchmarks speak for themselves.
And on top of that:
- It's open source! (Apache License 2.0)
- The creators of it (Binomial[7]) are working with the Khronos group on the specification to make it an industry standard.
- It is supported by Google[8]
Basis Universal for Unity
When BasisU was released, I got excited and created a small wrapper/library so you can load it in the Unity3D game engine. You can find it on my GitHub:
https://github.com/atteneder/BasisUniversalUnity
Let me know what you think. I'll try to prevent it from going to the graveyard of side projects before it is usable.
I think that if BasisU gains the traction it has the potential to, eventually Unity will support it by default and maybe even use it for texture/asset transmission internally.
Generic 3D assets: glTF
As mentioned above, efficient texture transmission is key for having a universal 3D asset format.
We're talking about a "last mile" format, with the intention to deliver final content to the end user. Not a format to deliver assets between digital content creation applications.
The Khronos group made an effort to give us a format like this called glTF[9].
It is getting some attention lately. For example you can load it in Google's model-viewer web component and view it directly in 3D or augmented reality. Also facebook does support posting 3D content via glTF-binary[10].
At the moment textures in glTF are encoded in either PNG or Jpeg, which suck, as I explained before.
But Khronos is working on including BasisU in glTF[11], so the future for this format is bright, once the industry starts to adopt to it.
Oh yeah, I've also created this Unity glTF loading library called glTFast (because it's really fast). I'll try to get BasisU support in there as well. Also on my GitHub:
https://github.com/atteneder/glTFast
Final notes
To stay up to date on this topic I recommend to follow the following sources:
The glTF draft pull request regarding compressed texture formats.
Stephanie Hurlburt and Richard Geldreich, the people behind Binomial.
Richard also has a blog, where (amongst other things) he gives lots of insight into texture encoding details.
Star/follow the repositories of Basis Universal and glTF on GitHub.
If you liked this read, feel free to
https://www.imgtec.com/blog/pvrtc-the-most-efficient-texture-compression-standard-for-the-mobile-graphics-world/ ↩︎
https://en.wikipedia.org/wiki/Ericsson_Texture_Compression ↩︎
https://www.khronos.org/opengl/wiki/ASTC_Texture_Compression ↩︎
https://opensource.googleblog.com/2019/05/google-and-binomial-partner-to-open.html ↩︎
https://developers.facebook.com/docs/sharing/3d-posts/glb-tutorials/ ↩︎
https://www.khronos.org/blog/google-and-binomial-contribute-basis-universal-texture-format-to-khronos-gltf-3d-transmission-open-standard ↩︎