NUKE’s Classic 3D Architecture

Introduction

NUKE’s 3D support is based around the DD::Image::GeoOp base class. This is the 3D equivalent of the DD::Image::Iop class: it provides all the common parts of handling 3D data in NUKE.

There are specialised subclasses of GeoOp for creating and modifying geometry (DD::Image::SourceGeo and DD::Image::ModifyGeo respectively), although they’re a convenience rather than a requirement: it’s possible for any subclass of GeoOp to create or modify geometry.

There’s more detailed information about GeoOp and its subclasses on the Writing a GeoOp page.

Ops which take a 3D scene and produce a 2D (or deep) image are referred to as renderers. There are some base classes which the NDK provides that may help in implementing these, such as DD::Image::RenderScene. NUKE’s ScanlineRenderer inherits from this class, for example.

When passing 3D data through the Node Graph (DAG), NUKE uses a flattened representation rather than a full scene graph. A scene consists primarily of a list of objects, where each object is specified in a local coordinate system and has a matrix to transform it into world coordinates. A scene also has a list of lights and cameras.

3D objects are represented individually by the GeoInfo class. This stores the world transform matrix and the lists of points, vertices, primitives and attributes for the object. Additional information like normals and texture coordinates is stored in specially named attributes (“N” and “uv” respectively). Attributes are stored in groups which determine their cardinality: Group_Points attributes have one value per point, Group_Vertices attributes have one per vertex, Group_Primitives have one per primitive and so on. Attributes can be added dynamically to any of these groups. Attribute names must be unique within their group, but otherwise they can have whatever name you like, and there is no limit to the number you can add.

A GeoInfo also has a pointer to a material. There is a single material at most per object. Objects which don’t have a material display as a default gray color in the viewer and come out black in a render.

Materials in NUKE’s 3D system can be any 2D Op. In general, the output of the 2D Op is used to texture the geometry. There is a special type of Iop, DD::Image::Material, which is a base class for Ops providing more complex material behaviour.

Core Classes

class DD::Image::Scene

Contains all the information about a 3D scene, including lights, cameras and a flattened list of the geometry.

class DD::Image::GeometryList

A list of geometry items which packs the data together in a cache-friendly arrangement. This is used to hold the geometry data for a Scene.

class DD::Image::GeoInfo

A single piece of geometry, consisting of:

  • a list of points

  • a list of primitives, whose vertices refer to indices in the points list

  • a collection of attributes

  • a pointer to a material op

  • a local-to-world transformation matrix

class DD::Image::Primitive

A simple geometric object such as a point, triangle, or polygon. This is a pure virtual base class.

class DD::Image::Attribute

A container for per-point, per-vertex, per-primitive, or per-object data. Attributes have a name and an array of data items. A per-point attribute, for example, has one array entry per point in the object. The group of an attribute is whether it’s per-point, per-vertex, etc.

Attributes can hold different types of data. For example, vertex normals are stored in an attribute where every data item is a Vector3. Other available types include ints, floats, strings, matrices, and arbitrary pointers.

Attribute names are unique for each group. You can have attributes with the same name in different groups, but you can’t have two attributes with the same name in the same group.

Attributes are usually accessed via the AttribContext class, rather than directly. This gives an extra level of safety: the AttribContext checks that you’re getting the correct type of data out of the Attribute. You would generally only go directly to the Attribute when speed was of the essence.

class DD::Image::Camera

A camera, obviously.

class DD::Image::Light

A light. There are a few different kinds of light that NUKE supports: directional lights, point lights, and so on.

class DD::Image::Material

A base class for Iops which provides special behaviour (custom shading, etc.) when used as the material for a 3D object.

Any 2D Op can be used as a material. If the Op is not a subclass of Material, it is used as a 2D texture.

Coordinate Systems

NUKE uses a right-handed coordinate system.

Points for each GeoInfo are defined in object (local) coordinates. To convert these into absolute positions in world-space (world coordinates), they must be multiplied by the GeoInfo’s matrix.

Axis Ops can be used to define new coordinate systems. They provide controls for scaling, rotation, translation, skew, etc. The Op combines these into a matrix which can be used to transform coordinates from the Axis’ space into world space.

Matrices in NUKE use column-major ordering, to match OpenGL.