VRM Size¶
Since VRM is a GLB-based format, we know tha
exported VRM file size => glb file size
glb => json + binary
.
json is a text-based format. Generally it is less than 1MB.
.
Image
and Mesh
are two major parts in binary
.
Here we show an example of how to calculate the size for a model with 50k vertices and 50k triangles:
Image¶
Image
contains Texture
(referenced by Material) and Thumbnail
(in VRM Meta). Those images are stored as PNG(JPG) bytes.
In v0.56, a large texture (e.g. 4096x4096) in the model fails to export as a smaller size texture (e.g. set to 1024x1024 by Texture Importer Settings -> MaxSize). We have fixed this issue in v0.58
https://github.com/vrm-c/UniVRM/issues/502
Mesh¶
Mesh
contains index buffer and vertex buffer.
Index Buffer¶
Index buffer uses Int
array.
To calculate the required size for a model with 50k triangles:
50000 x 4(Int=4byte) x 3(three vertices in a triangle) => 0.6MB
It is possible to store index using
unsigned short
in GLTF. However, UniVRM does not support it due to the fact that the Max vertices number is 65536, which is unable to store 50k triangles or more in a model
Vertex Buffer¶
The size for a vertex along with its attributes is:
{
float3 Position; // 頂点位置 4(floatサイズ) x 3(xyz) => 12byte
float3 Normal; // 頂点法線 4(floatサイズ) x 3(xyz) => 12byte
float2 TEXCOORD_0; // 頂点UV 4(floatサイズ) x 2(xy) => 8byte
short4 JOINTS_0; // 頂点BoneIndex 2(shortサイズ) x 4(4boneまで) => 8byte
float4 WEIGHTS_0; // 頂点Weight 4(floatサイズ) x 4(4boneまで) => 16byte
}
.
Some models contain Vertex Color or Secondary UV (not supported), so the required size may vary
In UniVRM, Tangent(float4) can be calculated in Unity instead of being stored in GLTF. Given Vertex Normal and UV, Tangent can be obtained via
MIKK T Space
algorithm
The case for a model containing 50k vertices:
50000 x (12 + 12 + 8 + 8 + 16) => 2.8MB
Basic Size¶
As described above, the basic size for a model is Total Image Size + Index Buffer + Vertex Buffer
.The basic size for a model with 50k vertices and 50k triangles is 3.4MB + Total Image Size
.Next, we will introduce size calculation for BlendShape, which may cause total size explosion in some circumstances.
BlendShape (MorphTarget) Size¶
// ブレンドシェイプ頂点
{
float3 Position; // 頂点位置 4 x 3 => 12byte. 必須
float3 Normal; // 頂点法線 4 x 3 => 12byte. オプション
float3 Tangent; // 頂点Tangent 4 x 3 => 12byte. 記録しない
}
If 1 BlendShape is added, the size will be: 50000 x (12 + 12) => 1.2MB
If 20 BlendShapes are added, the size will be: 50000 x (12 + 12) x 20 => 24MB
If 60 BlendShapes are added, the size will be: 50000 x (12 + 12) x 60 => 72MB
…
大量のBlendShapeがある
We can infer that if the number of BlendShapes are scaled to the hundreds, the size will become incredibly big. Moreover, most of the models do not actually use BlendShape on every single vertex. Reserving the space for BlendShape data for each vertex results in huge size.
To resolve this issue, below we provide several methods that may help shrink the total size.
Options for BlendShape Size Reduction¶
In Export Dialog, there are several options related to BlendShape size optimization.
Export Option¶
To reduce BlendShape size, the first two, ReduceBlendshape
and ReduceBlendshapeClip
, are the safest ways (no errors). We are working on UseSparseAccessor
to resolve the importing issue for some of the VRM loaders (UniVRM loader is fine). OnlyBlendshapePosition
has importing errors if the model is made by UniVRM-0.53 or earlier versions.
ReduceBlendshape¶
BlendShapes that are not referenced by BlendShapeClips will not be exported. The file size can be reduced.
ReduceBlendshapeClip¶
BlendShapeClip belonging to Preset.Unknown will not be exported. Used in combination with ReduceBlendshape.
UseSparseAccessor¶
Uses Sparse Accessor feature in GLTF: only records BlendShape vertices with non-zero value.
If the model contains multiple BlendShapes, enabling this can help reduce the file size.
WIP: fix importing error if the model has Sparse Accessor in GLTF (UniVRM is fine)
// ブレンドシェイプ頂点
{
int Index; // 有効なブレンドシェイプの index => 4
float3 Position; // 頂点位置 4 x 3 => 12byte. 必須
float3 Normal; // 頂点法線 4 x 3 => 12byte. オプション
float3 Tangent; // 頂点Tangent 4 x 3 => 12byte. 記録しない
}
The number of valid BlendShape vertices x (12 + 12 + 4) => ?MB
.
OnlyBlendshapePosition¶
BlendShape’s Normal and Tangent will not be exported if this option is selected.
The file size can be reduced. Be aware that errors may occur during import if the export target is made by UniVRM-0.53 or earlier versions.
MeshUtility: Split Mesh with/without BlendShape¶
For instance, a model’s mesh contains 50k vertices. It has 10k (with BlendShape) on face and 40k (without BlendShape) on body.
Setting up one BlendShape only needs: 10000 x (12 + 12) => 0.24MB
Setting up one BlendShape needs:
50000 x (12 + 12) => 1.2MB
.
The runtime performance will benefit to this mesh splitting as well. The trade-off is that Draw call is likely increasing since the number of rendering meshes increases
Summary¶
If you got a gigantic size of VRM model from export, check out the model’s BlendShape and texture images first.