Skip to content

Analysis: Caching

With a procedural workflow and more complex computations, caching is important to maintain good performance. There are a few different types of caches, each solving different problems. This document is intended to clarify discussion on this topic.

Alembic Caches

This type of cache stores an entire scene or collection of objects on disk, with baked transformations and geometry. Rigs, modifiers and other procedural effects are baked. Fast streaming of an animation sequence is possible. Alembic and USD are the common file formats, and can store an animation sequence in one file.

Use Cases

  • Interop between different applications.
  • Hand-off between different parts of the animation pipeline (e.g. animation -> physics -> lighting).
  • Better performance opening and playing back files.

Challenges

  • Blender and file format data structures may differ, causing subtle data loss or meaning some Blender features must be avoided.
  • Materials, lights and other custom Blender data must be defined outside Alembic and re-attached to the geometry after loading.
  • Need pipeline support to keep caches up to date and share them. A lot or little manual work for users.
  • New ways for things to fail, due to incomplete implementations and bugs in code that would otherwise not be needed.

Physics Caches

For physics simulation, each frame depends on the previous one and computing physics for the entire frame range up to the current frame is too slow. In general, physics baking is expensive to compute and may be run as a batch job on a user's computer or a render farm. Blender physics systems use custom file formats for this currently, with the exception of OpenVDB smoke. Other 3D apps also often use custom formats, with one file per frame.

Use Cases

  • Caching for physics playback in the viewport, if it's fast enough to be interactive.
  • Baking on a local computer for slower physics.
  • Baking on a render farm for even more expensive physics, or different variations.

Challenges

  • Good usability of clearing and saving caches, showing what is up to date, .. is a challenge. Users do many experiments before finding the final parameters.
  • File format must support fast random access read, and fast append write.
  • Disk space usage can be significant, especially for volumes.
  • Needs pipeline support when sharing and render farms are involved, may go out of date.
  • Current custom file format does not support topology changes, just array of points.

Memory Caches

While Blender is running, the result of node evaluation or other computations also must be cached in Blender. This allows quicker updates for editing and animation playback.

Use Cases

  • Cache evaluated mesh of each object, only update those that changed.
  • Cache intermediate node evaluation results, for faster parameter tweaking.
  • Cache animation sequence over multiple frames in the background.
  • Image textures loaded from disk.

Challenges

  • Memory usage is a concern, especially when caching intermediate results. Memory limits can help.
  • Keeping input and evaluated data in sync and intelligent updating just what is needed is hard (depsgraph).

Compile Caches

With more advanced node system, we can dynamically compile programs. If there are many such programs in a complex scene, caching the compilation is important.

Use Cases

  • Function nodes compiled to LLVM.
  • EEVEE shaders compiled to GLSL.
  • Cycles kernels compiled to OpenCL.

Challenges

  • Initial wait time when opening files or rendering can be long for initial cache fill.
  • Separate fast-to-compile and fast-to-run code paths are possible, but lead to extra code maintenance and bugs.
  • Machine code typically cannot be shared between systems, so every user has to wait.
  • Compilation performance is somewhat out of our own control and for GPUs driver dependent, difficult to rely on.

Notes

Memory and compile caches should mostly require no user interaction besides tweaking settings to keep memory usage under control. Physics caches can be somewhat automatic for playback, but users need to be aware of what is out of data, and of course for baking. Usability in Blender in this area should be improved.

Alembic caches are in common use for interop with other applications. When used in a production pipeline that is mainly Blender, usability is in my opinion not good enough to replace linking .blend files even if it would speed up some things. A lot more work is needed to ensure assets can be reliably exported to Alembic and loaded without data loss.

Part of that is in Blender implementation, part of that is in pipeline. Alembic style caches may not only be useful when handing off assets to the next pipeline stage within a bigger production. Being able to bake/freeze a collection within a single Blender session may be useful too. This kind of baking could in principle be done without converting to Alembic, though disk/memory usage would need to be reduced in some way.

It may be tempting to try to combine physics and Alembic style caches in some way. Support for topology changes would be good for features like cloth tearing and fracture, though Alembic does not have good file append performance, so it seems not an ideal fit. Mainly from a usability point of view, it is probably best to keep these uses cases separate regardless of the underlying file format. Physics simulation iterations and handing off a scene to the next pipeline stage are different workflows which should each be optimized in their own way.

USD is interesting in that it provides a file format that can not only be used for caching, but also to store original data. Using a single format for both avoids having to convert between different representations, which means less code and fewer bugs. It seems unlikely that we would move away from the .blend file format and data structures however.