Category Archives: 3D


See my Experiment on Rutt-Etra-Izer is a WebGL emulation of the classic Rutt-Etra video synthesizer. This demo replicates the Z-displacement, scanned-line look of the original, but does not attempt to replicate it’s full feature set.

The demo allows you to drag and drop your own images, manipulate them and save the output. Images are generated by scanning the pixels of the input image from top to bottom, with scan-line separated by the ‘Line Separation’ amount. For each line generated, the z-position of the vertices is dependent on the brightness of the pixels.

View Demo | Download Source

Running the Demo

To run the demo you need the latest version of Chrome or Firefox, and a fairly new machine. Check if your browser supports WebGL here. If it’s still not working, try restarting your browser.

If you are experiencing slow performance, there are a few things to try: 

  • Reduce stage size
  • Increase line separation
  • Reduce input image size

Generated Output

You can view more images generated by this demo in this Flickr set.

I also built an audio-reactive version with Processing . View a video of this in action below:

VAC / Rutt-Etra-Izer™ from felixturner on Vimeo.

More About Rutt-Etra

The Rutt-Etra video synthesizer was built by Steve Rutt and Bill Etra in 1972. It was one of the first devices to allow real-time manipulation of live video and helped instigate the video art movement of the 1970s. Unfortunately Steve Rutt recently passed away. His pioneering contributions to the field of video art will be always be remembered.

Anton Marini (Vade) created a fantastic Rutt-Etra Emulator for Quartz Composer. The source code of this demo is inspired by Andy Best’s 3D Web Cam Lines processing experiment.


UPDATE (June 13): It appears that saving images from WebGL is broken in Chrome 12. I’m looking into possible solutions. In the meantime, you can use Firefox instead.

UPDATE (June 14): Saving images in now fixed in Chrome 12. The solution is to call a render() immediately before calling toDataURL(). Thanks again to AlteredQualia and Mr.doob.

Nebula – a Three.js Experiment

See my Experiment on In order to learn Three.js with WebGL I built this particle experiment. The purpose of this demo is to investigate the performance of WebGL in the browser and to get some nice eye-candy in the process.

To run WebGL you need the latest version of Chrome or Firefox and a machine that is not more than a couple of years old. If you have this and it’s still not working, try restarting your browser.

Note that there is an issue with Three.js on Windows that causes particles not to be scaled – meaning the demo does not look as cool on Windows 🙁

View Demo | Download Source

Why WebGL?

Before anyone mentions it in the comments – no I don’t think WebGL is going to replace Flash any time soon. WebGL is an emerging standard and is not currently supported by many browsers. As such it is not suitable for building client websites. Why I am excited about WebGL is that it offers performance similar to Processing in the browser. On my laptop this demo runs fullscreen at 60FPS.

The Code

Using Three.js is similar to using Away3D or Papervision, indeed some of the code is ported from those engines. To create a 3D view you need a renderer, a camera, a scene and some 3D objects. Each 3D object consists of some geometry and a material. Three.js allows you to choose between a Canvas renderer and a WebGL renderer. The WebGL renderer is many times faster but does not run in as many browsers. The renderer is a normal HTML element and so you can overlay it with other HTML elements. The dot-screen effect is created by overlaying a transparent PNG via CSS background-image.

Nebula is composed of a particle system which loads a particle png material. Note that individual Particles don’t work with the WebGL renderer, you need to use a ParticleSystem. The particle movement is very simple. Particles start at the origin point (0,0,0) and are assigned a random speed. Each frame the particle speed is added to the particle position and the code checks to see if the particle has moved beyond a cutoff distance from the center, in which case it is reset back to the center.

There are also a number of sunbeams which are long skinny 2D planes that use a semi transparent flat color material (MeshBasicMaterial). Set meshes to be doubleSided if you want to see them when they rotate. All materials are set to use AdditiveBlending and depth testing is turned off. This improves performance and gives a nice glowy effect. To avoid the caret text cursor I use Aerotwist’s stop selection snippet. The code uses jQuery purely for handling div resizing and centering. I use requestAnimationFrame as a more polite way to ask for system resources.

The best way to start learning three.js is to download it and browse the examples. Note that examples that load external files such as 3D models need to be run from a local or remote web server. The three.js IRC channel is a good place to hang out and ask questions. Also check out the super-talented Aerotwist‘s great tutorial called “Getting Started with Three.js“.

JavaScript Dev Tools

