Hello. I seem to have encountered what I think could be a bug: while connected to a DX11 renderer, subpatches are keeping latent processes running while Switched off. This can have a heavy performance toll on a live production patch like the one I’m preparing.
The first image show the issue in full. The second one shows a workaround, connecting a toggle function to the subpatche’s enable pin (and anything downstream, for that matter).
Do I misunderstand how the Switch node works? Seems cumbersome to have to disable everything in a patch when it’s switched off?..
Sorry. Here it goes. To clarify, I mean that subpatches are taking considerable processing effort even though they are switched off. As a workaround, I am disabling everything I can, but I was thinking there must be a leaner way to do this?
A switch doesn’t “know” what is connected to it and simply switches between the inputs. Evaluation of the subpatch has nothing to do with it and it shouldn’t, because in a lot of cases that’s not what you want.
If you switch to the input of a different subpatch that is not evaluating (ie. not doing any processing) you will get the wrong or no output from that subpatch for the first frame, so to have seamless switching you need to keep evaluating in the background.
Also there might be some S and R nodes in the subpatch that need to keep working, so its good that the behaviour you were expecting is not like that.
You can unhide the hidden evaluate pin on any subpatch by rightclicking on the square to the left in Herr Inspektor till it becomes dark grey.
You can then switch between the inputs and evaluate at the same time or even better use a frame delay to start evaluating a frame before switching.
I’ll explain a bit in details how the internals work.
A switch (Node) is internally like a link, so when you change the input value, the graph will only evaluate the parts where the input is active.
Other switches behave like :
If (all inputs are the same) : only evaluate the pin correspording to the input.
If (any inut number is different) : evaluate all upstream.
Now one thing when having a subpatch is that some nodes have an “auto evaluate” flag. So if a node has this flag on, it will evaluate regardless it is required downwards, unless it’s contained in a subpatch, and evaluate pin on this patch is down.
Most animation nodes (damper/linearfilter) do have that flag on, which explains why in the case above most subpatches have a reasonable evaluation time.
On a side note on the DirectX11 side, it behaves (almost) the same, but there’s no concept of autoevaluate, only visible windowed renderers start calls (or readback can also do if requested to do so).
So your patch might still evaluate (vvvv side), but in the screenshot above it will not render.
Please note in DirectX11 some nodes can do an early out.
Group (DX11), DynamicBuffer (DX11) will not update/render on anything upstream if enabled is toggled off, and will also cut down evaluation.
Normally when using reasonably large patches, and lot of scenes, here is more or less my workflow:
Create a subpatch for all resources (which allows me to preload all i need in background), and use S->R (Node) to use them in the patch where they needed.
Any dynamic buffer which will not change data, I bang once on start to update them, and use “Keep in memory” pin on to avoid them being deleted -> reupdated. Same for most filetextures.
Use one (or two if i need crossfade) Switch Node, for texture/layer output. In DX11 case you might prefer texture, since Renderer (TempTarget) uses a pool anyway, so it will not cost you more memory.
Evaluate pin off is handy, but can be quite dangerous, normally on startup we evaluate all for 5 seconds (so memory is allocated), then start to pick what we evaluate or not (generally it makes transitions much smoother, specially the first time you switch to a subpatch).
Avoid damper on large spreads, and try to have them as much up on the graph as possible, alternatively, you can use enable pin + s+h (value) just on top of the damper, but mostly you also want a low spread count on it.
Use as much dynamic buffers, since apply pin to false also cuts evaluate, and they allow you to batch, making your rendering much faster.
Thanks for clearing that up @vux, I see its not as simple as I thought :)
I am not using DX11 so much, or at least don’t understand it enough, but the other stuff makes sense and it seems I have used those principles already intuitively.
There is only one big part of my patch where I manually disable evaluation for some subpatches that build a maya file in realtime and I only need it to evaluate from just before writing the file, so I made something similar to that example above that would switch the subpatches on just before writing the file and turn evaluation back off after successful writing.
Could you explain though why an LFO inside a non-evaluating subpatch does not effectively pause the LFO? It doesn’t update the output but the LFO seems to continue to run?!