How to use switch case statements?


I’m wondering if I can use switch-case statements with ISF? For example, if I write:

switch (PASSINDEX){
	case 0:
		gl_FragColor = frameDependentBuffer(coolPixel, fps, 0);

I get the following error:

ERROR: 0:227: ‘switch’ : Reserved word.

Thanks in advance – I’m trying to create an effect similar to the Jones Frame Buffer, but grappling with persistent buffers, TIME, and basically anything that doesn’t change with every frame render.





So, originally ISF was written against GLSL v1.2 / OpenGL 2, which as far as I understand, does not support using ‘switch’

However, we have with the latest ISF Editor beta releases added an option in the preferences that will let you write shaders for OpenGL 4, and if you do this, you can use switch statements.

VDMX currently is using OpenGL 2, so you wouldn’t be able to use those shaders in there, but some of the new plugins we are working on based off our new codebase will be able to work with both versions.

Generally speaking when it comes to breaking things up by the render passes, you might be best off doing something like this, which is functionally the same.

if (PASSINDEX==0)   {
else  {

Note that Freeze Frame FX might be a good starting point for something that does a basic one pass frame buffer,

and that FRAMEINDEX is used for the frame counter (always incrementing by 1), whereas PASSINDEX refers to the current pass within the current rendering frame; for single pass shaders, PASSINDEX is always 0, for multi-pass shaders the PASSINDEX will go from 0 to N-1 before the FRAMEINDEX is incremented – hope that makes sense!

And PS, here was one of my attempts to do a Dave Jones colorizer, though not quite as fancy as the original,



Thanks for the clarification David! I had written out a bunch of if/else if statements but was trying to tidy it up a little.

Regarding the behavior of FRAMEINDEX and PASSINDEX, if a shader has 10 passes, PASSINDEX will increment by one for each pass, from 0 to 9, after which point the FRAMEINDEX will increment by one? Does FRAMEINDEX ever “max out” or roll over back to 0?

I guess I’m wondering if there is any way to have the contents of a buffer persist after FRAMEINDEX is incremented? With Dave Jones’ frame buffer, for example, it appears that for a 30fps input video signal, frames 1-30 of the signal are written to their own spaces in memory, and then recalled exactly 30 frames later. So whatever was written into, say, FrameMemory1 gets recalled/potentially updated on frames 1, 31, 61, etc.

Dig the colorizer! That brings up another interesting point I’m trying to wrap my head around – is it possible to have multiple image inputs to a shader? One of the things I like about Dave’s frame buffer is the ability to use an external key source to determine which portion of the incoming video should be “saved” to the buffer. But, it seems like a shader only operates on one image and outputs one image. (I’m pretty new to this stuff, I’m definitely more of an analog/electronic person!)



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,

“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.



Thanks David! I had noted those details in the spec, but the translation from reading about FRAMEINDEX/TIME/PASSINDEX to their implementation was rocky for me :^) I’m used to thinking in terms of analog video circuits; it’s been fun translating ideas into shader land!

Thanks for the pointers on the other shaders, MicroBuffer and Layer Mask – I’ll be sure to check them out. If not designed with GLSL/ISF, do you have other recommendations for frame buffer effects? I have the Signal Culture Frame Buffer app as well, although my wimpy Macbook Air nearly explodes when running it alongside VDMX.



Yeahhhh maybe your best bet is to play around in Quartz Composer and check out the Sampler plugin from Bangnoise.



Thanks for the tip, I started tinkering with the Sampler plugin you linked to.

I was able to run the included Structure Sampler example just fine, but loading the Video Sampler caused QC to abruptly crash. My Quartz Composer is Version 4.6.2 (156), Framework Version 5.1 (370). (I have Xcode 10.1 installed, as it appeared to be the most recent, compatible version with my OS, Version 10.14.1)

I modified the working Structure Sampler example by including a __video argument in the function written in the Javascript block. I then connected the block’s Structure output to the Sampler input, causing the same abrupt crash. I sent an email to the author if he had a recommendation on a QC version that plays nice with video.

Either way, I’m excited about the possibilities of writing FX and plugins with QC! I feel like I’m learning a lot more about VDMX by playing around with QC/ISF. :^)