Try โ€‚โ€‰HackMD
tags: Design

High level controls for node assets

A proposal for making complex node trees customizable using node groups parameters.

Node assets that are supposed to be used as building blocks require detail knowledge to tweak their internals. Some parameters can be exposed on the modifier level, but extending a system requires a different approach, as will be demonstrated below.

This proposal describes a mechanism to allow users to specify node groups at the highest level of a node asset, which are then used inside the asset without requiring users to touch the asset internals themselves.

The modifier stack for node assets and its limitations

Simon Thommes recently published the first set of hair hair assets to be shipped with Blender.

Simon breaks down the hair workflow into separate modifiers. This relies a lot on the fact that modifiers can be applied as a single self-contained step one after the other.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More โ†’

Modifier stack in Simon's hair assets

Simulations won't be able to use this organizational trick so easily. That's because simulations contain multiple loops, nested inside each other, and the parts that users would be interested in modifying and swapping out are located within those loops.


Particle simulation prototype with a large simulation loop (click to enlarge)

The most obvious loop is the simulation stepping itself, sandwiched between the Simulation Input and Simulation Output nodes. This cannot be split into multiple node groups which then each go into their own modifier. In addition to this outer loop there may also be inner loops, depending on the purpose and complexity of the simulation.

In addition to having customizable parts inside loops there may also be initialization steps before or cleanup steps after the loop, which have to match parts inside the loop body.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More โ†’
.

Node groups for customizing assets

Let's use particle emitters as a case study. A particle system should support an arbitrary number of emitters. There are many different ways a particle emitter might be implemented:

  • A continuous stream of particles with a variable rate
  • Emission of a fixed particle count over some interval
  • Burst of particles at a single point in time

We can imagine an emitter as a node group that simply outputs a point cloud as geometry. Users could create such a node group quite easily without knowing a lot about the rest of the particle system.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More โ†’

Users should not need to dive deep into some obscure particle system to insert a new emitter. Instead, we want to decouple the declaration of such node groups from their evaluation.

Function sockets

A "function socket" encapsulates a node tree as a data type. It can be passed around a tree like other data types. It is ultimately passed to an Evaluate Function node, which takes the place of a regular node group. In place of the usual node group button it has a Function input socket.

The function can be generated by binding a node tree: If a node asset exposes a Function socket, users can select a node group as a default value. This provides an straightforward way to use node groups as a configuration tool for assets:

  1. Asset authors decide where customization is needed and provide function parameters for those cases (e.g. particle emitters).
  2. An Evaluate Function node is added where the outputs of such custom groups are used (e.g. the emission stage at the beginning of a simulation loop).
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More โ†’
  3. The Function input socket gets exposed through the node group interfaces, right to the top level of the asset.
  4. Users can define one or more groups to use as emitters with the resulting node tree button.
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More โ†’

How it works (the short version)

What function sockets are not:

  • Function sockets are single-valued (no fields). This should keep overhead from type checking and dispatching to a minimum. The Evaluate Function node can still accept and return fields, it just means the function itself is the same for all elements of a field.
  • Functions are never stored in blend files (serialized). There is no "function attribute". They are purely a runtime feature to customize a node tree.

The data type of a function socket is a closure: A combination of the node graph and a set of default values for inputs. The closure can be copied and passed through the node graph until it is evaluated.

passed through the node tree
Node Tree
Default Bindings
bind
Closure
evaluate
Result

The inputs and outputs of the Evaluate node are not directly related to any node tree. Users can freely chose which inputs to provide and which outputs are expected from an evaluation.

This means that a node tree can be unsuitable for a given evaluation! Specifically, inputs and outputs of the graph are optional: The Evaluate Function node can specify a subset of the graph inputs and any unspecified graph inputs will use a default or bound value. Likewise any unspecified graph outputs will simply be regarded as unused.

The evaluation node must, however, make sure that any specified outputs are provided by the graph it evaluates. Passing in a graph that does not have all required inputs or outputs constitutes a runtime error.