Gizmos for Geometry Nodes [Proposal]

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.

image

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.

Gizmo Nodes

The proposal is to add separate nodes for the different kinds of built-in gizmos.

image

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.
image

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.

18 Likes

I described the result of my reflection on this in Pass editing data through geometry nodes.
The main problem with passing the Ownership of a Value by socket to the top of the stack of nodes in the tree is that the values are positioned depending on the context.

  • I broke the link:
    • Where are my values?
    • Are they copied to the node below?
    • Are they still in the node above?
    • What if there are 2 nodes connected to this?
  • I am copying the node tree to another object:
    • I want a copy of the values!
    • I don’t want copies of the values!
  • I am copying several nodes in a group:
    • … .

The main problem, also, as I see it, is that it still doesn’t solve the problem of it being just a one-pot thing. So if I wanted to rotate the vase, or instantiate it, how would the gizmo handle it?

This means that the gizmo must be a geometry that the user can handle like any other.

This is an early examples of how I see the solution:

Summary


The value is stored as usual. It is easy for the user to change it. Copy, Past, Add, … .
There is a simple, defined interface for operations on these values, and that’s it.

As an extension of the idea of context-sensitive values, it would be easier to create those kind of values first. This would be similar to the preview node. But it would allow you to enter arbitrary values in the random instances of the group in the modifier. I’ve been thinking about it and it looks like a very fragile concept (questions above).

3 Likes

You bring up so many different topics that it is hard to know what you main point is. I’ll try to answer the important thing:

The values that are controlled by a gizmo can be stored in three different places in this proposal:

  1. The value of an input node, e.g. the “Value” node.
  2. An input socket of a group node.
  3. An input value in the geometry nodes modifier.

There is no new special behavior with respect to copying.

1 Like

Interesting proposal. Indeed the proposal from the workshop had the same issues. I have some comments that apply to both cases:

  • The socket should be visibly different (an arrow point left?).
  • The property which is “driven” by the Gizmo could also get a special color to match the Gizmo node color.

So, the main different here is that instead of treating the node as a special pass-through, we make it more close to the Viewer node. I think that can work.

3 Likes

In other words, this design implies the task of creating a new socket class. These are sockets that duplicate all previously existing math types (most of them, not just gizmo float).
And at the same time they have a reverse principle of flow (yes, the value goes as before. But the possession of the value reversely rises).
This already sounds like a complicated topic. And it most likely has a bunch of problems (didn’t try to reflect on this much. The simplest example is interaction with all the old nodes and their number of connections to output sockets (what would it mean to be able to do this?)):

  1. Default value flow:
    image
  2. Gizmo value flow:
    image
  3. Combination? Quantum mathematics?
    image

It’s a little hard to understand those diagrams. But I think it’s better to think of gizmo nodes in this design as just UI helper nodes that can be attached to values to give control to them in the viewport. Yes, that means the links between the values and the gizmo nodes aren’t real data-flow (so they should probably be drawn differently to make the distinction clear). But I don’t think that makes the design wrong.

2 Likes

Exactly.

The problem is that this function is meant to be implemented as links between nodes.
And here, we either create a new class of nodes, yes this.
Or we say: the result of the math addition node can be connected to 2 other nodes.
If both nodes are gizmo nodes (we invers additional value to ui). Then we attach UI to the gizmo… number 1 or 2?