directory
- introduce
KHR_mesh_quantization
andEXT_meshopt_compression
- Usage
- Performance (compression, loading, parsing)
- Available (scenario, scope)
- disadvantages
- Guess what future improvements might be
- conclusion
introduce
There are many other compression extensions, such as KHR_mesh_quantization and EXT_meshopt_compression, because GLTFLoader is adapted to small programs
KHR_mesh_quantization
Quantization (vectozation) refers to the movement of data represented by floating point numbers to integer data, which facilitates compression and storage, but loses accuracy. Similar methods have been seen in TFJS model before. GLTF grid data are stored using floating point numbers. A single precision floating point number takes up 4bytes of 32 bits, a vertex has 3 numbers of 12bytes, texture coordinates are 8bytes, normal lines are 12bytes, tangent space is 16bytes. The amount of information attached to a vertex requires 48 bytes, so use this extension, use SHORT to hold vertex coordinates, texture coordinates 4 bytes, use BYTE to store normal coordinates 4 bytes, tangent space 4 bytes (in order not to break the standard multiple of 4 bytes), There are 20 bytes in total, so the vectorized grid can be compressed by about 58.4%.
EXT_meshopt_compression
The extension on R122 enters three. Its compressed pipeline is as follows. The fifth step is the vectorization above.
KHR_DRACO_MESH_COMPRESSION
Github.com/google/drac… To learn more, read big Boss’s analysis. The default compression parameters are more radical than those above
Due to the support of WASM and JS volume and worker number limit issues, small programs are not appropriate. Js version decoder is larger than three
usage
KHR_mesh_quantization and EXT_meshopt_compression can use the same tool, GLTFpack
> npm i -g gltfpack
#The GLTFPack command line tool is a C project built out of WASM, and it looks like more WASM projects will be produced in the future
#An optimized version of KHR's Basis Trancoder is compiled to WASM using AssemblyScript
#Into KHR_mesh_quantization
> gltfpack -i model.glb -o out.glb
#To EXT_meshopt_compression, just add -cc
> gltfpack -i model.glb -o out.glb -cc
Copy the code
The advantage of using GlTFPack is that the vectoquantization parameters can be adjusted (requiring a Meshopt extension). For example, if the normals need to be more precise, change -vn, or read GlTFPack -h
KHR_DRACO_MESH_COMPRESSION can be used with GLTF-Pipeline
> npm i -g gltf-pipeline
> gltf-pipeline -i model.glb -o out.glb -d
Copy the code
The vectorization parameters of Draco can also be adjusted
Performance (compression, loading, parsing)
Then it is necessary to compare the performance of the compression grid
The model used is from GLtF-sample-Models
GLB is ReciprocatingSaw and Draco is ReciprocatingSaw. In fact, the reason is simple, Draco default compression parameter is much more radical than meshQuan, but BrainStem. GLB meshOpt with animation is the best. Waterbottle. GLB is not too far off because the number of vertices is limited and the texture takes up a lot of the main volume.
Then, since the default parameters are different, Draco has an advantage in comparison, so recompare the other parameters that require the same compression, this time only need to compare BrainStem and ReciprocatingSaw, and align the glTFpack parameter to Draco here
> gltfpack -i model.glb -o out.glb -vp 11 -vt 10
> gltfpack -i model.glb -o out.glb -vp 11 -vt 10 -cc
Copy the code
You can see that even if you change the parameters, the MeshQuan size does not change, because it has become standard, the vectozation parameters are fixed and cannot be changed, but the MeshOpt is slightly improved.
Decoder to load
Use a compression scheme, in addition to the need to compare the compression size, also have to compare the loading degree of decoder (Web, small programs and other environment), DracoLoader more than ten KB has not been counted
It is worth noting that MeshOpt WASM comes in two versions: a base version and a SIMD version
However, the official asm version is not provided, so you need to manually convert it through Binaryen/Wasm2js, or use meshopt_decoder.asm.module.js that I converted
At the decoder level it feels like a MeshOpt victory
Analytical time comparison
The model used here is compressed by default parameters, the power mode is high performance, and the CPU is always at the highest frequency. Five attempts were made to average all wASM versions. Where MeshOpt is SIMD version, Chrome 88
If you consider the loading time of decoder, you need to look at the first loading. Of the three extensions, only Darco will be affected, because only Draco needs to download WASM from the network to load GLTF for the first time. MeshOpt is a serialized string that can be unpacked without a network request.
Parse times for ASM releases are compared in the usability section
Comparison before and after compression
According to the principle in addition to the performance of the above indicators, but also to compare the compression of whether there is a problem, but this is not easy to index, or depends on the designer compromise, but for intuitive comparison, so I write a compressed model diff tool
There are three contrast modes and wireframe contrast used online.
Available (scenario, scope)
The available scenarios depend on how hard and large the Decoder is to load
As you can see, Draco is a bit of a pain on apet. MeshQuan doesn’t need a decoder so it’s the most usable. MeshOpt only needs to use asm version to be ios compatible with apet.
Therefore, if you need to be compatible with small program platforms, Draco is not suitable, of course, it can also be used to load the corresponding model for the platform, but the model effect needs to be fine-tuned separately for the platform, or the whole platform unified model has higher maintainability.
So this is a separate update to the decode performance of MeshOpt ASM
But there was something strange: the first parsing was very time-consuming, but the third was close to uncompressed performance, and the fifth was close to WASM performance. Why? Does it indicate a potential optimization approach?
Let’s take a look at Firefox, the first browser to support ASM. Is there a similar situation?
It seems that Firefox performs JS much better than Chrome in this case, but wasm does not produce better results, but there is a similar pattern. Does this mean that the decoder needs a warm-up, telling the browser that the decode code needs special optimization?
So this is done by loading a 1.21 KB triangle-Meshopt. GLB, 5 times, and then loading the test model, recording the data
GLB, only 3 vertices, execute 5 times also 15, magnitude did not go up. Is WebAssembly required from Web 3D? Find the answer
Because Chrome’s V8 engine supports JIT: just-in-time compilation, THE performance of JS programs is close to that of WASM (for Web 3D programs, the performance hotspot logic is executed multiple times in the main loop). V8, on the other hand, will determine the hot code after multiple executions and optimize it to bytecode; Then, starting with the next execution, execute the bytecode directly.)
The first load time of Asm under Firefox is 1.5 to 2.3 times that of uncompressed asm under Chrome is 3.08 to 4.4 times that of uncompressed ASM
Of course, because it is only wechat small program IOS, the IPhone CPU itself is better, so it can be accepted, if you can find the warm up method, the first load time is equal to the fifth time is better.
disadvantages
Vectozation is, after all, a lossy compression method that loses precision, but as KHR_mesh_quantization introduces, it is a compromise of precision and size
Vertex attributes are usually stored using FLOAT component type. However, this can result in excess precision and increased memory consumption and transmission size, as well as reduced rendering performance.
The disadvantage of KHR_mesh_quantization is that the vectozation parameters are fixed and cannot be modified. The advantage of KHR_mesh_quantization is that no additional decoder is required, while EXT_meshopt_compression is an upgrade that allows customization of vectozation parameters, such as increased capacity when normal accuracy is required
KHR_draco_mesh_compression, one of the better known extensions, has the highest compression ratio for the pure vertex model in this evaluation, but its decoder size and decode performance are not outstanding by comparison.
KHR_mesh_quantization and EXT_meshopt_compression are fixed conversions. For example, if the model itself is small in size and the range of floating-point numbers used is small, the accuracy loss will be greater. The solution is to increase the storage capacity. Enlarge the model so that the distance between the vertices is larger and smaller when used. The text description may not be as intuitive as the GIF.
When the model is magnified 10 times, the color changes are ignored when the model version is not the same
The difference between the middle bags is negligible, but there is a texture shift underneath.
Guess what future improvements might be
It can be inferred that the next step can be optimized due to the error problem caused by the above fixed vectozation that the model is in the range of small floating point numbers: dynamic vectozation + offset, visual inspection can further provide accuracy and compression ratio, but the decoder will increase in time.
For example, the maximum value of boundingbox.xyz of the model is mapped to 0-1 and then to integer/custom XByte. Of course, the same can be done for the sub-mesh of the model, and the xyz can be maintained separately, etc.
Of course it’s just an idea, the purpose of this article is to find a good extension MeshOpt, but it’s also an exploratory process to test and verify what’s introduced into the project usability with some rigor.
conclusion
MeshOpt cowhide