Previous topicNext topic

ISF program - problem with PASSES

Questions, comments, feedback, etc.
Post Reply
Psyne
Posts: 9
Joined: Tue Jun 06, 2017 1:11 am

ISF program - problem with PASSES

Post by Psyne »

I've been experimenting with ISF programming, and have run into a problem with a simple ISF fragment shader I was using to test persistent buffers. The program is supposed to allow a frame to be captured, strobing the captured frame instead of the current frame every 1/2 sec. My program:

Code: Select all

/*{
	"CREDIT": "Psyne",
	"ISFVSN": "2.0",
	"DESCRIPTION": "Strobes captured material every 1/2 second",
	"CATEGORIES": [
		"filter"
	],
	"INPUTS": [
		{
			"NAME": "inputImage",
			"TYPE": "image"
		},
		{
			"NAME": "capture",
			"TYPE": "event"
		}
	],
	"PASSES": [
		{
			"TARGET": "captureImage",
			"PERSISTENT": true
		}
	]
}*/

void main() {
	vec4 inputPixel = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord);
	if (capture == true || FRAMEINDEX == 0)
		gl_FragColor = inputPixel;
	else if (PASSINDEX == 1)
		gl_FragColor = (fract(TIME) < 0.5) ? inputPixel : IMG_NORM_PIXEL(captureImage, isf_FragNormCoord);
	else
		discard;
}

At present the effect just displays the last frame captured by the "capture" event. What am I missing here?
Magic
Site Admin
Posts: 3684
Joined: Wed Apr 09, 2014 9:28 pm

Re: ISF program

Post by Magic »

Just a quick thought, have you looked at the ISF Freeze Frame effect? It works similarly to what you're doing.
Psyne
Posts: 9
Joined: Tue Jun 06, 2017 1:11 am

Re: ISF program

Post by Psyne »

Nope - only the tutorials available on the ISF spec website. I'll have a look at that after work, and see if it helps illuminate my problem. Thanks!
Psyne
Posts: 9
Joined: Tue Jun 06, 2017 1:11 am

Re: ISF program

Post by Psyne »

Pointing me toward MMV's standard ISFs was definitely the way to go!

I've managed to deduce my problem after examining the Gaussian Blur ISF. Revised, working code below with problem details afterward.

Code: Select all

    /*{
       "CREDIT": "Psyne",
       "ISFVSN": "2.0",
       "DESCRIPTION": "Strobes captured material at the specified frequency and duty cycle",
       "CATEGORIES": [
          "filter"
       ],
       "INPUTS": [
          {
             "NAME": "inputImage",
             "TYPE": "image"
          },
          {
             "NAME": "capture",
             "TYPE": "event"
          },
          {
             "NAME": "frequency",
             "TYPE": "float",
             "MAX": 30.0
          },
          {
             "NAME": "dutyCycle",
             "TYPE": "float"
          }
       ],
       "PASSES": [
          {
             "TARGET": "captureImage",
             "PERSISTENT": true,
             "DESCRIPTION": "Pass 0"
          },
          {
          	"TARGET": "outImage",
            "DESCRIPTION": "Pass 1"
          }
       ]
    }*/

    void main() {
        if (capture) {
            gl_FragColor = IMG_THIS_PIXEL(inputImage);
        }
        else if (PASSINDEX == 0) {
            gl_FragColor = IMG_THIS_PIXEL(captureImage);
        }
       	else if (PASSINDEX == 1) {
          	gl_FragColor = fract(TIME * frequency) < dutyCycle ? IMG_THIS_PIXEL(captureImage) : IMG_THIS_PIXEL(inputImage);
       	}
    }
My mistake was in an assumption about how the PASSES array is used. If no PASSES array is specified there is one "output pass" to render the output of the shader. The second a PASSES array is specified, however, the output of the last pass is used; if you specify only one pass in PASSES, there is no "output pass" that follows those defined in the array. I assume this is mainly to allow the output pass to be persistent, differently sized, etc. without requiring the creation of an additional buffer if none is needed. Adding a second, non-persistent pass to render output was all that I needed to do (past a bit of cleanup).
Post Reply