This document is a variation of what was presented on the blog.
Viewport gizmos play an important role in making common features in Blender accessible without having to learn shortcuts. Similarly, gizmos for procedural assets can make the asset usable directly in the 3D viewport, without having to dive into potentially long parameter lists.
For example, in the mockup below, the height, twist and number of spots of a procedural vase can be controlled with gizmos.
The goal of this task is to describe how gizmos can be integrated with geometry nodes in a way that is well defined and flexible enough to support the following features:
- Support various kinds of gizmos (translation, rotation, etc.).
- Technically, we could support custom gizmos where the gizmo shape is generated in geometry nodes, but we intentionally don’t want to allow this for now, because we would rather have a small set of of well known gizmos that have a consistent look and feel.
- Support using a gizmo in a node group without the intention of turning it into an asset.
- Support exposing an arbitrary number of gizmos from a node group.
- Support building more complex custom gizmos as node groups by combining existing gizmos.
The proposal is to add separate nodes for the different kinds of built-in gizmos.
There are two main challenges to solve:
- Where is the actual gizmo value stored?
- How to deal with the dependency loop that the gizmo position depends on gizmo value, but the gizmo value also depends on the gizmo position?
The proposed solution is to make the
Value input of the gizmo nodes special. To detect where the gizmo value is stored, we statically follow links backward from the
Value socket until there is a value that can be changed destructively.
In the simplest setup, there is an input node connected to the gizmo value. In this case, changing changing the gizmo in the viewport changes the value in the input node. Only reroutes are allowed on the path from the input to the gizmo node.
This approach allows the same input node to be used with multiple gizmo nodes. I could see this being useful in more complex setups like a castle generator where there are multiple gizmos in different places that control the same wall thickness.
The other inputs in the gizmo node can depend on the value and determine where the gizmo will be drawn in the viewport.
Since there is no output on the gizmo node it is more obvious that this is just a node that affects the UI, similar to the viewer node.
The gizmo value can also be linked to a group input. This exposes the gizmo to the calling node group or modifier. So in the image below, the gizmo in the viewport controls the Value input of the group node on the right. To further expose the gizmo up to the parent node group, one just has to link the value to a group input again.