NUKE is a non-destructive, node-based (procedural), 32-bit float, multi-channel, scanline, image compositing system using its own image processing graph (usually called Node Graph or DAG). (In addition to the scanline-based 2D image system there are also a number of sub-system available, such as 3D system, deep image compositing system, and particle system.)
NUKE’s 2D architecture is largely defined by the Iop class, which is the base class for all the image operators. Iop specifically defines how NUKE’s channel system works, how region of interest and regions of definition are passed up and down the tree, how 2D data is cached, and how bounding box and image formats are dealt with. Several pure virtual functions must be defined by a inherited subclass.
As described above, NUKE is a scanline based system. This means that according to NUKE the fundamental unit for image processing is a scanline. The scanline is one horizontal line of the image. In the NDK (Nuke Developer Kit) a scanline is known as a Row. This architecture is the main reason NUKE can deal with almost unlimited image sizes. Because image processing is limited toRow-size chunks, the whole image does not need to reside in the computer memory at once.
When displaying a large image on the Viewer screen, there are typically less Rows displayed on the screen than actual Rows in the full image. The NUKE Viewer does not ask its input for every Row to produce the output image, as they are not required for display on the screen. In other words, the Viewer skips Rows. This is one of the reasons NUKE is fast and interactive even when dealing with large image sizes. This strategy for dealing with large image sizes also means that Rows are always computed at full resolution horizontally. Once they are computed, they are correct no matter what the zoom level on the image in the Viewer. In other word when the user zooms in, the Viewer only needs to ask its inputs for Rows it hasn’t asked for yet.
When producing the output image, the output node typically runs multiple threads to fetch multiple Rows from its input at the same time. NUKE has internal synchronization that guarantees only one thread is operating on one Row of one node at a time.
Typically when doing image processing, when some nodes are asked to produce their Row of output, they actually need more than one Row of input to produce the output Row. For instance, a Box Blur may need many input Rows for each output Row. In order to avoid computing the same Rows multiple times, NUKE generally creates a cache for those Rows. When a node asks for the same Row, it is returned from the cache instead of being computed again.
Often when performing image calculations, your image processing engine needs to access more than just one Row from its input to produce its output Row. In order to do that, NUKE has a concept of a Tile. A Tile has accessor functions on it that allow you to access pixels as a 2-dimensional array of the given Tile size. It is important to note that the fundamental unit of image processing in NUKE is still a Row. When a Tile is created for an input Op, a cache is created (if one doesn’t exist already), and then NUKE fills the Rows required on that input Op to fill the Tile. Those Rows are then locked in the NUKE cache for the existence for the Tile object. You can then use accessor functions on the Tile into the internal Rows in the cache for that input.
NUKE handles image colors as channels. A channel describe one floating-point component of all pixels in an image. Multiple channels make a channel set (sometimes called a layer).
There is another cache in NUKE in addition to the Row cache. This is called the Viewer cache and is also described in the Preferences and the user interface as the disk cache. The Viewer cache is a file written to your disk for each frame as it is displayed in the Viewer. The Viewer cache file is not used for image processing and is separate to the Row cache. Its primary purpose is the quick display of images in the Viewer for playback and viewing. Because it’s written to disk, it survives between runs of NUKE. When the Viewer as an output node needs to produce an output image for display, it first checks to see if any Rows that it needs to display are already in the Viewer cache on disk. If they are, it simply displays them rather than asks its input for the Rows. If any Rows are missing from the cache, the Viewer asks its input fro them as usual. So if you run NUKE after modifying your code when you create your own node, the results of the previous state appear in the Viewer instead of the new results. When you encounter this problem, do not panic. Move the mouse cursor over the Viewer area will refresh the Viewer.