The Scene DAG

All geometry is stored in a scene DAG (directed acyclic graph) that is built from groups and instances: a group is a container node that lists multiple child instances. An instance is used to place elements in 3D space (namely, groups, geometry objects, lights, and cameras). Instances contain a transformation matrix that converts from the parent space to local space, placing its child relative to its parent, and its inverse. Optionally, it may reference a transformation function that defines the transformation at runtime, and it may reference a material that is used for material inheritance.

The scene DAG also allows multiple instancing. This means that two or more instances may reference the same group, object, or light. The effect is that the referenced element appears more than once in the rendered image, at different locations determined by the instance transformations.

The Scene module offers two operations that are required for rendering begins, as part of a process called preprocessing. One is to convert the DAG with multiple instancing to a leaf instance list, such that there is one separate instance for every geometry object instance in the scene. It is then possible to evaluate the leaf instances in sequence to generate a complete list of geometric objects and lights. The transformations in the leaf instances of the preprocessed tree are composed from all parent transformations all the way back to the root of the tree; they convert between object and camera space. Parameter inheritance is also evaluated. This involves propagating materials or other user data down the tree during traversal according to programmable rules, and storing the end result in the leaf instances where it can be accessed by shaders. Parameter inheritance allows instancing an object in different places with different surface material properties.

The second main operation during preprocessing is tessellation. In the DAG, geometry may be stored as free-form surfaces and polygons, which are not directly renderable. Rendering always operates on triangle geometry stored in boxes. The conversion from surfaces and polygons to triangle boxes is called tessellation. The scene module uses dirty flags to keep track of which instances, transformation functions, and geometry objects in the scene DAG have been created or modified since the last tessellation, and retessellates only objects that have been modified or transformed. After tessellation, every leaf instance references a box (or box chain if the object is too large to fit in one box).

If an instance has a geometry shading function list attached, this function list is called during preprocessing. The geometry shaders return a scene element tag which is put into a group attached to the instance. This group is used for initialization of the source geometry in the DAG object. In addition, each material of an object is checked for geometry shaders to be called. All resulting dynamically created objects are put into a group attached to the object. This dynamically created source geometry is scheduled for tessellation in the same way as non-geometry shader objects.

Instancing requires that the renderer operates with object coordinates, not camera coordinates. This allows the Scene module to have multiple leaf instances, each with a different matrix, share the same box list. This happens if the object from which the boxes are derived was multiply instanced. Multiple instancing will fail for camera-space renderers because all instances of a multiply-instanced object will appear in exactly the same location in 3-space.

Source DAG
Source DAG

When this DAG is preprocessed, leaf instances for lights and objects are attached to the DAG (shown here as dotted arrows) The original DAG remains unchanged except for cached boxes (1c1 and 1c2) attached to objects.

Pre-processed DAG
Preprocessed DAG

This diagram shows that preprocessing produces two new lists: the light list and the object list. For clarity, an instance referencing more than one child is shown with two arrows leaving at the bottom; this is really implemented with child/sibling links. Groups contain real child list arrays. All arrows are tag links, not pointers. All instances referenced by dotted arrows are leaf instances. Because instances 2 and 3 both reference group 2, multiple instancing occurs and both light 2 and object leaf instance 7 with its boxes are duplicated into a and b versions. a is the result of instance 2, and b is the result of instance 3. (Because of the object-space restriction, 1a1 and 1b1, and also 1a2 and 1b2, are identical; Tags 1a1 and 1b1 are identical and so are 1a2 and 1b2.) The diagram shows a situation where object 1 is too large to fit in one box and needs two boxes for each instance.

The boxes 1c1 and 1c2 attached to instance 7 are called cached untransformed boxes for object 1. This list is optional. The preprocessing function can be told to make a copy of the reference to the results from a tessellation before transforming the boxes and attaching them to the leaf instances. This increases memory usage after rendering completes because boxes are not deleted during postprocessing, but it avoids retessellation of the same object if the object is instanced multiple times or if the scene is rendered multiple times with different transformations. Again, note that 1a1, 1b1, and 1c1 are all the same box, and 1a2, 1b2, and 1c2 are all another box, so that only two boxes exist in memory.

The new leaf instance contains a transformation matrix (which is optionally applied to the vertices in the boxes by preprocessing) and a material field, both of which are created by combining transformations and material fields during descent from the root group. This means that the leaf instances 7a and 7b likely have different transformations and/or materials because they are descended from different instances, 2 and 3. Transformations are combined using transformation function evaluation (if present and enabled) and matrix multiplication. Materials are combined by calling an inheritance function or traversal function specified by the options block. A material in this context need not be a simple material tag; it is an arbitrary-sized user field that can store more information such as textures or colors, or material editor flags. For such non-simple user fields, it is the responsibility of the inheritance or traversal function to properly propagate different user field members. It is called for every new instance encountered during traversal, and is called with both the parent parameters (none for the top-level instances) and the current instance.

Copyright © 1986, 2015 NVIDIA ARC GmbH. All rights reserved.