Tuesday, March 13, 2012

Visualizing the Future in Three.js: The Long Walk

Screen grab of "The Long Walk" 
The journey to describe and build the next generation of data visualization apps will be a long and circuitous one. [Is this part of what makes the journey so enjoyable?] On the journey, on occasion, we must stop looking at mere numbers and just look out and see see what we can see.

All this is to say that the weekend before last, I participated in the Art Hack at GAFFTA. The idea was that small teams could develop new artisticky apps. I was predestined to join Tony Parisi's team but no particular job had been decided. My role ended up as being "technical artist". My task was to bring over data created by designers and display it in the web app we were building. This ended up by necessitating the conversion of OBJ files into JSON files and then embedding these into a Three.js files in order to create a scene.

While I was able to accomplish this task, the results were not particularly gratifying. Subsequently I've learned quite a bit more about the topic and present a little demo here with.

The demo is on GitHub and is titled The Long Walk.

Some of the Lessons Learned
The best way to get stuff into Three.js is probably via the Three.js Blender Exporter. The basic concept is that if you can get your 3D data into Blender then the exporter will probably do a pretty good job of getting your 3D data into Three.js.

Once the exporter has created its output file – which is a JavaScript file, it is very easy to tweak the data file using a text editor. You can easily do things such as cut down the number of animation frames or change colors.

There are some issues with this. Blender is a huge application. It is as complicated, if not more so, than Adobe Photoshop or Autodesk AutoCAD. My personal game plan with Blender is not learn it, but to delve into its associated Python API. The application is built using Python and virtually every object in the application is accessible via the API. The major difficulty with doing this is that there has been a recent major upgrade to the Blender application and most documentation relates to the older version. It is not at all easy to find coding examples based on the new version. I ended up using a fair amount of source code from Code Snippets Cookbook. Also the Python forum on Blender Artists has been quite helpful.

At the outset, one reason for using Blender was that I believed it would be very easy to source large numbers of animated characters. Reality is somewhat different. It turns out that there are large numbers of animations available based on the BVH format. There are large numbers of characters available available on places such as Blend Swap. But there are very few, however, are animated characters characters that come with BVH files already embedded. There are a number of videos showing how to do this, but they all implicitly take for granted that you are a fairly advanced user of Blender. And the real deal-killer is that embedding animations manually is a vary slow labrious process.

I think I was quite lucky in finding a single animation (Thank you Ethan Luo) that I could successfully import into three JS without too many issues. There are probably a good number more, but I have not identified a ready source of these.

I did, however, identify what I think would be the logical next step. And that would be to download and install an application called Make Human. This app purports to be able to all that enables you to create characters and attach animations and export them into blender quickly and easily. In the near future I will try this out and report on my success or failures.

Learning how to properly export from Blender to Three.js requires is a lot of trial and error – far too much detail here. There are many issues: tweaking the textures to display in three JS, coercing Blender to export UVs, controlling the number of animations to be exported and much more. I won't go into these because I hope the whole Make Human procedure will obviate the need for such painful journeys. Suffice it to say that in the end I was able to bring in some Blender characters and invest them in a scene where they could animate themselves and display their textures.

In doing so I was able to add some shadowing. Shadows in Three.js are still a mystery to me. There is still no detailed account on how to set up the parameters and parameters actually control. So I pretty much took the settings from the Three.js Shadow Map example - editing these only slightly.

The camera motion I took from the Three.js JSON Blender example.

Perhaps the only non-obvious part of the demo is the way the characters move across the landscape. Actually the character animations stay in the same place. The camera rotates around the stationary walking-in-place characters. And it's not the ground object itself that is moving. The only thing moving is the texture on the ground object that is being a slid a little bit every new frame. The three characters are actually walking in place. This trick came from Jerome Etienne's Learning Three.js.

Envisioning the Vision
The really tricky bit is seeing how all of this fits back into visualizing huge quantities of numbers. Here is my vision of the vision stated briefly: It must be remembered that numbers are reductionist. Numbers are representations of things. But now, thanks to new computer technology, instead of representing things as numbers let us represent them as the things themselves. Instead of representing the number of employees as "389" let us - using particles and shaders - show images of the 389 people. A full discussion in future posts. The journey to getting there is, of course, a long walk.


  1. Interesting write up and three.js sketch. The way you faked the sense of movement by animating the texture is awesome! Seems like we where researching the same things at the same time. Let me know how your exploration into Blender goes. This is the first time I found out about the Blender Cookbook. Makes me want to build something like that for C4D. I am definitely going to try out Make Human, it will be so awesome if it auto riggs characters. The problem is bones work differently in every 3D package. Next step I want to explore is how to create a pre-loader so I can prevent the popping of objects and texture into the scene.

  2. >> Next step I want to explore is how to create a pre-loader
    >> so I can prevent the popping of objects and texture into the scene.

    I am no playing with adding and removing meshes at run-time. See my animated peeps post. A more detailed post is in the works - with adding and removing full scenes at run-time.