duplicating processes - iterations

Hey guys,

I’ve created something which I want to duplicate around 50 times and was wondering whats the best way of doing it?
I made a composition of a circle which floats across the screen going up and down as it moves along. I then added a number of random properties to it which affect things like the speed, the position, how fast and how much it moves up and down etc.

The idea here was so I could just duplicate this set of nodes over and over to get the effect I want. It works and I can do this, but as you can imagine the project gets very heavy and big


lol

I’m sure there must be a nicer way of doing this, if anyone has any suggestions I’m all ears.
If people want to have a look at what one element looks like here it is. I’ll also attach the vuo comp but you’ll need to reference some images in the List Files.

Thanks
M

Circles.vuo (7.66 KB)

Hi @marioepsley

I think it will likely depend on what kind of control you will wanna have over the copies.
Can you elaborate ? If you want 50 copies of that same emoji ? Or you wanna load a list of different emojis / images and display them and have them move randomly across the screen at different positions / speeds ?  

Hi again ;)

So if I’m right, basically want you want is an iteration of this animation.
Somehow it’s a little bit related to your previous question Building and processing lists? because technically it’s about moving copies of objects at different positions / speeds / rotations.

I assume you don’t want a strict copy of that animation, you could indeed copy it 50x but then it would be on top of each other and make no sense.
So I assume you want to have some control over variations.

And right now in my opinion that’s where Vuo is a little tricky so far, will be way easier in the future when those 2 related Features Requests will be implemented : Iteration: Turn most nodes into iterators by allowing single-value ports to accept lists & Particle emitter node

Right now I see indeed several methods, more or less complicated.

a - You could use Satoshi’s custom Particle Emitter node, it’s great, but for me it has a bug, it first spews a first group of particles before releasing them over time.

b - You could use Parabox custom nodes, the Get Mesh Values one and retrieve points for example from a rotating sphere and use those coordinates to copy your icons with some variations in positions / speed.

c - You could try to build a particle emitter composition with the stock nodes using a camera that would move away from the new layers on top, creating the illusion.

d - Or d, use a mix between the method given you by @jstrecker and that composition you found using Calculate List and Calculate and building a list your images using Build List and iterate some variations with math expressions. I have given it a try but I’m definitely not a mathematical expression type of guy so it’s really just a start, some way more talented folks could probably help you more here to create a particle list using math expressions !
Joining my attempt.

Cheers

Move Images Randomly 1.0 - Composition.png

Move Images Randomly 1.0 - Window.png  

Move Images Randomly 1.0.zip (467 KB)

Or here is a version using Tile 3D Object, a method I got from @jstrecker in another question.

However with this method you get a Nokia Snake effect, icons disappearing at one end of the screen re-apparear at the other side. Unless there is a way to avoid that by changing the Tile 3D object node values. But I don’t know how.

The y-position wave effect on the icons is still achieved via the math expression I got from @jstrecker too.  

Move Images Randomly 1.3.zip (467 KB)

This is so interesting, 2 quite different ways with the same results. This is exactly what I was after by the way. Sorry it’s taken me a while I wanted to have a proper look at these first.

Looking at both the comps I see the they’re mainly controlled through a few variables and expressions, something I haven’t played with much yet but would love to learn.

If you wouldn’t mind I’m struggling to understand exactly whats going on here. The blue. I see you’re making a list of xyz coordinates that’s controlling the objects translations. You’ve got values going into the X (moving it across screen) and values in the Y.

It’s the expressions that I’m struggling with.
GOING INTO THE X - I see you’ve made a variable for the speed which really controls time. Then you’ve got the expression time(index-1)*. The index is the build item, but why -1?

GOING INTO THE Y - You’ve made a random value list which is where it sits vertically on screen, then I get a bit lost, *X+perlin2d(timespeed,Xscale)amount. Would you mind explaining it a little further, once I get the principle I should be able to run on my own ;)

I’m starting to understand the power of lists now, definitely looking forward to those 2 feature requests though. Thanks to everyone on this forum by the way, you’re all awesome! M.

@marioepsley no sorry I can’t explain more.
As I said I’m not a math expression guy, so just like you I more or less understand the why and how but I grabbed those from answers from Jaymie and the example you found and some sample composition linked to the Calculate List node if I’m right and just play with the parameters until I get something a little satisfying ;)
From your screenshot I see you opened the first version of the composition, I had then uploaded version 1.3 using simplex noise instead of perlin and some tweaks and think the icons move more independently.

I’d love to know more about those too. If somebody know a link on the web about these or wanna make a tutorial with some examples it would be cool.

GOING INTO THE X

With time*(index-1), it’s taking the input time and spreading it out so that the 1st item ends up with time*0; the 2nd item, time*1; the 3rd item, time*2; and so on. Actually, taking off the -1 might be better. With time*(index-1), the 1st item always sits at an x-position of 1.2, offscreen. If you change it to time*index, the 1st item slowly moves to the left over time. (This is easier to see if you temporarily change Curve : Start Position to 0.9 so it’s onscreen.)

GOING INTO THE Y

X+perlin2d(time*speed,X*scale)*amount — OK, let’s break it down.

Each image is assigned a different randomly chosen value between -1 and 1 when the composition starts. That’s X.

The X+… part of the expression offsets the image vertically. So, rather than being clustered near the middle, the images are spread out vertically.

The perlin2d function takes 2 inputs. We’re using the first one to make the image move up and down over time. time makes that happen, and speed is just a parameter that you can change if you want the movement to be faster or slower.

