利用者:Geraldine/GSoC 2018/Proposal
目次
Further Development for Cycles' Volume Rendering
Traditionally, solid objects are represented as meshes: a set of vertices, edges, and faces. This interpretation of real-life objects into 3D space is more than sufficient for solid media such as teapots and chairs. However, this model faces many issues when used to represent more dynamic materials such as smoke or clouds or water, which have innumerable and constant shifts in number and location of vertices, edges, and faces, leaving mesh manipulation insufficient in terms of rendering efficiency, speed, and realism. These types of objects are typically classed and implemented separately as Volumes.
Due to the nature of the materials involved, Volume rendering requires a different set of solutions in regards to data structuring, light sampling, and so on. Quickly becoming an industry standard, OpenVDB is a Volume rendering framework developed by Dreamworks that sees wide usage throughout the graphics industry such as in Pixar's RenderMan, Houdini, and Modo. It is known for its incredible efficiency in handling sparse data sets and its wide range of filters, transformation operators, compositing tools, and many other features for the creation and robust manipulation of Volumes. Its integration into Cycles will surely further Blender's usage in the 3D graphics scene, as it is one of the most highly requested features by the Blender Artist Community.
Currently, Blender provides some partial support and integration with the OpenVDB standard. However, there is still a long ways to go before the full integration of Cycles with OpenVDB. I propose to tackle some of the current challenges in Volume rendering as follows.
Tiled 3D image storage and sampling support
Tiling is the method of taking a 3D scene and recursively subdividing it by a grid into tiles. This method of storing and restoring a scene requires significantly less memory usage, processing, and bandwidth when compared to the more naive method of regenerating the entire image. Since volumes are generally massive, sparse datasets, significant optimizations can be made to the kernel's efficiency in storing and speed of rendering Volume objects via the implementation of cache tiling. This also has the advantage of aligning the abstraction of Volumes in storage with that of the OpenVDB standard.
Support for import and reading of OpenVDB volumes as Cycles 3D images
Interoperability between industry software is a highly sought after feature. The Blender user base commonly uses many different tools in 3D modelling and animation, and a highly requested feature is the ability of Blender to read and edit OpenVDB volumes created in other software such as Houdini. Complete integration is a complex goal requiring many steps, one of the first of which should be the ability for Cycles to render OpenVDB objects. The programming of Cycles to be able to read and render OpenVDB objects not only allows Blender users to integrate their OpenVDB assets with their Blender projects, but also lays the groundwork for further integration with the OpenVDB framework.
Creation of a Volume Primitive
Cycles currently interprets Volumes as a mesh-type object. However, it would be much more prudent to have Volumes as their own separate data structure from Meshes, resulting in a much more structured codebase, easier implementation of Volume specific algorithms and functions, and, similar to the importation task, will represent a great step in furthering OpenVDB support in Blender rendering. The formal addition of the OpenVDB object into Cycles also opens the gates to making use of its various optimizations and efficiencies in regards to memory usage and speedy processing of volumetric data.
If time permits, the following feature may also be implemented:
Volumetric motion blur
Although motion blur for other object types currently exist in Cycles (e.g. dynamic meshes), volumetric motion blur has yet to be included. Motion blur for moving objects increases scene realism, and as such, the implementation thereof using Temporally Unstructured Volumes in combination with the Reves algorithm will help further develop the Cycles engine's accurate visualization of volumes in motion.
Deliverables
Basic Deliverables
- Improvements to Cycles' kernel memory, CPU, and bandwidth usage through implementation of volume tiling storage and sampling.
- Import and conversion of OpenVDB volumes to Cycles images.
- Creation of a Volume Primitive with interfacing to OpenVDB methods.
Reach Goals
- Integration of the Volume Primitive with existing codebase (the extent of which depends on the allotted time remaining).
- Motion Blur algorithm implementation for Volumes.
For all of the above
- GUI and Python API for appropriate features, i.e. those that involve user interaction.
- Developer documentation for reference, code maintenance and further development.
- User documentation and demonstration of new features as appropriate.
Project Details
Tiling for Volumes
From previous work on this topic, there currently exists an implementation of a marching cube algorithm to create a tight cubic mesh around the volume object. This has the benefit of greatly increasing rendering speeds for scenes containing Volumes, thanks to the merging of empty and non-empty voxels into "cubes" to reduce memory usage. This algorithm can be adapted for use in the kernel's cache.
We may divide the dense 3D volume grid into several NxNxN "cubes". For each cube, we store the coordinates and values of all "active" voxels, where a voxel is classified as "active" based upon some constant threshold. These cube abstracts would have ϴ((4N)^3) = ϴ(N^3) (3 coordinate values and 1 voxel value) space complexity, which is roughly equivalent to the original NxNxN sub-grid, while the average case given a sparse dataset will have much better performance. This conversion has the benefit of being easily reversible, to allow compatibility with the rest of Blender's volume manipulation. intern/cycles/kernel contains the relevant code for storing and retrieving volumes in the cache. The above algorithm will be inserted prior to the storage and after the retrieval of the volume data from the cache.
OpenVDB Import
Blender currently supports importing smoke objects from .vdb files into Blender objects compatible with the OpenVDB standard. However, this is somewhat limiting for a number of reasons, particularly the inability to import other volume materials. This task concerns the generic reading and rendering of all OpenVDB objects into Cycles as renderable images.
The OpenVDB library contains an IO functionality openvdb::io::File for reading of .vdb files into grids. In the OpenVDB data structure, a grid contains, among other data, the values of every voxel at every coordinate of the volume. Thus, we can convert the OpenVDB grid into a Cycles 3D image by generating a blank image, iterating through every voxel in the grid and retrieving its value, and storing the value in the Cycles image. Basic transformation operations will also be included e.g. translation, rotation, etc.
Editing of OpenVDB objects is outside the scope of this task, as it requires a much stronger integration of Cycles with OpenVDB than currently exists. Likewise, export to OpenVDB format will not yet be supported.
Creation of a Volume Primitive
OpenVDB utilizes three data structures in representing volumes: the Tree, a B-tree-like 3D structure that stores the actual voxel values; the Transform, a matrix that dictates how to transform the Tree from its local indices to the world coordinate system; and the Grid, which contains the Tree, the Transform, and any other additional characteristics, features, and methods of the volume object.
Currently, Volumes in Blender are stored as dense 3D grids which are only distinguished from standard meshes by a volume flag and attribute. This system could be greatly improved if supplanted by the OpenVDB library.
The volume Primitive will (as taken from previous work) tentatively have following structure:
typedef struct VolumeData {
struct VolumeData *next, *prev;
struct OpenVDBPrimitive *prim;
char name[64]; /* MAX_NAME */
short type; /* data type: float, int, vector... */
...
} VolumeData;
typedef struct Volume {
ID id;
ListBase fields;
} Volume;
This gives us most of the benefits associated with the OpenVDB framework, such as reduced memory usage, constant-time accessor, etc. while conforming to the standard Blender object data structure.
The next task would be creating a basic interface for the methods from the OpenVDB library with greater potential to see frequent use, in particular:
- voxel iteration
- voxel access
- voxel assignment
- randomized voxel assignment
- transformation
- reading and writing of grid metadata
- read grid from or write grid to external file
Finally, the parts of the Cycles code base that utilize volumes shall be updated to make use of the new volume primitive API (or to remove workarounds that were needed previously but are no longer required for the new primitive), such as (tentative list):
- intern/cycles/render/mesh.cpp
- intern/cycles/render/mesh_volume.cpp
- intern/cycles/render/nodes.cpp
- intern/cycles/render/object.cpp
- intern/cycles/render/osl.cpp
- intern/cycles/render/shader.cpp
- OpenVDB Smoke read/write feature
Project Schedule
Week | Date | To-do |
---|---|---|
0 | Apr 24 - May 13 | Exploration of Cycles code base and OpenVDB framework. Research implementations and prepare basic skeletons for the proposed tasks. Community bonding. |
1 | May 14 - May 20 | Tiled cache storage in kernel for volumes, CPU rendering. |
2 | May 21 - May 27 | Tiled cache storage in kernel for volumes, GPU rendering. |
3 | May 28 - Jun 03 | Testing Tiled Cache feature. Perform comparison tests. |
4 - 5 | Jun 04 - Jun 17 | ImageManager extension for reading OpenVDB files and conversion to Cycles image. |
6 | Jun 18 - Jun 24 | Testing, GUI, Python API, and build scripts for VDB Import feature. |
7 - 8 | Jun 25 - Jul 08 | Creation and testing of Volume Primitive structure and interface with OpenVDB utilities. |
9 - 10 | Jul 9 - Jul 22 | Updating and testing of Cycles volume handling with the new Volume Primitive. |
11 | Jul 23 - Jul 29 | Free week, buffer in case of unexpected scheduling issues, emergency situations, complex code errors, etc. |
12 | Jul 30 - Aug 05 | Final testing and debugging. At this point, all features must be ready for deployment. Finalized compilation of documentation (the features should be documented alongside the coding work). |
Biography
I am Geraldine Chua, and I am currently a Computer Science student at the University of Hong Kong. Although I am still an undergraduate, I am very interested in the field of computer graphics. From previous school projects and internships, I have experience in professional software development using Python, but my first language(s) learnt was C/C++, and I would say I am quite proficient in the latter. I have always been amazed at the art and beauty that has been created by the Blender Community, and I would be honored to help develop Blender even further.