PHOBOSLAB

Blog Home

Fast Image Filters with WebGL

WebGLImageFilter is a small JavaScript library for applying a chain of filters to an image.

Filters:
Sergey Brin in his badass Tesla, sporting Chrome wheels

But to quote myself from twitter:

That awkward moment when you realize the lib you've been polishing for the past 6 hours already exists. With more features and a better API.

~ @phoboslab, Nov 3.

So, yes, there's already a library called glfx.js which basically does the same thing. And I'm almost saddened to say that it's excellent.

It's not all in vain, however. My implementation features raw convolution and color matrix filters. The latter should be particularly interesting for those coming from the Flash world: it's the exact same as Flash's ColorMatrixFilter and allows for some nice "Instagrammy" photo effects among others. There are some JavaScript libraries around that implement this ColorMatrixFilter, but they all do it in JavaScript directly, which is quite slow. Mine can be used in realtime, even on iOS with Ejecta.

I also learned some things about WebGL and Shaders with all this. One interesting aspect is that you can't draw a framebuffer texture onto itself. So in order to apply more than one effect for the same image, you need to juggle around 2 textures - use one as the source, the other one as the target and then switch. And if you don't want to waste any draw calls, you need to know which draw call will be the last, so that you can draw directly onto the target Canvas instead of on a framebuffer texture.

WebGL's coordinate system also complicates things a bit. It has the origin in the bottom left corner, instead of in the top left like most 2D APIs, essentially flipping everything on the Y axis. This has caused me a lot of pain with Ejecta already. The solution sounds trivial: just scale your drawing coordinates by -1, but this only gets you so far. If you need to get the pixel data of your image or draw one canvas into another, you suddenly have to invert everything again.

Lesson learned: Always google before you start working.

Download: WebGLImageFilter on github.

Sunday, November 3rd 2013

8 Comments:

#1gotofritz – Monday, November 4th 2013, 09:05

~hug~

#2Šime Vidas – Tuesday, November 5th 2013, 21:12

Would be interesting to see how well they perform on a Firefox OS phone.

#3Dominic – Thursday, November 21st 2013, 13:11

@Šime Vidas: works perfectly fine on my Keon.

#4Felipe Budinich – Friday, December 13th 2013, 19:46

It's always good to have options, there is no one-size-fits-all

I'm glad you made this, besides you wont ever "unlearn" what you learnt doing it :)

#5friv 2 – Thursday, June 12th 2014, 10:08

I got more from your article than I have from others that have similar information.

#6Bjorn Roche – Friday, July 25th 2014, 16:12

Hey there,

I was looking around for ways to get certain looks using a matrix color filter and found this. Sweet! Thanks!

(I was really looking for a way to play with them myself online, but I think the looks you have are pretty much what I was after. Coolio!).

I'm curious if you can say where you got those numbers from. Are they stashed away in some book, or did you make them up? eg:

	_filter.brownie = function() {
		_filter.colorMatrix([
			0.5997023498159715,0.34553243048391263,-0.2708298674538042,0,47.43192855600873,
			-0.037703249837783157,0.8609577587992641,0.15059552388459913,0,-36.96841498319127,
			0.24113635128153335,-0.07441037908422492,0.44972182064877153,0,-7.562075277591283,
			0,0,0,1,0
		]);
	};

#7sash windows – Saturday, July 26th 2014, 21:13

very cool effects.

#8leziz – Saturday, July 26th 2014, 21:14

thank you for the source. we will ad this to our gallery.

Post a Comment:

Comment: (Required)

(use <code> tags for preformatted text; URLs are recognized automatically)

Name: (Required)

URL:

Please type phoboslab into the following input field or enable Javascript. This is an anti-spam measure. Sorry for the inconvenience.