Instancing

You might have noticed there is attribute called instances on most nodes. This attribute can be found in the inspector. Instances determine how many instances of a node exist in that node. For example; instead of making 100 Circle nodes you make one Circle node and set its instances to 100. Instancing can be a little daunting to get started with but it will quickly open up a whole new range of possibilities. 

Note that the article will get more complex as we go further down the rabbit hole. You don’t need to learn everything to get started. Doing the first example will get you started.

Now, before we start, make sure you know what terms like Boolean, Float4 and Shape2D mean. If those terms don’t ring a bell, no need to worry. Leave this page for a bit and read our article on Data Types.

By the end of this article you can easily make content like this.

Instances

The amount of instances can be set in the inspector. Because instances are more or less copies of the node, the amount of instances can’t be a negative number. We can’t have -4 apples in our hand can we?

The Attack Release node is set to 10 instances in the inspector.

After you have set the amount of instances the output of the node will change. If the node produces data like a Float 2, Boolean or Trigger it will now output a collection of values, these are called arrays. If the node produces Textures or Shapes it will simply output that data type times the amount of instances.

An instanced node can be easily recognized. When you click on the node, the amount of instances will be displayed next to its main outlet. An instanced connection can be recognized by its dashed connection wire. 

A preview of the values and a dashed line, indicating that the connection is instanced.


Example A - Circle Pattern

In this example you’ll be creating a circle of circles by using the Circle Pattern node. This is a node that will produce a Float 2 array with coordinates for a perfect circle.

  1. Create a Circle node and set the instances to 50 in the inspector.
  2. Create a Transform node and connect the Circle outlet to the Transform main inlet. Notice that the Transform node automatically becomes instanced too.
  3. Create a Circle Pattern node and connect it to the translation input of the Transform node. The Circle Pattern node can’t be instanced because it already produces an array by default.
  4. You’ve done it! Good job! Now try some other nodes that produce arrays like the Linear and Grid Pattern. Experiment with larger amounts of instances and try modulating some parameters with oscillators.

Limitations

Unfortunately there is a limit to all that power. Every instance you make will be calculated by your computer, so working with hundreds of instances can be taxing on your machine.

While it is possible to use instances of textures, we generally recommend against it. Playing back 10 instances of the same video file is still the same as playing back 10 video files at the same time.

This patch has 200 instances of circle, 200 oscillators, two linear nodes with size 200 and has a feedback loop with delay. This is running 60fps at 1080p on a modern notebook with a NVIDIA GeForce GTX 1650 Ti.


Arrays

An array is a collection of values that comes from an instanced node. Arrays contains values like Boolean, Float or Integers. Arrays of Triggers are also possible. Each value in the array has a position, known as an index. Indices always start from 0. Remember this well, because you will make a lot of mistakes by starting to count from 1 instead of 0.

If you’ve made Example A you will already have made some arrays. Nodes like Sequence, Linear and Circle Pattern will always output an array. You can also create arrays by instancing nodes that produce values. 

Creating a Float node set to 10 with 10 instances will create an array filled with 10’s. 

Creating a Random node with 10 instances will create an array with 10 random values.

Creating a Sine Oscillator with 10 instances will create an array of 10 values that are constantly changing. These values will all be the same, but you can change by applying an array to the Phase Offset. We'll be doing this in Example B.


Example B - Wave Making

Now that you understand the basics of arrays we’ll put these skills into practice by animating our circles in a wave-like motion.

  1. Create a Circle node and set it to 100 instances and its radius to 0.1 then create a Transform node and patch the Circle into the Transform.
  2. Create a Linear node. Rename it to Linear X and set its min and max value to -1.5 and 1.5. Set the size to 100.
  3. Create a Pack node. Patch Linear X into the Pack’s X-inlet. Now patch the Pack into the translation inlet on the Transform node. As you can see, the circles are distributed evenly over the X axis.

  1. Create a Sine node and set its instances to 100 and patch it into the Pack’s Y-inlet.
  2. Create another Linear node with size 100 and keep the default min/max. Patch this into the phase offset inlet on the Sine node.
  3. Damn son! You’re making waves out here! Now Start experimenting by patching Linear nodes into other parameters. You can even modulate the min and max parameter to get extra funky. Also try adding some color by using the Shape Render and Gradient Palette nodes. You are now advanced enough to figure these out yourself.