I’m currently using Aptana Studio 2 for JavaScript development . It’s an Eclipse based IDE with all the associated pros and cons. I personally like Eclipse since I’ve been using it for a while and know the shortcuts. An Eclipse IDE is probably overkill for a loosely typed language such as JS. The one feature I require from a code editor is that it correctly handles indentation and includes automatic code formatting. It’s amazing how many code editors cannot correctly indent the next line when you press return. If anyone knows a good lightweight JS editor that handles indentation properly, I’d love to hear about it.

For debugging JS I use Chrome’s Developer Tools and lots of console.log (it’s the new trace). Chrome’s Dev Tools are similar to Firebug, but I’ve pretty much stopped using Firefox since it seems so slow compared to Chrome.

WebGL for VJing

Nebula from felixturner on Vimeo.

I ended up using this code to build a Video Projection that was shown at the Venice Art Crawl. The text overlay was pulled from live audience tweets sent in to answer the question: “What is the best thing ever?”. The strobe effect was inspired by ‘Enter the Void’ (check this movie out for some truly insane visuals). Thanks to Stan Wiechers for helping out with the Twitter back-end component.

Hopefully this will inspire someone to get started with Three.js and WebGL. Let me know how you get on!

WebGL Roundup

Since the demise of the Flash Player’s ubiquity, it’s like the Wild West out there for rich media web developers today. There is a whole world of new technologies that allow for animation and rich interactivity on the web. These include jQuery, Canvas, CSS3 transitions, Unity and WebGL. Unfortunately none of these work across all platforms so we are back to the days of creating multiple versions of our content and switching them out based on browser detection.

One of the most exciting new technologies is WebGL. WebGL is a open-standard browser implementation of OpenGL – the graphics API that is used just about everywhere. The strength of WebGL is that it uses hardware acceleration to allow for complex, high frame-rate 3D animations and games. WebGL is scripted with JavaScript.

WebGL is currently supported in Chrome 9+, Firefox 4+ and Safari OSX 10.6+. Since Google turned on WebGL support for the current release version of Chrome, this means anyone can view WebGL content on the web for free. As this is a new technology it’s a little flakey. Some of these demos may hog your machine resources, also you may need to restart your browser now and again.


WebGL is low level API that provides a lot of flexibility and power with the trade-off that it can take a lot of code to make a simple scene. Luckily the ubiquitous Mr Doob has built a very nice JavaScript Library that allows you to easily utilize WebGL: Three.js. Three.js provides the option to choose a Canvas Renderer or a WebGL renderer. Download the library including many WebGL examples here.

WebGL Demos

Here are some demos from around the web that show the potential of WebGL. Use the latest Google Chrome to view them. Let me know in the comments if I’ve missed any good ones.

Three.js/WebGL demos from AlteredQualia.

Three.js/WebGL Demos

FractalLab – insane 3D fractal visualizer from subblue.

Demoscene style shader effects from Frank Reitberger.

WebGL demos from Evgeny Demidov

Learn More


Three.js Experiment – Cube Explosion

Had a chance to play with Mr.Doob‘s excellent JavaScript 3D library three.js today and came up with this. Resize your browser down and Refresh to increase performance. Grab the code via ‘View Source…’.

I’m getting ~54 FPS on Chrome, ~43 FPS on Safari and ~30 FPS on FireFox. The iPad gives a sad 7 FPS. To run on IE you will need the Google Chrome Frame Plugin.

There’s definitely a lot of potential in this library.

YouTube Overload

youtube demo

What’s better than a YouTube video? Sixteen YouTube videos – in 3D! 🙂

This is a for-fun, proof-of-concept demo loading in multiple instances of the new YouTube chromeless player and displaying them with Flash 10’s native 3D . Warning – this demo will probably run at a crawl and may crash your browser.

SWFAddress Gotcha: Navigating Directly to a Deep Link Breaks Preloader

There is a known issue with SWFAddress 2.2: When navigating directly to a deep link, the preloader does not display or jumps straight to 100%. When using the ‘#’ symbol in the URL, the browser loads the main SWF twice which cause the preloader to break.

The fix is to use a mini pre-preloader as supplied in the SWFAddress samples (‘samples/cs3/c.fla’). The mini-loader is loaded twice but since it’s so small it doesn’t matter. I’m adding this information here since the issue is pretty buried in the SWFAddress forum.

[UPDATE] OK, another SWFAddress gotcha by virtue of obscurity: If your back button is not working, check you have specified the ‘id’ attribute in the swfobject.embedSWF() call. The ‘id’ attribute can be any string.

swfobject.embedSWF('c.swf?path=main.swf', 'flashContent', '100%', '100%', '9.0.45', null, {}, {}, {id: 'myId'});