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 convience 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 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 will have one value per point, Group_Vertices attributes will have one per vertex, Group_Primitives has 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 will show up with a default gray colour in the viewer and will come out black in a render.
Materials in NUKE’s 3D system can be any 2D op. In the general case the output of the 2D op will be used to texture the geometry. There is a special type of Iop, DD::Image::Material, which is a base class for ops which provide more complex material behaviour.
Contains all the information about a 3D scene, including lights, cameras and a flattened list of the geometry.
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.
A single piece of geometry, consisting of:
A simple geometric object such as a point, triangle or polygon. This is a pure virtual base class. See the Using and extending 3D primitives page for more details about these.
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, will have 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 will check 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.
A camera, obviously.
A light. There are a few different kinds of light that NUKE supports: directional lights, point lights and so on.
A base class for Iops which provide 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 will be used as a 2D texture.
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.