Multi Editor

Before we go into fancy ways to manipulate the arrays we’ll first do some old fashioned manual labor with the Multi Editor. The Multi Editor is a tool to edit collections manually. Once you’ve instanced a node it becomes available in the inspector. The Multi Editor can be recognized by the symbol with three horizontal stripes on the right side of the value you want to edit.


The Multi Editor can be used to create arrays that would be difficult to achieve with nodes like Linear. In the example below we’ve used the Multi Editor to manually set the radii of the the three circles.

You can also hold CTRL and click on an instanced value to directly edit it from the canvas.  Only use this feature if you are ready to look like a real pro in front of your friends.

Some serious CTRL + Click mastery is going on here.


Manipulating Arrays

Well young padawan you have come a long way from your humble beginnings. You are now ready to start manipulating arrays. You can change values in an array, sort it, shuffle it, shrink it or expand it. This part will be about specific nodes that do this. If you are interested in doing math with arrays you can skip to Array Math.

Reading

There are two nodes that read values from an array: Read and Span.

Read will output the value at the given index. If you have an array running from 1 to 10 and you read out index 5 you will get a 6 (remember that arrays start at 0 ?). In the inspector you can set the index to wrap or clamp depending on your needs. It is also possible to feed the Read node an array for its index inlet. This way you can read out multiple values (the Sequence node is a good candidate to go into the index inlet).

Span will output a part of your array as an array. You can use this if you have an array of 100 values but you only need indices 50 to 60 for example.

Writing

We have three nodes that write to an array or expand its size: Write, Insert and Expand

Write will write a value to the given index. You can use this to adjust a single value in the array. This can also be used to modulate one value in the array. You could cycle through the array by connecting an oscillator to the Index input of the Write node. Add a Smooth node to the output of the array to create one-instance-at-a-time animation.

Writing -1 to index 5

You can also use an array as value and index to write to multiple positions. In the image below we generate and array with a size of 10 using the Float node. This sets all the values in the array to 0. Next we use the Sequence node to generate an array containing [3 , 4 , 5 , 6]. These are the indices we want to write to. Lastly we use a Linear node with a size of 4 to generate the values we want to write.

[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] becomes [0 , 0 , 0 , -0.5 , -0.17 , 0.17 , 0.5 , 0 , 0 , 0]

Writing the Linear array to indices 4, 5, 6 and 7 of the Float array.


Insert

The Insert node is an alternative to the Write node that, in addition to writing new values, also expands the node. The new values are inserted to the array, increasing its size. 

It is possible to insert a single value or insert an array at the given index. In the image below you can see how two Linear(5) nodes are inserted, creating an array with 10 instances.

Using Insert to combine two Linear nodes with 5 instances into an array with 10  indices.


Expand

Expand is a very interesting node that “grows” an array with three different wrapping algorithms. This node takes a value or an array and expands it to the desired size. This can be a great tool for generating gradients or patterns. Expanding with the ping pong wrapping (set in the inspector) is a quick way to add a reverse of the array to your array

Repeat [1 , 2 , 3] > [1 , 2 , 3 , 1, 2, 3]
Ping Pong [1 , 2 , 3] > [1 , 2 , 3 , 3 , 2 , 1]
Clamp [1 , 2 , 3] > [1 , 2 , 3 , 3 , 3 , 3]

Expanding the Linear array with 3 instances into an array with 10 instances using the Expand node.

Buffer, Ringbuffer and Stack