We’re using the perlin2d function’s second input to make each image follow a different path, instead of all moving up and down in unison. The unique X of each image makes that happen. scale is another parameter that you can change or not. If you make scale closer to 0, the images are closer to being in unison.

The last part of the expression — …*amount — is yet another parameter. It controls the vertical range of movement for the images.


@Bodysoulspirit — great answers! :)

One small suggestion (sorry if I messed this up in my original composition) — to keep extra events from going into the Build List loop and possibly messing up its count, there should be a Hold Value between Change Speed and Calculate.

2 Likes

@jstrecker thanks for the expression explanation and the hold value tip again ;) !

1 Like

Jaymie (@jstrecker) Very helpful explanation, thanks a lot for this, I feel like I’ve got some new toys to play with ;)

1 Like

I hadn’t quite realized that there was sub composition support that is as robust as it is until recently.

But this got me thinking - isn’t that most of what is needed to create an iterator type scenario? What happens if a subcomposition is setup to load itself? Or if a sub composition is fed a structure which then causes it to load itself X amount of times?

I haven’t tested what happens now, but if it doesn’t just work, it seems like some sort of loop could be added to whatever part of the code loads compositions up as nodes, and then get iterator like behavior? I’m sure it’s more difficult than just that, but it got me thinking about that being the basis of an approach.

Yep, that is basically the plan for Iteration: Turn most nodes into iterators by allowing single-value ports to accept lists — a single node on the canvas gets executed repeatedly, as if there were multiple instances of the node.

Recursion, as in a subcomposition loading itself, would theoretically be another way to implement iteration, but (mathematicians and Haskell programmers aside) loop/foreach style iteration generally seems more approachable.

I hesitated to talk about this point, because I didn’t want to get too off topic, but it does tie in with your point.

Macros in QC were great, and I think that in earlier thoughts about the VUO system and the problems of QC, that the judgement that macros are wonky was not well considered in context of the workflow benefits. I think the macro-esque implementation of an iterator was very handy from a workflow perspective.

Relatedly, If I am stringing together a multistage fluid simulation in VUO, and I’m trying to do it with either the ShaderToy node, or the GLSL node from parabox, it is astounding how many nodes have to be laid out on just one level of a composition. For me, it becomes difficult to actually make the compositions, without being able to section stuff away in a Macro.

Think about if you had a Render in Image patch in QC, a GLSL shader, a grid, and then need to feed it with typical values. You’ll soon have all of that stuff that would be inside the Render In Image patch in QC, all on one level. You’ll also have a bunch of extra “build point” type stuff, more than likely.

So it was GREAT to see that subcompositions work the way they do, but it’s pretty hard to work that way because the debugging gets difficult. If only one could just “click” and get into it, the way that macros worked.

I often find myself almost having to lay things out in QC first, because if I didn’t, it would be impossible to get the composition worked out to start with, between debugging shaders without code highlighting for errors, and without macros.

Come to think of it, since I updated to High Sierra, specific shader bugs no longer even print to Console. It just gives a sort of generic line that references VUO, without the info it used to give.  

1 Like

I’m hopeful that you’ll see the changes to subcompositions and shaders coming in Vuo 1.3 as an improvement. They address some of your concerns, including debugging inside of subcompositions and error reporting for shaders.

Agree 100% with much of what George said. (I don’t code shaders though)

Macros are desperately needed in Vuo IMHO because the canvas (for me) becomes bloated quickly. Way to much time is spent rearranging the nodes to make more space and arrange nodes in coherent ways. Canvases get a bit ugly quite quickly and it takes time tidy up. Sometimes I’m loathed to share a comp because it looks so messy and may be hard for another person to follow (attempted) my code logic.

Part of this is because one of the strengths of Vuo is the native datatypes, but to change one or more values in a multivalued datatype, say a 4D point or List, one needs to break out the datatype value into components, alter one or more of them and recombine back into the native datatype. Sometimes I find myself wishing that I could perform a Calculate Node on a multi-value datatype (say a 3D point) inside a single Calculate node using multiple expressions each outputting a component of the final datatype. (I’ll think some more on a practical implementation method and FR it maybe you’d need to be able to select the input datatype and the output datatype I think to make it really useful, a 2D Point might get processed into a Tuple (a Text String paired with a 2D point say)). I could see myself using that node A lot if it was more powerful in that way, so much easier to construct than the Process List setup.

Another thing I just wanted to do with Calculate List was get the value using the neighbouring value, so take the Y value from (Index +1) and perform a calculation with it and add to Y at current Index. This cannot be done, it requires a Process List loop and Value at Index patches to pull the two values from neighbouring values in the list.

Sub-comp debugging and editing is for me quite impractical, so ATM doesn’t substitute as a kind of poor mans Macros/Group node.

I think the three types of sub-composition are Group Node | QC Macro, Local Sub composition from library (edit once deploy many times in local comp) & universal sub composition from Library (current implementation needing debugging improvements) are all FRs and known to Team Vuo, right @jstrecker? Group Nodes FR is here LINK

Recursion would be amazing for sub comps but would we maybe need new “cons” structured lists like get used in FP so anybody could iterate through any list using recursion in sub comps, I guess.

Imagine if it was combined with sub-comp lambda outputs from nodes (once dreamed about for pre-alpha Vuo I think)… we could make our own powerful function factories like in Haskell that can operate on lists or custom datatypes by reusing simpler functions that work on complex and native datatypes (would they go inside each other or in-line on the same level?).  

Some relevant feature requests:

2 Likes