A “VDB” is typically defined as a “voxel database” or a “volumetric database”. It is a data structure that allows users to store sparse-grid information in the form of vectors, scalars (numbers), etc.
If that is still confusing, consider the following illustration: Imagine a 2D image. Each pixel contains an RGB (vector) value. If its resolution was something like 1024x1024 pixels, it would contain over a million pixels in total. Now imagine that only a handful of pixels in the image contain color information (maybe a couple of tiny dots in the corner)…the rest of the pixels are completely blank and contain no useful color information. What would be the most efficient way to store all of that data? Certainly not a straightforward pixel-by-pixel storage format, since it would contain data for both colored pixels and also data for a million empty pixels, which is a waste of storage space. Now, imagine if you converted that 2D image of pixels into a 3D cube of voxels with a resolution of 1024x1024x1024. Instead of a million empty pixels to store, you have a billion empty voxels to deal with. Even using various compression schemes to crunch the data would still be very inefficient.
That’s where VDBs come in: they are tree-based structures that only contain data relevant to active voxels in a grid space. And their grids are implicit - they have no boundary defining the extents of their empty voxels because they don’t need one. They don’t store empty voxels - they only store data where necessary. VDBs exploit the fact that volumetric representations of objects tend to have lots of holes and empty space around them, and use that fact to their advantage in order to maximize memory and storage efficiency.
OpenVDB - the brainchild of Ken Museth - is the industry-standard VDB library for developers to implement (and it is the one used by tyFlow). It contains many helper functions for constructing signed distance fields, advecting velocities, performing various grid analyses (curvature, gradient, laplacian, etc), converting to and from polygonal meshes…the list goes on and on. It is a robust framework for working with voxels and it adds a ton of functionality to tyFlow’s overall capabilities.
In short: VDBs are a data structure you can use to store and modify data inside voxels.
tyFlow offers a variety of operators which can be used to manipulate VDB data. A typical workflow might involve converting a polygon mesh into a VDB, advecting its surface, and then converting it back into a mesh. Or converting a mesh into a density field for later rendering as smoke or fog. Usually the user will start by converting a mesh into an SDF, then they will modify or convert the SDF with various tyFlow operators, and finally export the resulting VDB to a .vdb file or mesh format.
A VDB can contain multiple grids of different types (and a “grid” in this case is just a set of voxels that each contain a piece of data). For example, it might contain an SDF grid, a velocity grid and UVW grid. Changes to one grid won’t affect another grid unless you’re specifically performing operations on both (ex: using an SDF Solver operator to advect an SDF grid with a Velocity grid). You can use the VDB Modify operator to make changes to specific grids in each VDB. As an analogy, think of a VDB like a Photoshop PSD file, and the grids inside like the layers of your composition. Layers can be modified individually, but also blended and combined to compose a final image. Similarly, a VDB can contain multiple grids but the goal is usually to harmonize them together for a single type of output.
An SDF is a Signed Distance Field. A signed distance field is a scalar field where the value of each grid cell corresponds to that cell’s distance to an implicit surface. Values inside the implicit surface are negative, while values outside are positive. By using these values alone, an explicit surface can be computed. SDFs are the basis for all mesh-based computations within a VDB.
A Density grid is a VDB grid type that contains scalar values which represent grid density at any given point. A value of 0 means a given cell is empty, and a value of 1 means a given cell is full. By using these values, dense substances like fog/smoke/atmospherics can be computed (ie, any substance that doesn’t have an explicit surface).
While both Density and SDF grids are composed of scalar values alone, operations on those values will produce very different results. tyFlow’s VDB implementation allows SDF grids to be converted to Density grids, and vice versa. This allows for extra flexibility when working with grid data. For example, adding noise to the values of an SDF will improperly skew its surface representation, but adding noise to a Density grid will simply alter its overall density. By converting that altered Density grid back to an SDF, a properly displaced surface will be the result. Similarly, an SDF can be converted to a Density grid for transforming the implicit surface into a dense, volumetric representation.
VDBs are not internally converted into particles in tyFlow, nor are their voxels. Their voxels (which have a static location in space) are directly manipulated by VDB operators at each step of the simulation. For example, imagine you have these VDB operators in your flow: Birth VDB (to initialize the VDB at a particular frame), Object to SDF (to convert a polygonal mesh into a VDB-based SDF), VDB Modify (to generate vectors from the SDF), SDF Solver (to advect the SDF along the generated vectors) and SDF to Mesh (to convert the SDF back into a polygonal mesh). At each step of the simulation, tyFlow will process the operators and iterate through all active voxels in the initialized VDBs, manipulating their data long the way in one fell swoop. So, instead of iterating over a list of particles with your operators, you’re iterating over a list of initialized VDBs. In other words, each operator affects all active voxels in a VDB at once, and the flow of your operators determines how the VDB’s data evolves over time as a whole. No specific manipulations of individual voxels are possible, unlike in a particle system where it’s easy to make specific adjustments to individual particles.
Yes, some VDB operators can output particles from a VDB, and other operators can input particle data into a VDB. Since both VDBs and particles are updated together during the same time step, they can work together in lockstep (for example, you can convert VDBs to particles, or advect particles with VDB velocities, etc).
tyFlow can export VDB data as a mesh or in the .vdb format. Beyond that, users will have to rely on their preferred renderer’s ability to process the .vdb format in order to render it. The same goes for atmospheric representations of VDB data in the viewport - tyFlow can display VDB data as a mesh, but in order to view representations of fog or other atmospheric effects in the view, users must rely on 3rd party software (ex: VRay’s VRayVolumeGrid object, or a PhoenixFD container). Point-based representations of Density grids are possible in tyFlow, using a Display VDB operator. Velocities and UVWs can be visualized in a similar way.