To best clarify, you can read the details about these variables in the full spec.
FRAMEINDEX, like TIME, always goes up – it only resets when you restart / reload the composition.
PASSINDEX resets every time a frame is rendered. If you are rendering at 60 fps, this goes from 0 to N-1 60 times per second.
Individual passes can be set to be persistent so that they are retained between frame renders, this is how the Freeze Frame filter I linked to works. For example,
“PASSES”: [
{
“TARGET”: “freezeBuffer”,
“persistent”: true
}
]
Note that persistent passes need to have a target name (use this to refer to the image when getting pixels) and the persistent flag set to true.
As a general performance tip, you generally don’t want to have too many passes, especially if they are persistent. I strongly suggest keeping the number of passes to a minimum, but there are certainly cases where you can do some clever things with multi-passes, like the our deep blur examples.
There is a shader called ‘MicroBuffer.fs’ that does 10 passes, with the intent of buffering the last 9 frames, but while it works, it isn’t a particularly good way to do frame buffering because each buffer has to be copied from one slot to the next, which adds a lot of extra overhead. For the kind of buffering you are talking about, GLSL / ISF probably isn’t the ideal route, though you could perhaps hack something together.
And yes, shaders can have multiple image inputs, the Layer Mask is a classic example of that, but there are others.