Model optimization study
!!!!!!!!!!!!!!!!! Article to be reformated with the new site css. !!!!!!!!!!!!!!!!!
-
Barbarian model: Optimization study
-
The Model
The model comes in a MS3D format with TGA
textures. It has a two LOD definition: low poly and high poly.
It has diffuse, opacity, normal and specular maps.
Here is the file list, size and some informations:
-
barbarian_high.ms3d 3058 ko
-
barbarian_low.ms3d 2332 ko
-
barbarian_d.tga 14126 ko (2048 x 2048)
-
barbarian_a.tga 4097 ko (2048 x 2048)
-
barbarian_n.tga 14478 ko (2048 x 2048)
-
barbarian_s.tga 13974 ko (2048 x 2048)
-
armor_d.tga 16155 ko (2048 x 2048)
-
armor_a.tga 12289 ko (2048 x 2048)
-
armor_n.tga 15707 ko (2048 x 2048)
-
armor_s.tga 15764 ko (2048 x 2048)
-
Memory optimization
If you load the low / high poly models and save it
straight away without any optimizations enabled, you'll get a JMF file
of size 7629 ko / 7886 ko with the build 1.1.3-28-08-2010 and
prior. If you use the build released this september, which contains
various internal memory structures optimizations, you'll get an
approximative 2 mo reduction: 5334 ko / 5594 ko !
You can expect that the model takes at least this much of memory inside
the JVM, non compressed JMF files are close to memory dump (java object
serialization).
This 2 mo improvement is great, but still 5 mo usage inside the JVM is
big. We'll see how this can be improved.
For those of you reading this article, some of you may have read this Archived forum (retired).
We'll see the results of using the Optimizer introduced there.
With the build 1.1.3-28-08-2010 and prior, you'll get the same memory
usage than the non optimized model, meaning 7629 ko / 7886 ko.
Using the build release this september, you'll benefit of some new
memory optimizations that will reduce the 5334 ko / 5594 ko of the
orignal model to just 2462 ko / 2722 ko !!
You've now saved an additional 3 mo (5 mo in total). You can still save
a little more memory by using the new 'destructive' animation
compression. This optimization will detect unecessary animation keys
that could be interpolated very closely (closely is not exactly hence
the name 'destructive'). Default settings are not very destructive,
instead of using floating point equality, it will use compare the float
value differences by a small equsilon value to get rid-off of
interpolation foating point imprecision of the exporter of the format
conversion.
Using the default setup, which results to a not so destructive
optimization as you'll not see any differences, the model is sized down
of 20%: 1981 ko / 2240 ko. If you want to reduce even more the
animation, you can choose an heavy destructive which currently results
to some slight skeleton vibration, you can size it down to 1676 ko /
1417 ko (and more with higher destructive
setup).
In summary, you've seen how important is to use the engine optimizer.
You can save a huge amount of memory, this sill allow to load more
models, to fit in smaller hardware, or just to use less memory that
could be used by the OS or other applications.
Note: All optimizations presented here applies mostly to
skinning animation info. Geometry (vertex) data has already been hugely
optimized before, and takes 700ko for the high poly models (all the
remaining size are for the bigger part skinning animation info).
-
File-System storage
All size show in the previous paragraph are
non compressed JMF model, just stay close to that actual JVM usage.
Now will see the same values with a model compressed using LZMA, for each of the two
builds of the engine.
Using this compressing, the 7629 ko / 7886 ko are compressed to
respectively 701 ko / 816 ko. With the lastest optimized build, 1981
ko / 2240 ko are compressed to 574 ko / 690 ko.
We'll also, in a smaller ratio, save some space with the compressed
format.
-
Texture optimization
The high definition textures (2048 x 2048)
takes just too much memory: 104 mo !
We'll see how to using the tool provide with the engine. It could be
possible to do the same thing using some external tool such as ATI The Compressonator, but we'll
stick here with the all-in-one optimizer of the engine. It can be easily
used in a batch convert, in a multiplatform ecosystem.
So let's use the setTextureWriterOptions
introduced in Archived forum (retired). We'll use here dds format, maximum texture size
of 1024 x 1024 and merging of diffuse and opacity textures.
After running this tool, you'll getthose textures (to be compared to the
tga listed on start of this article):
-
armor_d_da.dds 1024 ko (DXT5)
-
armor_n.dds 1024 ko (ATI2/RGTC2)
-
armor_s.dds 512 ko (DXT1)
-
barbarian_d_da.dds 1024 ko (DXT5)
-
barbarian_n.dds 1024 ko (ATI2/RGTC2)
-
barbarian_s.dds 512 ko (DXT1)
The 104 mo TGA has been reduce to a 5 mo,
which is a much more acceptable size.
Using 512x512 textures, the size could be reduce by 4 to a small 1.25mo.
Another interesting texture format is TEX,
which has been specifically designed for the engine. This format is
derived of DDS, and support similar features: non-compressed
(byte/float) and compressed (S3TC(DXTx) / 3Dc / RGTC / LATC) texture,
with mipmap and cubemap support.
In addition, TEX format support an optional file compression (using
LZMA) and optional encryption for protection. TEX format is a binary
format independent of the runtime class of the engine. Its design is
finished, and forward and backward compatibility is guaranteed.
Let's see the result for this file format using both compression and
encryption:
-
armor_d_da.tex 412 ko (DXT5)
-
armor_n.tex 966 ko (ATI2/RGTC2)
-
armor_s.tex 368 ko (DXT1)
-
barbarian_d_da.tex 332 ko (DXT5)
-
barbarian_n.tex 898 ko (ATI2/RGTC2)
-
barbarian_s.tex 293 ko (DXT1)
This results to 3.77 mo (25% smaller for this set of
texture).
For 512x512 textures, the size is reduced to 845 ko.
-
Loading speed optimizations
Previous paragraph was oriented around memory
improvements. We'll see here the amount of time you'll saved in the
different steps.
I've runned a benchmark to measure the time to load the different model
and texture format (times after JVM and hard-drive warm-up). MS3D
and TGA are the input files listed at start and are exported in
JMF/DDS/TEX.
Here are the results:
-
MS3D + Optimization 2.80 s
-
JMF (Optimized) 0.12 s
-
JMF (LZMA+Encryption+Optimized) 0.39 s
and for the textures:
-
TGA 2048 6.04 s
-
DDS 512 0.07 s
-
DDS 1024 0.14 s
-
TEX 512 (LZMA+Encryption) 0.48 s
-
TEX 1024 (LZMA+Encryption) 1.67 s
JMF loads notably faster than MS3D, even with
lzma and encryption enabled.
TEX are slower to load than DDS due to the additional lzma compression
and encryption. Without that, they loads at the same speed than DDS.
Both DDS/TEX loads notably faster than original TGA files.
-
Temporary memory loading
In addition to loading speed, it may also be
interesting to have some indication to memory and garbage collection
usage.
Each test are runned separatly with a new VM without warm-up. Garbage
collection is requested before running the test code and memory is in
this state: total memory is 15.5 mo (Runtime.totalMemory()) and
used memory is 0.16 mo (Runtime.totalMemory() -
Runtime.freeMemory()).
For each tests, measurements are:
1) Memory used before GC
2) Memory used after GC
3) the new total memory used by the JVM. This value may be
different to the initial value if the VM has expanded (occures when the
heap has been fully allocated).
MS3D and TGA are the input files listed at start and are exported in
JMF/DDS/TEX.
Here are the result for each tests: 1) /
2) / 3)
-
MS3D + Optimization 22.37 / 0.49 / 28.29
-
JMF (Optimized) 4.38 / 0.38 / 15.56
-
JMF (LZMA+Encryption+Optimized) 5.32 / 0.43 / 15.56
-
TGA 2048 48.22 / 0.21 / 62.47
-
DDS 512 1.20 / 0.21 / 15.56
-
DDS 1024 5.08 / 0.71 / 15.56
-
TEX 512 (LZMA+Encryption) 1.29 / 0.29 / 15.56
-
TEX 1024 (LZMA+Encryption) 5.93 / 0.29 / 15.56
As expected MS3D (and tga) uses a high amount
of temporary memory, which result to resize of the JVM heap in the test
conditions.
It is probably not a big issue in nowadays computer, but on mobiles
devices (or on applet with limited JVM heap) this can be the cause some
serious issues (out of memory).
