Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does TwoPassFilter GPUImage actually do?

I am trying to re-create the GPUImageTwoPassFilter from GPUImage(ios) for Android. I am working off the work done here for an Android Port of GPUImage. The port actually works great for many of the filters. I have ported over many of the shaders, basically line for line with great success.

The problem is that to port some of the filters, you have to extend from the GPUImageTwoPassFilter from GPUImage, which the Author of the android version didn't implement yet. I want to take a stab at writing it, but unfortunately the iOS version is very undocumented so I'm not really sure what the TwoPass filter is supposed to do.

Does anyone have any tips for going about this? I have a limited knowledge of openGL, but very good knowledge of Android and iOS. Im definitely looking for a very psudocode description here

like image 800
Jameo Avatar asked Feb 05 '13 17:02

Jameo


1 Answers

I guess I need to explain my thinking here.

As the name indicates, rather than just applying a single operation to an input image, this runs two passes of shaders against that image, one after the other. This is needed for operations like Gaussian blurs, where I use a separable kernel to perform one vertical blur pass and then a horizontal one (cuts down texture reads from 81 to 18 on a 9-hit blur). I also use it to reduce images to their luminance component for edge detection, although I recently made the filters detect if they were receiving monochrome content to make that optional.

Therefore, this extends the base GPUImageFilter to use two framebuffers and two shader programs instead of just one of each. In the first pass, rendering happens just like it would with a standard GPUImageFilter. However, at the end of that, instead of sending the resulting texture to the next filter in the chain, that texture is taken in as input for a second render pass. The filter switches to the second shader program and runs that against the first output texture to produce a second output texture, which is finally passed on as the output from this filter.

The filter overrides only the methods of GPUImageFilter required to do this. One tricky thing to watch out for is the fact that I correct for the rotation of the input image in the first stage of the filter, but the second stage needs to not rotate the image again. That's why there's a difference in texture coordinates used for the first and second stages. Also, filters like the blurs that sample in a single direction may need to have their sampling inputs flipped depending on whether the first stage is rotating the image or not.

There are also some memory optimization and shader caching things in there, but you can safely ignore those when porting this to Android.

like image 190
Brad Larson Avatar answered Sep 28 '22 05:09

Brad Larson