To allow more complex applications and scenes in your WebXR app, Wonderland Engine implements
various optimizations. Find a non-exhaustive list below:
Optimizations that target faster frame rendering.
Dual Quaternion Scene Graph
While conventional scene graphs are implemented using matrices, Wonderland Engine’s scene graph uses
Dual quaternions require only half the amount of memory of a 4x4 matrix and require less operations to
As dual quaternions only represent rotation and translation, we augment them with a separate scaling vector.
For skinning, dual quaternions are especially advantageous, as they preserve volume better than other methods.
With the scene graph, this integrates nicely.
Wonderland Engine joins meshes together at runtime to allow multiple meshes to be drawn with a single draw call.
As each mesh usually uses different materials, we have special shaders that are able to use a list of materials
to draw parts of the batch in different ways.
Textures need to be batched aswell. This process is called “texture atlassing”.
This optimization heavily reduces draw calls, as e.g. 512 draw calls can be merged into a single one as long as
they all share the same shader.
Using compressed GPU formats, the GPU storage can be used more efficiently. This way the same amount of GPU
memory can hold more textures and texture resolution in the scene can be higher.
As a WebAssembly 3D engine, Wonderland Engine has more control over memory usage and increased performance over
features like batching can hereby implemented way more efficiently.
SIMD instructions in WebAssembly allow processing multiple pioeces of
data in a single instruction. This can especially speed up vector math.
While WebAssembly SIMD is not yet generally supported in Browsers
yet (most require setting a flag to enable support), Wonderland Engine is ready for it.
Data Oriented Design
Wonderland Engine’s scene graph and component system, awell as other parts of the code base, are designed through
Data Oriented Design. DOD is a way to write code such that data
is processed more efficiently by the CPU by improving cache usage and helping predicitive code execution.
Optimizations that target faster loading.
Binary scene format
As parsing text (e.g. from gltf or obj files) into binary for WebGL is already done in the editor,
the data is passed to the runtime in a binary format directly.
This binary data is layed out in a way such that minimal effort is required by the runtime to use it for
It also allows us to do Quantization on
e.g. the mesh data: some mesh properties can be stored with less bits per vertex, if their value range is known.
Basis Universal image compression
Compressed Texture format support is different per device. With Basis Universal, we can
compress images to a single format that can then be converted (“transcribed”) into device specific compressed
GPU texture formats.
We use Quantization and remove redundant
keyframes to reduce size of animations.
We pay special attention to keep our WebAssembly binary size small and keep the amount of dependencies low,
as the runtime is one of the first things to be downloaded.
Our WebAssembly runtime is currently around 1.3 MB and will even be reduced further eventually.