Basis Universal Texture Support
Last year Google and Binomial LLC partnered to release the Basic Universal library as open-source. This library is the successor to Crunch. Both these libraries are like OGG compression for textures. They compress data very well into small file sizes, but once loaded the data takes the same space in memory as it normally does. The benefit is that it can reduce the size of your game files. Crunch only supports DXT compression, but the newer Basis library supports modern compression formats like BC5, which gives artifact-free compressed normal maps, and BC7, which uses the same amount of space as DXT5 textures but pretty much eliminates blocky DXT artifacts on color images.
I've added a Basis plugin to the Plugin SDK on Github so you can now load and save .basis texture files in the Leadwerks Game Engine 5 beta. Testing with a large 4096x2048 image in a variety of formats, here are my results.
- TGA (uncompressed): 24 MB
- PNG (lossless compression): 6.7 MB
- DDS (DXT1 compression): 5.33 MB
- Zipped DDS: 2.84 MB
- JPEG: 1.53 MB
- BASIS: 573 KB
The zipped DXT option is the most like what you are using now in Leadwerks Game Engine 4. Since the overwhelming majority of your game size comes from texture files, we can extrapolate that Basis textures can reduce your game's data size to as little as 20% what it is now.
With all the new image IO features, I wanted to write a script to convert texture files out of the Leadwerks 4 .tex file format and into something more transparent. If you drop the script below into the "Scripts/Start" folder it will automatically detect and convert .tex files into .dds:
function BatchConvertTextures(path, in_ext, out_ext, recursive) local dir = LoadDir(path) for n = 1, #dir do local ftype = FileType(path.."/"..dir[n]) if ftype == 1 then if ExtractExt(dir[n]) == in_ext then local savefile = path.."/"..StripExt(dir[n]).."."..out_ext if FileTime(path.."/"..dir[n]) > FileTime(savefile) then local pixmap = LoadPixmap(path.."/"..dir[n]) if pixmap ~= nil then pixmap:Save(savefile) end end end elseif ftype == 2 and recursive == true then BatchConvertTextures(path.."/"..dir[n], in_ext, out_ext, true) end end end BatchConvertTextures(".", "tex", "dds", true)
Here are my freightyard materials, out of the opaque .tex format and back into something I can easily view in Windows Explorer:
These files are all using the original raw pixels as the .tex files, which internally are very similar to DDS. In order to convert them to .basis format, we need to get them into RGBA format, which means we need a DXT decompression routine. I found one and quickly integrated it, then revised my script to convert the loaded pixmaps to uncompressed RGBA format and save as PNG files.
--Make sure FreeImage plugin is loaded if Plugin_FITextureLoader == nil then Plugin_FITextureLoader = LoadPlugin("Plugins/FITextureLoader.dll") end function BatchConvertTextures(path, in_ext, out_ext, recursive, format) local dir = LoadDir(path) for n = 1, #dir do local ftype = FileType(path.."/"..dir[n]) if ftype == 1 then if ExtractExt(dir[n]) == in_ext then local savefile = path.."/"..StripExt(dir[n]).."."..out_ext if FileTime(path.."/"..dir[n]) > FileTime(savefile) then --Load pixmap local pixmap = LoadPixmap(path.."/"..dir[n]) --Convert to desired format, if specified if format ~= nil then if pixmap ~= nil then if pixmap.format ~= format then pixmap = pixmap:Convert(format) end end end --Save if pixmap ~= nil then pixmap:Save(savefile) end end end elseif ftype == 2 and recursive == true then BatchConvertTextures(path.."/"..dir[n], in_ext, out_ext, true) end end end BatchConvertTextures("Materials/Freightyard", "tex", "png", true, TEXTURE_RGBA)
Cool! Now I have all my .tex files back out as PNGs I can open and edit in any paint program. If you have .tex files that you have lost the source images for, there is now a way to convert them back.
Now I am going to try converting this folder of .tex files into super-compressed .basis files. First I will add a line of code to make sure the Basis plugin has been loaded:
--Make sure Basis plugin is loaded if Plugin_Basis == nil then Plugin_Basis = LoadPlugin("Plugins/Basis.dll") end
And then I can simply change the save file extension to "basis" and it should work:
BatchConvertTextures("Materials/Freightyard", "tex", "basis", true, TEXTURE_RGBA)
And here it is! Notice the file size of the selected image.
If you want to view basis textures in Windows explorer there is a handy-dandy thumbnail previewer available.
Now let's see what the final file sizes are for this texture set.
- Uncompressed TEX files (DXT only): 35.2 MB
- Zipped TEX files: 25.8 MB
- BASIS: 7.87 MB ?
When converted to Basis files the same textures take just 30% the size of the zipped package, and 22% the size of the extracted TEX files. That makes Basis Universal definitely worth using!
- 3
4 Comments
Recommended Comments