Context Input Nodes [Proposal]

This document is based on parts of this blog post. There is a work-in-progress PR.

Problems

The goal of this proposal is to solve the following problems:

  • We want to remove the need for control node groups as a way to get global input values (example). While this approach is useful in some setups, it doesn’t work all that well when building reusable node systems.
  • We have no good way to pass the hair system’s surface geometry to the relevant hair nodes in a good way.
  • We have no way to override existing contextual input nodes like Mouse Position, Active Camera and Scene Time. Being able to override tool inputs like mouse position and viewport transforms would be especially useful when we want to turn an edit mode operator into a modifier.
  • We need a more flexible replacement for the “Is Viewport” node, which is used to control a performance vs. quality trade-off. Just making this decision based on whether we’re rendering or not is not good enough. For example, sometimes the “fast” mode of a node group should be used in edit mode.

Abstract Problem

What all these issues have in common is that we want to pass information into nested node groups without having to set up all the intermediate links which would cause a lot of annoying boilerplate. Nevertheless, we want to be able to override all these inputs at any intermediate level.

Proposal

The proposed solution is the concept of “Context Inputs”. A context input is a group input that is automatically exposed on parent node groups as well, unless it is explicitly overridden.

Built-in Context Inputs

For example, in the image below, the node group uses a Scene Time node which outputs information retrieved from the current evaluation context. The group automatically gets new inputs in a “Context” panel that are derived automatically. They are also grayed out in the side bar because they aren’t editable. The Group node also shows the context input panel. By passing in a value for the “Seconds” input explicitly, one could overwrite it. By not passing in anything, the value will be retrieved from the context.

If the root node group has context inputs, those will also be shown in the modifier, where one can then also decide to either override the input.

If the same context input is used in a node group multiple times, it is deduplicated and only exposed to the parent once.

Custom Context Inputs

In addition to the built-in context inputs of which we have many already, we can also add support for custom contexts. For that, a new Context Input node is added.

Each custom context input has the following properties:

  • Data type: Type that is output from the node.
  • Identifier: Used for deduplicating multiple custom context inputs.
  • Name: User-friendly name for the context input that is shown in the UI.
  • Description: Tooltip used for group inputs.

If multiple context input nodes have the same identifier but different types, the “most complex” type is exposed if possible (e.g. vector is more complex than float). If the types are not compatible, there is an error. If the names or descriptions are different, the first found non-empty name or description is used. The order in which nodes are checked is deterministic but not defined.

These properties of context inputs are not input sockets because they need to be known statically; they affect the interface of the node group and might also affect the dependency graph.

Custom context inputs are also propagated all the way up to the modifier if they are not overridden in the node tree. The modifier then has three choices:

  • Provide a specific value for the context input.
  • Retrieve the context input from an even higher level context, e.g. custom properties of the object or scene.
  • Fall back to some default value. The design for default values is not entirely clear yet. For now it would just fall back to zero. The issue with storing a default value in the Context Input node is that those values can’t be deduplicated if they are different without potentially changing the evaluation result. Maybe there just needs to be an error if multiple different default values are provided for the same context input.

The video below shows how a custom default is propagated step by step all the way to a custom property on an object.

Relation to Group Input Defaults

There is a little bit of overlap with the Group Defaults node proposal. Context inputs are also inputs with special defaults.

There is also the question of whether all the context inputs have to be in the “Context” panel or if the node group author is allowed to interleave them with other inputs. For example, hair node groups often need access to the surface geometry. This can often be retrieved from context, but it still makes sense semantically to expose it as a normal input.

Currently, my stance on that is that all context inputs should be forced to stay in the separate panel which Blender manages automatically. However, the user can manually create a separate group input that uses the context value as default value. In the Group Defaults node proposal, that would mean that the Context Input is linked to the Group Defaults node.

16 Likes

Hello
This is very complex to understand. Personally I don’t get it.
I wanted to say:
I hope it won’t confuse new geometry node users even more. Geometry node is starting to get very intimidating, I hope it won’t get worse with time :fearful:

2 Likes

Those can be global variables basically. Read from objects or scenes.
They could be a huge convenience, because in the past Ive seen many nodetrees using external object transforms as ‘global variables’. I.e. the z coordinate of an objects location to drive a float value in the nodetree. works but it clutters scenes and nodetrees.

4 Likes

Then why not calling them object or scene properties? Blender already has a custom property system…

Even after rereading the topic I don’t understand how these are global properties, concept that I’m familiar with from Houdini

Contextual dataflow is great to see, especially if it’s implemented in a way where we can I/O the inputs, but I’m not sure how well this would work at-scale without some UX polish around namespaced properties. That polish wouldn’t be particularly complicated (if you’ve ever implemented path semantics for object storage identifiers, you’ve trod this ground before), but it would be important to funnel people into using namespaces from the get-go.

Proper hierarchical dataflow would be a challenge, given Blender’s (lack of) scene hierarchy, but it would be interesting to see context properties propagate down from (but probably not aggregate up to) collections. That would give layout artists a ton of options.

1 Like

You could do that, but this proposal combines both, scene and object. So the smallest common denominator leaves ‘context’. And since its only an input we get ‘Context Input’.
Ofc looking for better naming is absolutely valid! :slight_smile:

The context input node is taking these values from the custom properties you mentioned.
Its not replacing them, its reading them.

That was just a comparison to programming. They act like global variables.
If you put a custom property called ‘wind_strength’ in the scene properties you can access it from within every geometry nodetree.

You would need to set up the node like this:
• Float
• wind_strength (searching first in object props, if not found; Step one up to scene props)
• Wind Strength (Modifier UI Name, Needed for override functionality.)
• Description (Also for the Modifier UI)

I can see this especially useful with addons.

@jacqueslucke
Only two questions on my mind:

Could an ‘Exists’ output socket like in the named Attribute be included?

I can see this working very well with addons. But many addons save all their properties in one Python class/object.
Could this design also consider accessing those?
Through many outputs or even output bundles?

Hi There
I would’ve like to give some feedback on this proposal

Relation to Group Input Defaults

In relation to group default values.
This sort of design would do the job fine IMO

Edit*
it was proposed also here

Visually it makes a lot of sense, is more intuitive, than separate nodes :slight_smile:

We want to remove the need for control node groups as a way to get global input values (example). While this approach is useful in some setups, it doesn’t work all that well when building reusable node systems.

In othersofware, it’s relatively easy to define a global variable, and access it in a nodetree. Fortunately blender has a custom property system, if GeometryNode could access custom property, it could make things much more simpler.

Reference to custom property global variables could also be indicated as an overlay, and in the modifier interface :slight_smile:

2 Likes