Skip to content

Commit

Permalink
Adding Evaluate Context section
Browse files Browse the repository at this point in the history
Add a new section to the NGE main page about Evaluating Context with examples for content and perf. Also update the Evaluate Context descriptions for each node in the nodes doc.
  • Loading branch information
PatrickRyanMS committed Nov 8, 2023
1 parent d3e27b9 commit 29d43a7
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 14 deletions.
26 changes: 26 additions & 0 deletions content/toolsAndResources/nge.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,32 @@ When clicking on an empty portion of the graph, the parameters panel will displa

![Options for the graph color, grid, and zoom including save and load actions](/img/tools/nge/ngeOptions.jpg)

## Evaluating Context
Context is a new concept in our tool set introduced by Node Geometry. Context is used to describe the set of data which determines the geometry output at the current node in the graph. When reaching a node that requires context to output geometry in the graph, it evaluates each node that feeds it to determine the geometry to output. This is called **Evaluating context** which always happens at least once for each node that outputs geometry, though it is also possible to require that a node evaluates its context many times. There are times where it is desirable to output geometry once and pass the same geometry to each successive node. Additionally, it is also valid to require a node output unique geometry for each request made by connected nodes. To enable both scenarios, there is a property on all nodes that output geometry called **Evaluate context**. Enabling this property allows the node to pass unique geometry for each request by successive nodes while disabling it ensures the node only ever passes a single geometry to all requests for output.

In practice, we don't have to set this parameter on each node as the property defaults to enabled. This is because it is common in procedural mesh generation to want to produce a variety of similar - but not identical - instances of geometry. However disabling it on a node in a graph will effectively prevent context from being evaluated more than once on all preceding nodes. To illustrate this, consider the following graph and preview.

![Graph wired to create 4 boxes at random sizes and positions wired through a merge geometry node](/img/tools/nge/boxEvaluateContext.jpg)

This example shows that **Evaluate context** is enabled on the `Box` node, all four `Transform` nodes, and the `Merge` node. This means that each node will evaluate its context once for each request for output made by connected nodes. For the `Merge` and `Transform` nodes, context will be evaluated only once even though **Evaluate context** is enabled because each of these nodes is receiving only one request for output from connected nodes. The `Box` node is different in this case as it is receiving four requests for output, one from each `Transform` node. With **Evaluate context** enabled on the `Box` node it will evaluate its context four times, one for each request. Since there is a `Random` node connected to width, height, and depth of the `Box` node, the `Box` node will prompt the `Random` node to generate values four times, resulting in four randomly sized boxes in the preview. If we wanted the boxes to all be the same size, we would make one simple change as illustrated below.

![Graph wired to create 4 boxes at the same size in random positions wired through a merge geometry node](/img/tools/nge/boxNoEvaluateContext.jpg)

In this example, the `Box` node has **Evaluate context** disabled, which means that the `Box` node will only evaluate it's context once. While the `Random` node will still generate three different values for width, height, and depth, this is the only time that the nodes connected to the `Box` node will be considered in the graph. Even though there are four requests for output from the `Box` node, since it is only evaluating context once, it will pass the same output to all nodes requesting geometry from it.

### Performance and Evaluating Context
There are also times where **Evaluate context** should be disabled for performance reasons. If we consider the following graph which is just a slight change from the examples above, we have a `Box` node being instantiated on the vertices of a `Grid` node.

![Graph wired to create 50 boxes at the same size in in a 10 by 10 grid at random grid locations with evaluate context enabled taking 5 ms](/img/tools/nge/perfEvaluateContext.jpg)

The data feeding the `Box` node is static and sets the same values for width, height, and depth each time the box node is evaluated. In this case, the `Instantiate on vertices` node will loop through the 10 x 10 grid of vertices and instantiate a box on half of them randomly. This means that the `Box` node, with **Evaluate context** enabled will evaluate the float node feeding the box size and and generate a box 50 times. Even in this very simple example, we can see how that effect can be exponential as a graph gets more complex. In real terms, this graph takes 5 ms to build which can be seen on the `Geometry Output` node. This value will vary as there is some randomness in how long it takes to generate the instances being that it is randomly choosing vertices for instantiation, but this is still a good representation of the time this graph takes. Now let's see the difference if we disable **Evaluate context** on the `Box` node.

![Graph wired to create 50 boxes at the same size in in a 10 by 10 grid at random grid locations with evaluate context disabled taking 0.4 ms](/img/tools/nge/perfNoEvaluateContext.jpg)

In this case the `Box` node only evaluates its context once, the first time it is reached in the graph. The `Instantiate on vertices` node still makes 50 requests of the `Box` node, but each time the geometry passed is the one that was first generated and the `Box` node does no further calculation. With this one change we reduce the time to build this graph from 5 ms to 0.4 ms. Again, the time it takes to build the graph varies slightly, but will always build much faster when **Evaluate context** is disabled.

When creating a graph in node geometry, always determine if each node generating output geometry needs to evaluate its context more than once. There will be times when enabling or disabling this parameter will have no effect on the build time of the graph, but those times will be due to there only being one request for output from connected nodes. However, there can be a significant savings in build time if the data feeding a node is static and output from the node is requested multiple times. Remember that these nodes always default to evaluating their context so the performance from evaluating context will always be at its worst if this property is not intentionally managed when creating a graph. It is always best practice to consider where time can be saved by determining if a node needs to regenerate its output for each request, or if it only needs to compute its output once.

## Iterating and Debugging
When creating `NodeGeometry` in a scene, it can always be edited simply by launching the Node Geometry Editor with the `NodeGeometry` mesh selected in the inspector. The **Edit** button to launch the Node Geometry Editor can be found under the _Node Geometry_ section of the mesh properties which appears right after the _Transforms_ section.

Expand Down
Loading

0 comments on commit 29d43a7

Please sign in to comment.