These nodes get a special mention as both have unique ways to create arrays.

The Buffer node will take inputs until it is full and then output its values as an array. The Ringbuffer node is more like a waiting line: it fills up and then it is first one in is first one out.
The Stack node works like a stack of number where on every trigger you put a number on top. The pop function allows you to remove the top of the stack.

Example C -  Mirror Movement

Alrighty, you’re becoming a serious Instancing-Pro aren’t ya? In this example we’ll use some of the nodes we were just discussing to make a mirror movement pattern and a funky gradient.

  1. Create a Circle node and set it to 10 instances, set its radius to 0.15. Next, create a Transform node and patch the Circles into the Transform.
  2. Create a Linear node and set its min and max value to -1.5 and 1.5. Set the size to 10. Now make a Pack node, patch the Linear into the X and the output of the Pack into the translation inlet on the Transform.
  3. Create a Float node, leave it at 0 and set its instances to 10. This will create an array of 10 values all set to 0. This will be our base height.
  4. Create a Write node, patch the Float into it and set the value to 1. Patch the Write into the Y of the Pack. Now play with the Index parameter on the Write node. Your circles should pop up one at a time.
  5. Let’s smooth the popping. Place a Smooth node between the Pack and Transform. This will smooth the transition from 0 to 1 and give a more animated feel.
  6. Create a Sine node with the amplitude set to 10 (because we have 10 positions in the array). Set its instances to 2. Patch it into the index parameter of the Write node.
  7. Lastly, create a Linear node with min 0 and max 0.5. Set the size to 2 in the inspector and patch it into the phase offset of the Sine.
  8. Create a Shape Render and patch the output of the Transform into it.
  9. Create Gradient Palette and pick two funky colors. Set it to either 2 or 5 instances.
  10. Create an Expand node. Set its mode to PingPong. Patch the Gradient Palette into the Expand node and the Expand node into the material inlet of the Shape Render node.
  11. Well done!  Now try to use the Mirror and Repeat nodes to make a complex pattern. Or maybe… add some feedback and delay.


Sorting

At some point you might want to sort your arrays out. Clean those messy arrays up boy! We have a few nodes that handle sorting as well as doing the reverse for all you chaos-loving folk out there. You might also want to get values like the lowest value in an array or the average value in an array. We’ll touch on those later.

Reverse & Sort

The reverse node will do just that, reverse your array.

The sort node will sort your array in either ascending or descending order. The order can be set in the inspector.

Shuffle

The shuffle node will shuffle your array around and make a proper mess of it. Trigger the reshuffle inlet to shuffle the array around some more. Duplicates are off by default but after you turn it on the array might contain duplicates. Who knows? 

Shift

The shift node can be used to move the values in the array around. All values will be shifted to new positions in relation to the offset parameter.

Blue = Linear. Purple = Reverse. Red = Shuffle.


Array Math

Doing math with arrays can be a little confusing so we’ll try to keep it short and simple. 

You can do math operations(addition, division etc) with two arrays of the same size or an array and a single value.

Let's take addition as an example. If you use the Add node to add up two arrays, each value in array A is added to the value in array B with the same index. Index 0 in array A is added to Index 0 in array B. This results in:

[1 , 2 , 3 ] + [5 , 6 , 7] = [6 , 8 , 10]

When using a single value, the operation is done with all positions.

[10] + [1 , 2 , 3 ] = [11 , 12 , 13]

Note that you can’t set the instances for many math nodes. This will be done dynamically as you patch. No need to worry about it.

Top Result: 0.1 added to the Linear array. Bottom Result: An array of 10 random values added to Linear array.

Array Logic

Array logic operations are done in a similar way as the math operations. You can compare either two arrays of equal size or the whole array with a single value. No need to set the instance count on the logic nodes, we’re handling that under the hood. Using logic operations with arrays will result in a boolean array filled with trues and falses.

Related Articles