Updated: Apr 12
Sometimes, all you need is just a tiny and fast effects compositor.
Maybe you don’t need meshes, multiple renderers, scene graphs, asset loading, or anything like that. Because, you probably have your own product, with all its batteries included. You just want to apply some cool effects to your videos and images. That’s what we needed here at Wix Engineering, when we set out to deliver our Transparent Video element in the Wix Editor.
Having a WebGL rendering context as a generic recurring element in a website is a VERY unorthodox use of a WebGL context. Usually such instances are used once or twice in an application, covering most of the viewport, and providing a singular, monolithic experience inside a broader context, or serving as the entire experience itself.
OK, so why should you?
Here at Wix, we wanted to give site authors the ability to sprinkle their website with small, decorative, stylish videos that stand out on the foreground and can boost the site’s design.
That’s why we created the Transparent Video element. But to be able to play it cross-browser, smoothly at 60 FPS, in a reasonable quality, we had to resort to some WebGL trickery.
This means we need multiple contexts, smoothly playing, fault tolerant, orchestrated together, inside a raging environment of elements, code, and user interaction. So we thought, why not have a bit more graphics fun while we’re at it ;)
Enters kampos, a tiny WebGL effects compositor. It’s really tiny. And it’s fast.
It lets you paint your media (be that video, image, etc.) on a canvas and apply filter effects.
Here’s an example of a simple usage - setting a hue-rotate filter on a video:
Let’s go over what we see above:
grab a target canvas to draw on and a media source as content.
create a `hueSaturation` filter, and set the rotation angle to 90 degrees.
a `Kampos` instance is created with the target and effects we need. Notice effects are applied, in the order specified in the `effects` array.
then, all that’s left to do in this example is set the source input and start the drawing loop by calling `play()`.
If we wanted more than a single video to paint over, we can create a `Ticker` to manage a single loop:
We just created a `ticker` and then handed it over to every `Kampos` instance we had created earlier. Now, to start playing all loops together we `start` the ticker instead, so all put together it looks like this:
Currently Kampos has just a few simple effects in its arsenal, but it has a generic core, and it is obnoxiously simple to add/create your own effects/transitions, given, of course, you know some GLSL and familiar with the WebGL concepts required for achieving that effect.
How simple, you ask? Well, it’s dead simple.
For example, here’s the duotone effect, stripped down to just the mandatory content:
In there you’ll notice the uniforms needed to be declared, with the content format below (`uniforms`) - and initial `data` (here representing a grayscale effect) - and the definitions above (`fragment.uniform`), which will be added to the shader’s code.
In the middle part, inside `fragment.main` you can see the actual operations this effect performs on the media source. `color` is a “global” variable, reserved by kampos for containing the color part of the pixel we sampled from the source, and which will be written to the output.
`lumcoeff` is a “global” constant containing the generally used luminance coefficient.
And that’s all folks! We just got a grayscale version of the `color` input, and used it to interpolate the output between `u_light` and `u_dark`, which, in this case, will result in the same `gray` result.
For simplicity and interoperability with the rest of the web, we chose to follow the SVG filter effects specs when we implemented our effects. So you can seamlessly mix CSS, SVG, and kampos effects together. We even have end-to-end tests to verify that (but that is another story and will be told another time).
If you want to apply filters to videos in all browsers, if you want to play dynamically with filters and transitions on images and videos in a performant way, than kampos is definitely worth checking out!
This post was written by Yehonatan Daniv
For more engineering updates and insights:
Visit us on GitHub
Subscribe to our YouTube channel