Fast Image Filters with WebGL
WebGLImageFilter is a small JavaScript library for applying a chain of filters to an image.
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.
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.
11 Comments:
~hug~
Would be interesting to see how well they perform on a Firefox OS phone.
@Šime Vidas: works perfectly fine on my Keon.
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 :)
I got more from your article than I have from others that have similar information.
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 ]); };very cool effects.
thank you for the source. we will ad this to our gallery.
From this website you can get tool dragon city very easily. You can also get unlimited gems,gold and food of dragon city free of cost which helps in play dragon city game.
Hi, I'm new to javascript. Wondering what is the "inputimage" parameter does?
i have a question... i'm newbie at this. How can a use the convolutional filter?