<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Design and Programming by Michael Chang</description><title>Ghost Hack</title><generator>Tumblr (3.0; @mflux)</generator><link>http://mflux.tumblr.com/</link><item><title>FITC Toronto Wrap-Up</title><description>&lt;p&gt;Hi friends, I recently gave a talk at &amp;#8220;Future Innovation Technology Creativity&amp;#8221; in Toronto. The city was really cool, I loved the tech and design vibe, and the weed shop on Queen St.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="http://i.imgur.com/z14q8rp.jpg"/&gt;&lt;/p&gt;

&lt;p&gt;I wish I had more pictures of the event. The whole time I was suppressing a back pain; must have pulled something at the airport. Which also unfortunately made this the most anti-social conference visits of mine, if I missed talking to you, apologies!&lt;/p&gt;
&lt;p&gt;My talk was titled &lt;strong&gt;Creative Coding with THREE.js&lt;/strong&gt; and I chronicle my year-long experience working with it, and why I think it&amp;#8217;s an important piece of software and contribution to the web. You can &amp;gt;&lt;a href="http://ghost-hack.com/post/CREATIVE%20CODING%20WITH%20THREE.JS.zip"&gt;download my slides here&lt;/a&gt;&amp;lt;, though admittedly there&amp;#8217;s plenty of omissions in the slides since most of my talk was spent looking at the interactive pieces and walking through how they were made and what they meant to myself and others.&lt;/p&gt;
&lt;p&gt;For good measure, I&amp;#8217;ll drop the link to &lt;a href="http://threejs.org"&gt;THREE.js&lt;/a&gt; here. As always, credit goes to Mr. Doob and all the git contributors for making the library what it&lt;span&gt;is to day: an excellent tool for creating visually awesome work on the web.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I really enjoyed &lt;a href="http://kylemcdonald.net/"&gt;Kyle Mcdonald&lt;/a&gt;&amp;#8217;s talk on giving things away. When I saw the slide of his room, it reminded myself of my own barren mattress of a housing situation. He really is living the New York hacker lifestyle to the max.&lt;/p&gt;
&lt;p&gt;I also enjoyed Matt Fisher&amp;#8217;s talk on 3D-printing assault rifles. I guess when the playing field is even, maybe we can laser-cut some kevlar vests?&lt;/p&gt;
&lt;p&gt;And finally, &lt;a href="http://www.daito.ws/en/"&gt;Daito Manabe&lt;/a&gt; is some sort of kefka-esque mad genius. Between the terrible (and often hilarious) translation from Japanese to English, and the insane things he does to himself in his projects&amp;#8230; it was well worth the trip alone. Stay brilliant and weird, Mister Tokyo.&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/48829783881</link><guid>http://mflux.tumblr.com/post/48829783881</guid><pubDate>Wed, 24 Apr 2013 20:37:00 -0700</pubDate></item><item><title>100,000 Stars Nominated for Webby Awards</title><description>&lt;a href="http://pv.webbyawards.com/nominees/web/general-website/science/100000-stars"&gt;100,000 Stars Nominated for Webby Awards&lt;/a&gt;: &lt;blockquote class="link_og_blockquote"&gt;Vote with me to help them win! - April 9th - 25th.&lt;/blockquote&gt;
&lt;p&gt;A few days left. Vote for 100,000 Stars, the project I helped create at Google Data Arts Team.&lt;/p&gt;
&lt;p&gt;Also check out &lt;a href="localhost:8080/en/tutorials/casestudies/100000stars/"&gt;“Making of 100,000 Stars”&lt;/a&gt; I wrote for HTML5Rocks.&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/48222583671</link><guid>http://mflux.tumblr.com/post/48222583671</guid><pubDate>Wed, 17 Apr 2013 13:59:08 -0700</pubDate></item><item><title>More to come soon :)</title><description>&lt;img src="http://25.media.tumblr.com/53f12cb23600d5b3e06e83585733f95d/tumblr_mesc5b9zMM1qgliyjo1_400.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;More to come soon :)&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/37589403631</link><guid>http://mflux.tumblr.com/post/37589403631</guid><pubDate>Sun, 09 Dec 2012 14:36:47 -0800</pubDate></item><item><title>Timpulse: Who Works With 'Creative Coders?'</title><description>&lt;a href="http://timstutts.com/post/33707922665/who-works-with-creative-coders"&gt;Timpulse: Who Works With 'Creative Coders?'&lt;/a&gt;: &lt;p&gt;Colleague Tim Stutts posted an excellent article on “Creative Coders” and a list of agencies that often work with them. Also some nice &lt;a href="https://news.ycombinator.com/item?id=4660793"&gt;discourse over at Hacker News&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="tumblr_blog" href="http://timstutts.com/post/33707922665/who-works-with-creative-coders"&gt;timstutts&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Degrees and academic trajectories that combine design and programming as a way of creating digital media are becoming increasingly popular these days at educational institutions around the US and Europe. Students learn tools like &lt;a href="http://processing.org/" target="_blank"&gt;Processing&lt;/a&gt;, &lt;a href="http://www.openframeworks.cc/" target="_blank"&gt;OpenFrameworks&lt;/a&gt;, &lt;a href="http://libcinder.org/" target="_blank"&gt;Cinder&lt;/a&gt; and &lt;a href="http://mrdoob.github.com/three.js/" target="_blank"&gt;ThreeJS&lt;/a&gt; to…&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://mflux.tumblr.com/post/33722006389</link><guid>http://mflux.tumblr.com/post/33722006389</guid><pubDate>Tue, 16 Oct 2012 12:46:07 -0700</pubDate></item><item><title>GAFFTA Workshop Introduction to WebGL with THREE.js Day 1 Part 2</title><description>&lt;p&gt;In Day 1 we went over how to set up a THREE.js scene and how to create and add geometries to the scene. We also looked at the THREE.js api, and messed around with a Pong clone after watching this awesome talk called &amp;#8220;Juice it or lose it&amp;#8221; by some fellow indie game devs. Highly recommended watch, it&amp;#8217;s entertaining, and pure awesomeness.&lt;/p&gt;
&lt;p&gt;&lt;iframe frameborder="0" height="360" src="http://www.youtube.com/embed/Fy0aCDmgnxg?feature=player_detailpage" width="640"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Then I shared this Pong clone I coded in THREE.js.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://dl.dropbox.com/u/705999/webglgaffta/02-pong.zip"&gt;Download the pong clone code here.&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="https://dl.dropbox.com/u/705999/webglgaffta/02-pong/index.html"&gt;View it online.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You were then asked to &amp;#8220;juice up&amp;#8221; this example as described in the above video, by adding particles, screen shake, color, whatever you want.&lt;/p&gt;
&lt;p&gt;&lt;img height="310" src="http://i.imgur.com/Pa09d.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;This example will show you how to actually do something with THREE, like a simple game. Let&amp;#8217;s walk through the code real quick.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;From main.js&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;playerOne = makePaddle();&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;makePaddle() from gameobjects.js is called, which looks like&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;function makePaddle(){&lt;br/&gt;  var geometry = new THREE.CubeGeometry( paddleThickness, paddleLength, 20 );&lt;br/&gt;  var material = new THREE.MeshBasicMaterial(&lt;br/&gt;    {&lt;br/&gt;      color: 0xffffff,&lt;br/&gt;    }&lt;br/&gt;  );&lt;br/&gt;  var mesh = new THREE.Mesh( geometry, material );&lt;br/&gt;  return mesh;&lt;br/&gt;}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here we see that I&amp;#8217;m creating the player-controlled paddle out of cube geometries, then returning the mesh that gets created. This is an easy way to configure a mesh for creation and just add it to the scene for use.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll also notice the material of type THREE.MeshBasicMaterial. There&amp;#8217;s &lt;a href="https://github.com/mrdoob/three.js/tree/master/src/materials"&gt;a bunch of material types&lt;/a&gt; you can play with. The important thing to note here is the passing in of a map with properties of the material. For example MeshBasicMaterial (&lt;a href="https://github.com/mrdoob/three.js/blob/master/src/materials/MeshBasicMaterial.js"&gt;see the reference code&lt;/a&gt;). Here we&amp;#8217;re just passing in a color, which THREE expects as a hexadecimal value, like 0xffffff, rather than the CSS style hex value of #ffffff.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s go back and look at main.js&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;playerOne = makePaddle();&lt;br/&gt;playerOne.position = new THREE.Vector3( -500, 0, 0 );&lt;br/&gt;gameWorld.add( playerOne );&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;playerOne is now a THREE.Mesh, which like I mentioned in the previous post, has position, rotation, scale. These properties come from &lt;a href="https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js"&gt;THREE.Object3D&lt;/a&gt; which most THREE objects derive, like Light, Camera, etc. &lt;/p&gt;
&lt;p&gt;Another thing to note is that position, rotation, and scale are all THREE.Vector3, which is THREE&amp;#8217;s vector class. Here we replace the playerOne&amp;#8217;s position with -500,0,0 which is left of center (with 0,0 being the center by default).&lt;/p&gt;
&lt;p&gt;Finally, we add playerOne to the gameWorld which is another Object3D. Remember that THREE.js is a scene-graph, so we do this up above&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;scene = new THREE.Scene();&lt;br/&gt;gameWorld = new THREE.Object3D();&lt;br/&gt;scene.add( gameWorld );&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the scene graph looks like scene-&amp;gt;gameWorld-&amp;gt;playerOne. &lt;/p&gt;
&lt;p&gt;The reason we created a &amp;#8220;gameWorld&amp;#8221; object is so we can hold all the game meshes, and if you wanted to, you could rotate or translate the entire game world. Try uncommenting this line.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;// gameWorld.rotation.x = -1.2;&lt;span class="Apple-tab-span"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img height="291" src="http://i.imgur.com/FPgjl.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;Play around with this project and try to modify it. Feel free to mail me questions.&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/30978948955</link><guid>http://mflux.tumblr.com/post/30978948955</guid><pubDate>Wed, 05 Sep 2012 21:02:00 -0700</pubDate><category>gaffta</category><category>webgl</category><category>art</category><category>technology</category><category>three.js</category><category>teaching</category><category>programming</category><category>graphics</category></item><item><title>Starting a Local Web Server</title><description>&lt;p&gt;You may want to dynamically load things like OBJs, other code, or HTML to your projects. In this case you usually need to have a web server to do this.&lt;/p&gt;
&lt;p&gt;While you could load your project onto say, ftp or dropbox, it&amp;#8217;s much easier to dev locally.&lt;/p&gt;
&lt;p&gt;First you need Python. If you are running OSX, you should already have it and don&amp;#8217;t need to do anything extra. If you are on Windows, you need to download and install the &lt;a href="http://www.python.org/ftp/python/3.2.3/python-3.2.3.msi"&gt;Python Windows Installer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, go to your command prompt or terminal (in OSX you can just use Spotlight to find Terminal, in Windows you use windows-&amp;gt;run&amp;gt;cmd and hit enter), and browse to your project location.&lt;/p&gt;
&lt;p&gt;Enter this command&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;python -m SimpleHTTPServer&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you point your browser to localhost:8000 now, you will see your project files or its index.html, hosted as if it&amp;#8217;s on a web host. &lt;/p&gt;</description><link>http://mflux.tumblr.com/post/30901548850</link><guid>http://mflux.tumblr.com/post/30901548850</guid><pubDate>Tue, 04 Sep 2012 17:18:00 -0700</pubDate><category>programming</category></item><item><title>GAFFTA Workshop Introduction to WebGL with THREE.js Day 1</title><description>&lt;p&gt;Hi! This post will serve as your guide through the &lt;a href="http://www.gaffta.org/2012/07/16/introduction-to-webgl-with-three-js/" target="_blank"&gt;GAFFTA Introduction to WebGL with THREE.js workshop&lt;/a&gt;. This post is intended to be your companion for the workshop, in case you get lost on your experiments you can always refer back to this page for help.&lt;/p&gt;
&lt;p&gt;In case you&amp;#8217;ve landed on this page somehow and are not taking the workshop, you can also follow along. &lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/mrdoob/three.js/"&gt;THREE.js&lt;/a&gt; is a powerful open source javascript library started by &lt;a href="http://mrdoob.com" target="_blank"&gt;Mr. Doob&lt;/a&gt; and contributed to by many amazing creative coders.&lt;/p&gt;
&lt;p&gt;&lt;img height="226" src="http://i.imgur.com/bvL6O.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;To get started with this workshop, you can follow along one of two ways:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method A. &lt;/strong&gt;This will get you good solid setup for any future experimentation you would want to do. I recommend this method first.&lt;/p&gt;
&lt;p&gt;Download &lt;a href="https://www.google.com/intl/en/chrome/browser/"&gt;Google Chrome&lt;/a&gt; or &lt;a href="http://www.mozilla.org/en-US/firefox/new/"&gt;Firefox&lt;/a&gt;, or any WebGL supported browser.&lt;/p&gt;
&lt;p&gt;Download a good text editor so you can write code. For example, &lt;a href="http://www.sublimetext.com" target="_blank"&gt;SublimeText&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Then download the &lt;a href="https://dl.dropbox.com/u/705999/webglgaffta/01-helloworld.zip"&gt;example sketch&lt;/a&gt;. You can also &lt;a href="https://dl.dropbox.com/u/705999/webglgaffta/01-helloworld/index.html"&gt;view this sketch online&lt;/a&gt;. The example sketch contains all the files you need, such as a main.js where the code lives, and a copy of three.js in the same folder.&lt;/p&gt;
&lt;p&gt;Once you have the sketch downloaded, you can open index.html in the sketch with your browser. That&amp;#8217;s it! You should then see a rotating cube.&lt;/p&gt;
&lt;p&gt;&lt;img height="324" src="http://i.imgur.com/yDMKk.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method B. &lt;/strong&gt;This method is totally experimental and it&amp;#8217;s entirely possible to lose your work, but it&amp;#8217;s really good for just trying something out. Give it a shot anyway!&lt;/p&gt;
&lt;p&gt;Go to &lt;a href="http://mrdoob.com/projects/code-editor/" target="_blank"&gt;&lt;a href="http://mrdoob.com/projects/code-editor/"&gt;http://mrdoob.com/projects/code-editor/&lt;/a&gt;&lt;/a&gt; Mr. Doob wrote a snazzy in-page code editor for the lazy. It&amp;#8217;s still early in development and there are always issues with such things, so please keep that in mind.&lt;/p&gt;
&lt;p&gt;You can go ahead and edit right in that window and update the code as needed.&lt;/p&gt;
&lt;p&gt;Some handy links to have open when you&amp;#8217;re working with three.js&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/mrdoob/three.js/tree/master/src" target="_blank"&gt;source repository&lt;/a&gt; so you can look at what each object expects as arguments.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/mrdoob/three.js/wiki"&gt;three.js wiki&lt;/a&gt;. This page might answer a lot of your questions.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;h1 class="blog_info"&gt;&lt;strong&gt;Hello World&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Let&amp;#8217;s go over the formalities. &lt;/p&gt;
&lt;p&gt;Three.js is a &lt;a href="http://en.wikipedia.org/wiki/Scene_graph"&gt;scene graph&lt;/a&gt;. If you are already familiar with OpenGL, it takes care of the render calls for you, you just need to parent objects to the scene and things will be made visible. If you are familiar with something like 3D Studio Max or Maya, then this hierarchy should also be familiar to you.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s take a look at the main.js that comes from the example hello world zip.&lt;/p&gt;
&lt;h1 class="blog_info"&gt;&lt;strong&gt;Renderer&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;You need to instantiate a &lt;em&gt;renderer&lt;/em&gt;. This will do the business logic of rendering your scene.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;var renderer = new THREE.WebGLRenderer();&lt;br/&gt;renderer.setSize( window.innerWidth, window.innerHeight );&lt;br/&gt;document.body.appendChild( renderer.domElement );&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that we&amp;#8217;re setting the size of the renderer to the browser window&amp;#8217;s width and height. Additionally, we&amp;#8217;re attaching the dom element for the renderer to the body.&lt;/p&gt;
&lt;h1 class="blog_info"&gt;&lt;strong&gt;Scene&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;The &lt;em&gt;scene&lt;/em&gt; is just a root THREE.js object. Things that you want rendered will need to be added to this object, like so&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;scene.add(myObject);&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You will see an example of this further down the code.&lt;/p&gt;
&lt;h1 class="blog_info"&gt;&lt;strong&gt;Camera&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Next, you need a &lt;em&gt;camera&lt;/em&gt;. This will be where your render view will be looking at. For this example we do &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;var camera = new THREE.PerspectiveCamera( 60, (window.innerWidth / window.innerHeight), 1, 10000);&lt;br/&gt;camera.position.z = 1000;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here we&amp;#8217;ve instantiated a camera with &lt;em&gt;field of view&lt;/em&gt; of 60, an &lt;em&gt;aspect ratio&lt;/em&gt; of window width divided by window height, and finally a near clip plane and a far clip plane. Don&amp;#8217;t worry if you don&amp;#8217;t understand this yet. These are what OpenGL expects when determining how to render your scene.&lt;/p&gt;
&lt;p&gt;Now that we have the holy trifecta of THREE.js objects created, let&amp;#8217;s put some geometry on the screen.&lt;/p&gt;
&lt;h1 class="blog_info"&gt;&lt;strong&gt;Geometry and Mesh&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;THREE.js has two constructs to be aware of, Geometry and Mesh.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/mrdoob/three.js/blob/master/src/core/Geometry.js" target="_blank"&gt;Geometry&lt;/a&gt; is the thing that will hold on to vertex positions. For example, the vertices of a cube will be in geometry.vertices. &lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/mrdoob/three.js/blob/master/src/objects/Mesh.js" target="_blank"&gt;Mesh&lt;/a&gt; is a scene-graph object. Creating a Mesh usually involves giving its constructor a Geometry and a Material. We won&amp;#8217;t worry about the material part yet.&lt;/p&gt;
&lt;p&gt;So in our example&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;var geometry = new THREE.CubeGeometry( 500,500,500 );&lt;br/&gt;var mesh = new THREE.Mesh( geometry );&lt;br/&gt;scene.add( mesh );&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We&amp;#8217;ve created a CubeGeometry which is a cube primitive from this &lt;a href="https://github.com/mrdoob/three.js/tree/master/src/extras/geometries" target="_blank"&gt;list of primitives&lt;/a&gt;. Then we&amp;#8217;ve stuffed the geometry into a new Mesh. Finally, we add the mesh to the scene. The renderer will take care of the rest.&lt;/p&gt;
&lt;h1 class="blog_info"&gt;&lt;strong&gt;Animation&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Finally, let&amp;#8217;s take a look at our animation function.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;function update(){&lt;br/&gt;  mesh.rotation.y += 0.01;&lt;br/&gt;  renderer.render( scene, camera );&lt;br/&gt;  requestAnimationFrame( update );&lt;br/&gt;}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With mesh.rotation.y += 0.01, we&amp;#8217;re telling the mesh&amp;#8217;s rotation to increment every frame. Each Mesh is an &lt;a href="https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js" target="_blank"&gt;Object3D&lt;/a&gt; that has &lt;em&gt;position&lt;/em&gt;, &lt;em&gt;rotation&lt;/em&gt;, and &lt;em&gt;scale&lt;/em&gt; that you can modify.&lt;/p&gt;
&lt;p&gt;Then following line, we make the renderer render by calling render() and passing in the scene and camera.&lt;/p&gt;
&lt;p&gt;Finally, we do requestAnimationFrame, a nice and web-safe way of doing an animation loop. This causes the update function to be run over and over again so long as the user is viewing this page. Notice how we pass in the entire update function back into requestAnimationFrame.&lt;/p&gt;
&lt;p&gt;Oh yeah, and update() needs to be called once, at the very bottom.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll go over much more in the workshop, depending on the number of students and the level of knowledge attendees come with. Let&amp;#8217;s make some webgl!&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/30683004557</link><guid>http://mflux.tumblr.com/post/30683004557</guid><pubDate>Sat, 01 Sep 2012 15:37:00 -0700</pubDate><category>webgl</category><category>threejs</category><category>art</category><category>programming</category><category>tutorial</category><category>gaffta</category></item><item><title>Generative Machines</title><description>&lt;p&gt;A few months ago I was asked to make some visuals for &lt;a href="https://developers.google.com/events/io/"&gt;Google IO &lt;/a&gt;, something I&amp;#8217;ve done in the past with these &lt;a href="http://www.youtube.com/watch?v=a46hJYtsP-8"&gt;procedural circuit-board diagrams&lt;/a&gt;. I spent a good few weeks experimenting with a ton of different things, in both THREE.JS and Processing, and slowly gravitated towards one concept.&lt;/p&gt;
&lt;p&gt;This post will be image heavy, so I&amp;#8217;ll skip on the failed experiments and get right to it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://workshop.chromeexperiments.com/machines" target="_blank"&gt;&lt;img align="middle" height="414" src="http://i.imgur.com/5TtDK.png" width="800"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://workshop.chromeexperiments.com/machines" target="_blank"&gt;Generative Machines&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The idea of a procedural &lt;a href="https://www.google.com/search?q=exploding+view+diagram&amp;amp;sugexp=chrome,mod%3D18&amp;amp;um=1&amp;amp;ie=UTF-8&amp;amp;hl=en&amp;amp;tbm=isch&amp;amp;source=og&amp;amp;sa=N&amp;amp;tab=wi&amp;amp;authuser=0&amp;amp;ei=bacyUMWiJ4eByAHP9IGIDQ&amp;amp;biw=1440&amp;amp;bih=740&amp;amp;sei=b6cyUODBIemXyAHW34GYAg"&gt;exploding view diagram&lt;/a&gt; was very attractive to me. It had all the right elements: a bunch of techy looking mechanical shapes, diagrammatic, and all of these lines criss crossing everywhere as if to suggest motion of a kind that automatically assembles.&lt;/p&gt;
&lt;p&gt;It wasn&amp;#8217;t enough that I simply had rivets and slots coming together, I also wanted to make an overall structure that looked as if, when assembled, became a machine that forms a whole that was more than the sum of its parts. &lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;This got me thinking about creating procedural shapes that I can cut up. My first exploration into this was creating a one dimensional exploding axis, where elements can fly forward or back, and adding a radial dimension where elements could be chopped up and exploded outwards.&lt;/p&gt;
&lt;p&gt;&lt;img height="293" src="http://i.imgur.com/yxDFV.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;This involved in a lot of geometry splitting, helped by this wonderful THREE.JS library by &lt;a href="http://chandler.prallfamily.com/"&gt;Chandler Prall&lt;/a&gt;, based on a &lt;a href="http://en.wikipedia.org/wiki/Constructive_solid_geometry"&gt;Constructive Solid Geometry&lt;/a&gt; (or CSG) javascript library by &lt;a href="http://madebyevan.com/"&gt;Evan Williams&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/"&gt;Example usage of this library.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Normally the library allows you to subtract geometry, add geometry, or intersections, however what I really needed was a cutting plane that slices any arbitrary geometry that I give it. I whipped up this hacky solution where I defined a plane, and a solver would create two gigantic boxes on either side. These two boxes are then used for two intersect operations on the geometry, one on each side of the plane.&lt;/p&gt;
&lt;p&gt;&lt;img height="366" src="http://i.imgur.com/0Gm6p.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;This allowed me to have geometries with N number of slices, each forming individual mesh pieces that I can then animate.&lt;/p&gt;
&lt;p&gt;&lt;img height="1538" src="http://i.imgur.com/pzRXQ.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;While this got me somewhere, it still didn&amp;#8217;t feel like it was creating a machine. It looked too abstract. What I needed was something that carefully straddles the line between hand-made geometry design and something that was procedural.&lt;/p&gt;
&lt;p&gt;The next experiment involved procedurally generating shapes that were somewhat recognizable. Capsules lined with shells, screws, and wiring in this example.&lt;/p&gt;
&lt;p&gt;Then I needed a skeletal base on which to generate the geometry. This would allow me to do replication (important in a machine-looking thing!) and some form of hierarchical generation. &lt;/p&gt;
&lt;p&gt;&lt;img height="394" src="http://i.imgur.com/dNgdb.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;I divided the code into three main layers.&lt;/p&gt;
&lt;p&gt;The highest level was the skeleton, which would be a procedurally generated series of nodes (each using an Object3D, abusing THREE&amp;#8217;s scene graph for my own purpose, more on this later). &lt;/p&gt;
&lt;p&gt;The strategy I ended up with was to generate a &amp;#8220;spine&amp;#8221; from which radial and branching skeletons would emerge. After the skeleton was decided on, a function traverses each joint and generates the &amp;#8220;meat&amp;#8221; on the bones, called &amp;#8220;assemblies&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;img height="694" src="http://i.imgur.com/4Co4y.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;The next layer is what I call assemblies. Each assembly lives on a single joint length in the skeleton. They exist as functions that are hand tailored to procedurally generate something recognizable, such as a jet engine or a battery compartment (I wasn&amp;#8217;t too focused on realism at this point). The assemblies get information about the joint length, and where the next joint is, but that&amp;#8217;s about it. Inside each assembly are some randomized parameters, and sometimes conditions based on length, so each assembly will look slightly different based on initial conditions.&lt;/p&gt;
&lt;p&gt;&lt;img height="369" src="http://i.imgur.com/gUbgG.png" width="700"/&gt;&lt;/p&gt;
&lt;p&gt;Finally at the &amp;#8216;lowest&amp;#8217; level were components. These were essentially recyclable geometry generating tools I would use in each assembly to create the recognizable pieces, such as struts, lattices, wires, etc. For what it&amp;#8217;s worth these were pretty quickly hacked up and not really meant to be reusable for the future, but they accomplished their job admirably.&lt;/p&gt;
&lt;p&gt;&lt;img height="812" src="http://i.imgur.com/5VbWu.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;Deciding on a color palette was interesting. I wanted the palette to be generated, but any ol&amp;#8217; random colors will not do. I needed sets of colors that work well with each other, but randomly distributed to the components.&lt;/p&gt;
&lt;p&gt;I drew inspiration from these &lt;a href="http://en.wikipedia.org/wiki/Mirror's_Edge"&gt;Mirror&amp;#8217;s Edge&lt;/a&gt; 1080p wallpapers that I had laying around. The artists for this game really love color, and the palettes these images are blessed with are beautiful. So why not just borrow them?&lt;/p&gt;
&lt;p&gt;&lt;img height="230" src="http://i.imgur.com/iwCGX.png" width="737"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="338" src="http://i.imgur.com/I4h4l.jpg" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="371" src="http://i.imgur.com/bj93G.png" width="700"/&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;I ended up creating these palette sets, based on sampling each image with approximate distributions. When the machine is first generated, a randomly chosen palette is picked. Each machine component type is then randomly assigned a color ID from the palette. This creates a look of &amp;#8216;organized random&amp;#8217;, since each assembly has these uniformity to them, even though the process for picking them was totally random.&lt;/p&gt;
&lt;p&gt;&lt;img height="338" src="http://i.imgur.com/OeKNk.jpg" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="376" src="http://i.imgur.com/4DAtV.png" width="798"/&gt;&lt;/p&gt;
&lt;p&gt;Some more color palette examples&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;img height="325" src="http://i.imgur.com/VgdjF.png" width="800"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="474" src="http://i.imgur.com/NCQRv.png" width="900"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="383" src="http://i.imgur.com/dJCou.png" width="947"/&gt;&lt;/p&gt;
&lt;p&gt;Creating animation for these was one of the main features I wanted to try, essentially producing something that looked like it was assembling or dis-assembling based off of the exploding diagram they were inspired by. &lt;/p&gt;
&lt;p&gt;I heavily abused these two wonderful tools, THREE.SceneUtils.traverseHierarchy, which crawls through the scene graph calling a function on each, and Javascript&amp;#8217;s ability to give a function to any object.&lt;/p&gt;
&lt;p&gt;Each Mesh that I want animated was given an update function, like so:&lt;/p&gt;
&lt;pre&gt;shell.update = function( percentage ){
	this.position.z = this.start + (this.end - this.start) * percentage;
};&lt;/pre&gt;
&lt;p&gt;The percentage would represented a normalized value between 0 and 1, 0 being a state of total disassembly, and 1 being total assembly.&lt;/p&gt;
&lt;p&gt;Each mesh would then be responsible for taking care of their own translate or rotate values based on the input percentage, so I could easily set the initial and end state for the mesh. All meshes were procedurally generated with their end state, but their update function with a value of 0 would cause them to be at a disassembled state. For example at 0, a screw would be far off to the side, and by increasing it to 1 it would rotate and spin inwards towards its generated, final position.&lt;/p&gt;
&lt;p&gt;&lt;img height="1711" src="http://i.imgur.com/OMtb6.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;I then used &lt;a href="https://github.com/sole/tween.js/"&gt;TWEEN.js&lt;/a&gt; to create interpolation to each animation. To create the staggered animating effect, I instructed the TraverseHeiarchy to go outwards from the lowest chain in the scene graph, animate those, and skip animating the parents (and their parents) until the children are completed with their animation. This causes the smallest, lowest bits of the assembly / component system to be animated first before animating larger entities. &lt;/p&gt;
&lt;p&gt;&lt;img height="834" src="http://i.imgur.com/BgzYq.png" width="700"/&gt;&lt;/p&gt;
&lt;p&gt;There are some finishing touches that needed to be considered. I&amp;#8217;ve experimented with putting the structure on black and dark gray, both of which gave an interesting look, but I still settled on white because of the black diagram lines, keeping the aesthetic more in line with the exploding view diagrams this was inspired by.&lt;/p&gt;
&lt;p&gt;&lt;img height="387" src="http://i.imgur.com/4gXXM.png" width="800"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="346" src="http://i.imgur.com/AC0TU.png" width="700"/&gt;&lt;/p&gt;
&lt;p&gt;I added an ambient light color wash which took out a bit of the &amp;#8220;CG Phong&amp;#8221; look which plagued that shader when used by default, though admittedly it&amp;#8217;s now become very instagr.am-looking.&lt;/p&gt;
&lt;p&gt;&lt;img height="357" src="http://i.imgur.com/VqZiF.png" width="700"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="716" src="http://i.imgur.com/n944r.png" width="700"/&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve also added some randomized specular lighting which gave it a metallic sheen. Finally, I experimented a bit more with the skeletal layout system to create some radial-symmetry, hopefully to create more orderly-looking constructs from a higher level, something like a &lt;a href="http://cache.boston.com/universal/site_graphics/blogs/bigpicture/lhc_08_01/lhc15.jpg"&gt;Large Hadron Collider&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img height="459" src="http://i.imgur.com/G3EG1.png" width="900"/&gt;&lt;/p&gt;
&lt;p&gt;The finishing touches on UI and styling are by &lt;a href="http://www.georgemichaelbrower.com/"&gt;Geoerge Michael Brower&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are some more images from the final piece. &lt;/p&gt;
&lt;p&gt;&lt;img height="459" src="http://i.imgur.com/yMzdM.png" width="900"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="413" src="http://i.imgur.com/QHzzb.png" width="800"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="415" src="http://i.imgur.com/x5yeS.png" width="800"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="519" src="http://i.imgur.com/uRqRN.png" width="800"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="519" src="http://i.imgur.com/01CP9.png" width="800"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="519" src="http://i.imgur.com/H7Fpk.png" width="800"/&gt;&lt;/p&gt;
&lt;p&gt;This project didn&amp;#8217;t end up getting used for Google IO this year for reasons unknown to me, but I&amp;#8217;m happy it&amp;#8217;s seeing the light of day as a &lt;a href="http://chromeexperiments.com" target="_blank"&gt;Chrome Experiment&lt;/a&gt;.&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/29879318929</link><guid>http://mflux.tumblr.com/post/29879318929</guid><pubDate>Tue, 28 Aug 2012 14:42:00 -0700</pubDate><category>animation</category><category>code</category><category>google</category><category>procedural</category><category>three.js</category><category>work</category><category>art</category><category>technology</category><category>illustration</category></item><item><title>Arms Trade Visualization</title><description>&lt;p&gt;*edit* This post was created a few days ago but had to be taken down. Should be okay now that It&amp;#8217;s up on &lt;a href="http://googleblog.blogspot.com/2012/08/a-new-way-to-visualize-global-arms-trade.html"&gt;Google&amp;#8217;s official blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;#8212;-&lt;/p&gt;
&lt;p&gt;I work for Data Arts Team at Google and we get a lot of cool oddball projects here and there, more of which I might write about in the future, permissions pending.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s something that is just wrapping up.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://workshop.chromeexperiments.com/projects/armsglobe" target="_blank"&gt;Arms Trade Visualization&lt;/a&gt; (best viewed on Chrome on full-screen).&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="1164" src="http://i.imgur.com/E3a1s.png" width="1794"/&gt;&lt;/p&gt;
&lt;p&gt;A few weeks ago I was introduced to Dr. Robert Muggah, principle of SecDev Group who was giving &lt;a href="http://googleblog.blogspot.com/2012/07/google-ideas-joining-fight-against-drug.html"&gt;a talk at INFO&lt;/a&gt; summit (Illicit Networks Forces in Opposition), a conference about how information technologies can expose shitty things happening in the world (slave trade, illegal arms dealing, bad actors network). Somehow our team was asked to make a data viz on data, and the project fell on my lap.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;Of the data sets that were presented to me, one stood out the most ripe for visualization, and that was the (legal) arms trade data set collected by the UN and compiled by Robert Muggah and &lt;a href="http://www.prio.no/"&gt;PRIO&lt;/a&gt; (Peace Research Institute Oslo).&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="383" src="http://i.imgur.com/DRgdw.png" width="728"/&gt;&lt;/p&gt;
&lt;p&gt;This data set contains about a hundred thousand &amp;#8220;trades&amp;#8221; between countries for weapons reported by the UN. The columns represent the year of the trade (as high resolution as we could get, at least that&amp;#8217;s what they said), the exporter and importer country names, the exporter and importer country codes (who knows what they are? I didn&amp;#8217;t look very far), weapons code (UN specified) that refers to some categories like ammunition, military rifles, sporting rifles, etc, and the US dollar amount for the trade, unadjusted for inflation.&lt;/p&gt;
&lt;p&gt;As an aside, I really enjoy data that comes in as &amp;#8220;flat&amp;#8221; as possible such as this CSV, especially for time series things. The trick is now to &amp;#8216;bin&amp;#8217; this into something I can parse for a data viz.&lt;/p&gt;
&lt;p&gt;The first order of business is to sanitize the country names against something I could use. Upon reflection I probably should have done this by matching the country&amp;#8217;s &amp;#8216;code&amp;#8217; id with some data base of countries, but my inquiry about this with the data provider didn&amp;#8217;t turn out anything.&lt;/p&gt;
&lt;p&gt;From my previous projects I already had a country list that had ISO-3166 codes matched to country names, for example &amp;#8220;United States&amp;#8221; to &amp;#8220;US&amp;#8221;, or &amp;#8220;Taiwan&amp;#8221; to &amp;#8220;TW&amp;#8221;. In addition, the country codes are paired up already with latitude and longitudes important for us later on.&lt;/p&gt;
&lt;p&gt;Here are some examples of country names mismatching:&lt;/p&gt;
&lt;p&gt;In the CSV: &amp;#8220;Antigua &amp;amp; Barbuda&amp;#8221;&lt;br/&gt;In my set: &amp;#8220;Antigua and Barbuda&amp;#8221;&lt;/p&gt;
&lt;p&gt;In the CSV: &amp;#8220;Congo (Republic of)&amp;#8221;&lt;br/&gt;In my set: &amp;#8220;Congo&amp;#8221; &lt;/p&gt;
&lt;p&gt;I decided it&amp;#8217;s better to &amp;#8216;fix&amp;#8217; the data set&amp;#8217;s naming than it is to come up with yet another match list. Instead of a straight &amp;#8220;find and replace&amp;#8221; which would have been horribly messy especially with a hundred thousand entries and over two hundred and fifty countries.&lt;/p&gt;
&lt;p&gt;I opened the CSV in &lt;a href="http://code.google.com/p/google-refine/"&gt;Google Refine&lt;/a&gt;, a nice little utility that allows me to quickly sort and see issues in the data set. In addition to fixing the names, I could save out the &amp;#8220;change-list&amp;#8221; so that in the future if I found out I screwed up somewhere I could essentially revert or adjust, as the change list json acts as a modification history to the data (this comes super handy later when I discovered that I had missed a few countries).&lt;/p&gt;
&lt;p&gt;The next step is to &amp;#8220;bin&amp;#8221; the data into groups by year, instead of attempting to parse a hundred thousand pieces of data each time. This is helpful since I knew my data viz was going to be a time series, and I knew that it would be useful to scrub the timeline and see changes, so organizing the data in a way that makes this easy was high priority. &lt;/p&gt;
&lt;p&gt;I wrote a small python script to both convert and save the data out as JSON, which is really useful since I&amp;#8217;m eventually going to parse it with Javascript anyway, and here I can organize it into the exact way I want to actually access the data. (Not sure if I can share this part since but it&amp;#8217;s really simple).&lt;/p&gt;
&lt;p&gt;Originally the weapon codes were described as such:&lt;/p&gt;
&lt;p&gt;930100 – military weapons, and includes some light weapons and artillery as well as machine guns and assault rifles etc.  &lt;/p&gt;
&lt;p&gt;930190 – military firearms – eg assault rifles, machineguns (sub, light, heavy etc), combat shotguns, machine pistols etc&lt;/p&gt;
&lt;p&gt;930200 – pistols and revolvers&lt;/p&gt;
&lt;p&gt;930320 – Sporting shotguns (anything that isn’t rated as a military item).&lt;/p&gt;
&lt;p&gt;930330 – Sporting rifles (basically anything that isn’t fully automatic).&lt;/p&gt;
&lt;p&gt;930621 – shotgun shells&lt;/p&gt;
&lt;p&gt;930630 – small caliber ammo (anything below 14.5mm which isn’t fired from a shotgun.&lt;/p&gt;
&lt;p&gt;At some point we decided that the UN&amp;#8217;s weapons trade categorization were far too arbitrary and confusing, even to the expert that we asked this about. So instead we just decided to combine the categories. &lt;/p&gt;
&lt;p&gt;Okay! The JSON came out to be roughly the same filesize as the CSV, weighing at about 5 megs. Again, upon reflection, we could have used country codes to save space, but I wasn&amp;#8217;t really worried at this prototype stage. I just wanted something on-screen so we can see.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://arms.dat-friends.appspot.com/categories/All.json"&gt;You can see the output JSON here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Time to parse this guy. I won&amp;#8217;t cover too much on WebGL, &lt;a href="https://github.com/mrdoob/three.js/" target="_blank"&gt;THREE.js&lt;/a&gt; and globe code, but I&amp;#8217;ll gloss over a bit of it here.&lt;/p&gt;
&lt;p&gt;First I read in the country names, then matched up country name with country codes and latitude longitudes. &lt;a href="http://arms.dat-friends.appspot.com/country_lat_lon.json" target="_blank"&gt;Here is the json that I produced using public data found on the internet.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following snippet is how I converted the lat lons into 3D geometry coordinates. The final code included a bit of fudging factor to make things match up, but for the most part this works.&lt;/p&gt;
&lt;pre&gt;	//	take the lat lon from the data and convert this to 3d globe space
        var lon = country.lon - 90;
        var lat = country.lat;
        
        var phi = Math.PI/2 - lat * Math.PI / 180;
        var theta = 2 * Math.PI - lon * Math.PI / 180;
		
	var center = new THREE.Vector3();                
        center.x = Math.sin(phi) * Math.cos(theta) * rad;
        center.y = Math.cos(phi) * rad;
        center.z = Math.sin(phi) * Math.sin(theta) * rad;  	
	
	//	save and catalogue       
	country.center = center;&lt;/pre&gt;
&lt;p&gt;&lt;img align="middle" height="835" src="http://i.imgur.com/z9kQN.jpg" width="1627"/&gt;&lt;/p&gt;
&lt;p&gt;Now we&amp;#8217;re getting somewhere. Each line you see represents a trade. You can barely make out europe in that tight patch of countries where it&amp;#8217;s really bright. The curvature is just a spline construction (&lt;a href="http://arms.dat-friends.appspot.com/js/visualize_lines.js"&gt;see the code here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Already it&amp;#8217;s rendering slowly since *each* trade is a GL line draw call, so I decided to dump all of them into a vertex buffer, and it works much faster, but we have this laser ball now pointing to the middle. That&amp;#8217;s okay though, since it will be covered up by an eventual sphere.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="838" src="http://i.imgur.com/hX4pT.png" width="1626"/&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s also important to identify the trades by country, so here you see each country being assigned a random color and then applying the color to the line itself. By using additive blending and reducing the brightness, we can get a sense of volume for the trading area.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="838" src="http://i.imgur.com/pUbL7.png" width="1626"/&gt;&lt;/p&gt;
&lt;p&gt;Next we need to see the countries! The most obvious way is to bring in some NASA texture map or a PNG of some country border, but that&amp;#8217;s kind of boring, so I decided to use a &amp;#8220;pin map&amp;#8221; version of the world map presented by vertices. As you can see each country is composed of a series of vertices and I&amp;#8217;m simply extruding them up to form hexagon bricks that I then color by the randomized country colors.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="842" src="http://i.imgur.com/LOmEx.png" width="1632"/&gt;&lt;/p&gt;
&lt;p&gt;The data viz is now lacking a key layer of information&amp;#8230; &amp;#8220;which country is selling, and which country is buying&amp;#8221;? How do I represent importers and exporters? I ended up with this experiment where particles represent weapon sales and are traveling from the country of origin to destination so you can see who are the primary exporters and importers.&lt;/p&gt;
&lt;p&gt;&lt;img height="838" src="http://i.imgur.com/YXK95.png" width="1624"/&gt;&lt;/p&gt;
&lt;p&gt;Obviously you can only see how this works in motion, but you can tell from the final version that this solution is what I ended up with.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="841" src="http://i.imgur.com/ohXzS.jpg" width="1626"/&gt;&lt;/p&gt;
&lt;p&gt;At this stage there&amp;#8217;s still a few problems that I needed to solve. How do I represent categories of weapons sale, do I use color? Particle icons? Something else? Another problem you can see is the country centers. At this point they were using the country vertex locations and getting the average center, which is usually not what we think of as &amp;#8216;center of a country&amp;#8217;. For example, United States gets pulled north due to the amount of vertices Alaska contains. This was eventually fixed by doing a lookup of actual lat lons of countries instead of finding averages of vertices.&lt;/p&gt;
&lt;p&gt;To prepare for the eventual UI that is going to be built, I prototyped the filter functionalities by adding DAT.gui, a simple UI interface made my friends on the team. This is really handy for getting quick checkboxes and dropdowns when doing creative coding work that needs to be adjusted on the fly.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="839" src="http://i.imgur.com/rQTo4.png" width="1625"/&gt;&lt;/p&gt;
&lt;p&gt;A few things I decided to change in my design at this point, given feedback from the team and examining our options. First was that the pins (hexagonal bricks) representing the countries were too visually noisy, since the lines and particles were the actual &amp;#8220;meat&amp;#8221; of what we should be looking at. Second, the colors needed to be fixed so that they actually represent something useful other than simply showing different countries. Third, the particles themselves need a bit of love. Finally, I&amp;#8217;ve also planned on adding some sort of 2D &amp;#8220;HUD&amp;#8221; markers that sit on top of the globe to act as selectors for the countries, in leu of doing actual country picking (more on this later).&lt;/p&gt;
&lt;p&gt;The first problem was really tricky &amp;#8212; I wanted to flatten the representation of countries back to a texture on the globe, but I also needed to highlight countries. Essentially I needed a dynamically updatable texture map, with any of the 250+ countries capable of lighting up when I needed it to.&lt;/p&gt;
&lt;p&gt;A few considerations came to mind&amp;#8230; I could render each country as vertex / quad geometry, but I would have to produce this geometry some how and that would be pretty time intensive and questionable if it would work out well.&lt;/p&gt;
&lt;p&gt;Alternatively &amp;#8230; I could have two hundred and fifty country image panels and somehow mapped their UVs for rendering. Again, this sounded really painful and I dreaded the notion of trying to map these correctly back onto the globe.&lt;/p&gt;
&lt;p&gt;I tried this wonky solution of using an SVG of the world map (&lt;a href="http://en.wikipedia.org/wiki/File:BlankMap-World6-Equirectangular.svg"&gt;the equirectangular svg map found on Wikipedia&lt;/a&gt;), and using this cool little library called &lt;a href="http://code.google.com/p/canvg/" target="_blank"&gt;CanVG&lt;/a&gt; that renders SVGs onto canvas, and then injecting the resulting canvas into a GL texture.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="856" src="http://i.imgur.com/EHfrP.png" width="1180"/&gt;&lt;/p&gt;
&lt;p&gt;It worked alright but the rendering time was around two seconds per render (!). It was  unbearable, and given the level of interactivity I wanted this was unacceptable.&lt;/p&gt;
&lt;p&gt;I talked to &lt;a href="http://onecm.com/" target="_blank"&gt;Ryan Alexander&lt;/a&gt; about this problem, asking if there was a GL shader solution. He recommended that I try a lookup table which I&amp;#8217;ll attempt to explain here.&lt;/p&gt;
&lt;p&gt;The strategy revolves around having a globe texture with each country colored at a different grayscale index. I wrote a small Processing app that took the SVG I was using previously and rendering each country (thank god the SVG was already split by ISO-3166 country codes!!) as a different gray value, between 1 and 256. If there were more than 255 countries I would run into problems&amp;#8230; but thankfully that wasn&amp;#8217;t the case. Additionally, pure black 0 was used to represent the ocean (no country).&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="600" src="http://i.imgur.com/tjP7Z.png" width="1200"/&gt;&lt;/p&gt;
&lt;p&gt;In addition to outputting this image, I also had the Processing program write out a JSON array of grayscale lookup to country code.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="278" src="http://i.imgur.com/NT8OE.png" width="1113"/&gt;&lt;/p&gt;
&lt;p&gt;Finally I cooked up this bit of GLSL code. The idea is really simple&amp;#8230; there will be two image buffers, the first one holds the image above, and the second is a 256x1 pixel buffer that will be the actual color rendered for that country. For example, &amp;#8216;FR&amp;#8217; (France) has a grayscale value of 3, so on the second image buffer I look up the third pixel from the left for what color to render France with.&lt;/p&gt;
&lt;p&gt;With this I was able to mask any number of countries and color them instantaneously, all done from the video card. Using the same lookup map I was able to render one pass at the original grayscale (0-255 index) values to do picking, so that ended up being a two for one victory.&lt;/p&gt;
&lt;ol&gt;&lt;li class="li1"&gt;
&lt;div class="de1"&gt;&lt;span class="sy0"&gt;&amp;lt;&lt;/span&gt;script id&lt;span class="sy0"&gt;=&lt;/span&gt;&lt;span class="st0"&gt;&amp;#8220;globeFragmentShader&amp;#8221;&lt;/span&gt; type&lt;span class="sy0"&gt;=&lt;/span&gt;&lt;span class="st0"&gt;&amp;#8220;x-shader/x-fragment&amp;#8221;&lt;/span&gt;&lt;span class="sy0"&gt;&amp;gt;&lt;/span&gt;   &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;        uniform sampler2D mapIndex&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;        uniform sampler2D lookup&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;        uniform sampler2D outline&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;        uniform float outlineLevel&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;        varying vec3 vNormal&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;        varying vec2 vUv&lt;span class="sy0"&gt;;&lt;/span&gt;      &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;        &lt;span class="kw1"&gt;void&lt;/span&gt; main&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt;                          &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;               &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;                vec4 mapColor &lt;span class="sy0"&gt;=&lt;/span&gt; texture2D&lt;span class="br0"&gt;(&lt;/span&gt; mapIndex&lt;span class="sy0"&gt;,&lt;/span&gt; vUv &lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="sy0"&gt;;&lt;/span&gt;    &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;                float indexedColor &lt;span class="sy0"&gt;=&lt;/span&gt; mapColor.&lt;span class="me1"&gt;x&lt;/span&gt;&lt;span class="sy0"&gt;;&lt;/span&gt;       &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;                vec2 lookupUV &lt;span class="sy0"&gt;=&lt;/span&gt; vec2&lt;span class="br0"&gt;(&lt;/span&gt; indexedColor&lt;span class="sy0"&gt;,&lt;/span&gt; &lt;span class="nu0"&gt;0&lt;/span&gt;. &lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;                vec4 lookupColor &lt;span class="sy0"&gt;=&lt;/span&gt; texture2D&lt;span class="br0"&gt;(&lt;/span&gt; lookup&lt;span class="sy0"&gt;,&lt;/span&gt; lookupUV &lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="sy0"&gt;;&lt;/span&gt;                              &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;                float mask &lt;span class="sy0"&gt;=&lt;/span&gt; lookupColor.&lt;span class="me1"&gt;x&lt;/span&gt; &lt;span class="sy0"&gt;+&lt;/span&gt; &lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="nu0"&gt;1&lt;/span&gt;.&lt;span class="sy0"&gt;-&lt;/span&gt;outlineLevel&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="sy0"&gt;*&lt;/span&gt; indexedColor&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;                mask &lt;span class="sy0"&gt;=&lt;/span&gt; clamp&lt;span class="br0"&gt;(&lt;/span&gt;mask&lt;span class="sy0"&gt;,&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;.&lt;span class="sy0"&gt;,&lt;/span&gt;&lt;span class="nu0"&gt;1&lt;/span&gt;.&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;                float outlineColor &lt;span class="sy0"&gt;=&lt;/span&gt; texture2D&lt;span class="br0"&gt;(&lt;/span&gt; outline&lt;span class="sy0"&gt;,&lt;/span&gt; vUv &lt;span class="br0"&gt;)&lt;/span&gt;.&lt;span class="me1"&gt;x&lt;/span&gt; &lt;span class="sy0"&gt;*&lt;/span&gt; outlineLevel&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;                float diffuse &lt;span class="sy0"&gt;=&lt;/span&gt; mask &lt;span class="sy0"&gt;+&lt;/span&gt; outlineColor&lt;span class="sy0"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;                gl_FragColor &lt;span class="sy0"&gt;=&lt;/span&gt; vec4&lt;span class="br0"&gt;(&lt;/span&gt; vec3&lt;span class="br0"&gt;(&lt;/span&gt;diffuse&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="sy0"&gt;,&lt;/span&gt; &lt;span class="nu0"&gt;1&lt;/span&gt;.  &lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="sy0"&gt;;&lt;/span&gt;                                             &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt; &lt;/div&gt;
&lt;/li&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;        &lt;span class="br0"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class="li2"&gt;
&lt;div class="de2"&gt;&lt;span class="sy0"&gt;&amp;lt;/&lt;/span&gt;script&lt;span class="sy0"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;img align="middle" height="861" src="http://i.imgur.com/55uiY.png" width="1624"/&gt;&lt;/p&gt;
&lt;p&gt;The next problem I needed to tackle was the &amp;#8216;country markers&amp;#8217;, which were planned to include country names. Originally I used a crappy custom-written SVG-pinning library I wrote for shits and giggles. This allowed me to see what 2D HUD elements looked like on the globe.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="538" src="http://i.imgur.com/i66n9.png" width="1462"/&gt;&lt;/p&gt;
&lt;p&gt;The 2D elements are really dom elements since I didn&amp;#8217;t want to render any type or solve those kinds of issues in WebGL, this is what the web is best for, after-all. The trick would be to translate the 3D position to 2D screen space position and then use CSS to place it correctly.&lt;/p&gt;
&lt;p&gt;The following snippet does the conversion, using THREE.js&amp;#8217;s projector class.&lt;/p&gt;
&lt;pre&gt;function screenXY(vec3){
	var projector = new THREE.Projector();
	var vector = projector.projectVector( vec3.clone(), camera );
	var result = new Object();
	result.x = Math.round( vector.x * (window.innerWidth/2) ) + window.innerWidth/2;
	result.y = Math.round( (0-vector.y) * (window.innerHeight/2) ) + window.innerHeight/2;
	return result;
}	
&lt;/pre&gt;
&lt;div&gt;then&amp;#8230;&lt;/div&gt;
&lt;pre&gt;var matrix = rotating.matrixWorld;
var abspos = matrix.multiplyVector3( country.center.clone() );
var screenPos = screenXY(abspos);&lt;/pre&gt;
&lt;p&gt;and now we can give it to the element&amp;#8217;s css style left and top for placement.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="859" src="http://i.imgur.com/tHreB.jpg" width="1628"/&gt;&lt;/p&gt;
&lt;p&gt;Eventually I replaced the crappy SVG lib with just straight dom spans as markers, and started adding typography so we can see the country names. There&amp;#8217;s also a few tricks to figuring out the sizing, occlusion behind the globe, and LODing, but I won&amp;#8217;t cover that here. You can see this in &lt;a href="http://arms.dat-friends.appspot.com/js/markers.js" target="_blank"&gt;markers.js&lt;/a&gt; the (ugly) logic behind this.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;ll recall the color-space was being used initially to represent countries. Now that we have a much cleaner country separation, we could use color to represent other things. At first I tried using color to represent weapons categories, but this lead to problems due to additive blending, which tend to output a rainbow splash instead of anything visually useful.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="857" src="http://i.imgur.com/jBfXb.png" width="1626"/&gt;&lt;/p&gt;
&lt;p&gt;We finally decided to distill (simplify) the color space down to two colors and represent purely imports and exports and upon reflection this was probably the wisest choice decision I&amp;#8217;ve made in my career doing data viz. It&amp;#8217;s still imperfect, since the colors do tend to merge (and I stubbornly refuse to give up on additive blending, &lt;a href="http://i.imgur.com/ovXgR.png"&gt;see this image for comparison&lt;/a&gt;), but the end result strikes a decent balance between aesthetics and actual utility.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="817" src="http://i.imgur.com/1ANo7.png" width="1629"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="860" src="http://i.imgur.com/8N3FL.png" width="1630"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="859" src="http://i.imgur.com/eW7as.png" width="1629"/&gt;&lt;/p&gt;
&lt;p&gt;Our team hired &lt;a href="http://www.pitchinteractive.com/" target="_blank"&gt;Pitch Interactive&lt;/a&gt; to complete the remaining UI elements which &amp;#8216;completes&amp;#8217; the visualization, including bar graphics for import export and category comparisons, filtering options, and a timeline scrubber with a historical graph showing change over time. &lt;/p&gt;
&lt;p&gt;I wish I could talk even more on Robert Muggah&amp;#8217;s investigation of the data, listening to him talk about it is really jaw-dropping since he can point out global conflicts directly on the visualization, for example in 1999 the arms race between India and Pakistan causing a gigantic spike in ammunition sales from Russia to India, or how depending on the country you can tell the exact brand of pistol or rifle (eg if it came from Italy vs Germany). &lt;/p&gt;
&lt;p&gt;Here are images from the INFO event in Los Angeles featuring this visualization. Photos courtesy of Google.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="460" src="http://i.imgur.com/kBFSO.jpg" width="689"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="460" src="http://i.imgur.com/F0kW0.jpg" width="689"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="460" src="http://i.imgur.com/tXDSG.jpg" width="689"/&gt;&lt;/p&gt;
&lt;p&gt;Overall I&amp;#8217;m pretty happy with the way the visualization turned out. It was a pretty classic &amp;#8220;make this data look sexy&amp;#8221; exercise, and as much technical hurdle as it was, the project itself was very very straightforward. &lt;/p&gt;</description><link>http://mflux.tumblr.com/post/28367579774</link><guid>http://mflux.tumblr.com/post/28367579774</guid><pubDate>Mon, 30 Jul 2012 16:05:00 -0700</pubDate></item><item><title>EyeO Wrap-up Part 2</title><description>&lt;p&gt;&lt;p class="p1"&gt;&lt;img alt="Robert Hodgin giving a talk at EyeO" height="525" src="http://i.imgur.com/SL2w6.jpg" width="700"/&gt;&lt;/p&gt;
&lt;p class="p1"&gt;When I ask attendees what their favorite talk was &amp;#8212; most pointed to &lt;a href="http://www.flight404.com/blog/"&gt;Robert (Flight404) Hodgin&amp;#8217;s&lt;/a&gt; presentation. It was a real delight watching his new simulations presented and packaged up so neatly, lens-flare, lipsticks and all. I remember someone telling me off-hand that perhaps, of all speakers, Robert prepared the most of anyone. It really shows. I&amp;#8217;m eagerly waiting for the EyeO video archives to be placed online so that you too can see his latest stuff.&lt;/p&gt;
&lt;p class="p1"&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p class="p1"&gt;One thing I want to note was his &amp;#8220;Cornell box&amp;#8221; that he presented all his simulations in. I often did similar things when writing software that required me to have a defined, three dimensional space &amp;#8212; it was really helpful to get a sense of scale, to have a ground. Robert takes this to the extreme, creating a Portal (the Valve game) like &amp;#8220;test chamber&amp;#8221; environment, typography and all, with a fluorescent overhead light that could be turned off at will.&lt;/p&gt;
&lt;p class="p1"&gt;Another aspect of Robert&amp;#8217;s presentations that I was really blown away by was the sound design he carefully paired the visuals with. Sound really does add 50% on top of the 100% rock solid visuals which were presented.&lt;/p&gt;
&lt;p class="p1"&gt;What really takes the cake was the humor and lighthearted-ness of it all. I don&amp;#8217;t want to ruin it for you, but by the end of the talk I&amp;#8217;ve really come to like party balloons.&lt;/p&gt;
&lt;p class="p2"&gt;&lt;img alt="Casey Reas talking about a C64 one line program" height="525" src="http://i.imgur.com/s2ccr.jpg" width="700"/&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;a href="http://reas.com/"&gt;Casey Reas&lt;/a&gt;&amp;#8217; talk was another highlight of EyeO. He had been the most important teacher in my university experience, and a guide to my subsequent career, so of course I had to sit front row and center. I sat there relaxed, and pretended to be once again in a UCLA D|MA lecture, soaking up wisdom and knowledge via osmosis.&lt;/p&gt;
&lt;p class="p2"&gt;&lt;img alt="Mississippi river" height="525" src="http://i.imgur.com/jpyUC.jpg" width="700"/&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;a href="http://www.aaronkoblin.com/"&gt;Aaron Koblin&lt;/a&gt; also gave a talk slash interview. He showed some up and coming work from Google Data Arts Team that I&amp;#8217;m part of, and was cool enough to give me some shoutouts and showed slides from some of my past work at Creative Lab. I&amp;#8217;m still eagerly waiting for a lot of this work to be released publicly so I can write more about it.&lt;/p&gt;
&lt;p class="p2"&gt;&lt;img align="middle" alt="Myself giving a show and tell at EyeO" height="768" src="http://i.imgur.com/MmtwZh.jpg" width="1024"/&gt;&lt;/p&gt;
&lt;p class="p1"&gt;Finally, I gave a quick five (ten? I forget) minute show and tell about my work with Google IO visuals and the sketches that led up to the final pieces. Hopefully in the next update or two I can talk more about them in detail.&lt;/p&gt;&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/24792714595</link><guid>http://mflux.tumblr.com/post/24792714595</guid><pubDate>Sat, 09 Jun 2012 21:11:00 -0700</pubDate></item><item><title>EyeO Wrap-up Part 1</title><description>&lt;p&gt;I&amp;#8217;m privileged to have the opportunity to visit EyeO and hang out with the likes of Casey Reas and Robert Hodgin. It&amp;#8217;s weird that our little &amp;#8220;shiny&amp;#8221; community has branched out and formed its own conference.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" alt="Casey Reas giving a talk at EyeO" height="481" src="http://i.imgur.com/uIM17.jpg" width="641"/&gt;&lt;/p&gt;
&lt;p&gt;At the risk of rambling, I just want to quickly write that I haven&amp;#8217;t blogged or tumblr&amp;#8217;d or wordpressed or whatever for god knows how long. After having attended EyeO I felt that the best way to connect with these technocrats was to share the work that we all love, and also have a space through which I can write about the process on my own work, be it procedural art or game dev.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" height="481" src="http://i.imgur.com/cPDRZ.jpg" width="641"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://unlekker.net/"&gt;Marius Watz&lt;/a&gt; also gave a thought provoking talk, part of which I want to muse about. He was talking about this notion of over-used algorithms, eg vornoi, flocking, etc in our medium, and how it&amp;#8217;s become a sort of cliche, a &amp;#8220;found object&amp;#8221; through which many artists simply snap screenshots and simply upload to flickr and call it a day. This reflected how myself and Aaron Koblin felt every time we&amp;#8217;re tasked to make &amp;#8220;yet another &amp;#8221; garbage flocking particle BS thing, and I feel like Marius summed up these thoughts quite well.&lt;/p&gt;
&lt;p&gt;However&amp;#8230; I also feel that 99.999% of the human population have no idea what a particle simulation is, or flocking, or iso-surfaces&amp;#8230; as much work as it is that one puts into something highly complex, the layman, the non &amp;#8220;technocrat&amp;#8221; (as Marius puts it) will simply look at it and go &amp;#8220;well.. that was cool&amp;#8221;, and that would be the end of the dialogue. &lt;/p&gt;
&lt;p&gt;I was talking to an editor Jason (&amp;#8230;forgot last name&amp;#8230;) from Wired Magazine during my lunch break. He laughed at this and compared it to comedians that either make jokes for other comedians, or jokes that are for the audience at large. I found this a somewhat apt analogy.&lt;/p&gt;
&lt;p&gt;Another thought was that, our medium simply does not have an audience sophisticated, or been around long enough, to make comparisons to identify what works are simple snapshots of &amp;#8220;found objects&amp;#8221; and what works are deeper and more fulfilling. To make yet another comparison, film and cinematography has been around for a hundred years and there has been enough time for audiences that want deeper, more interesting stories, or films, or cinematographic techniques. &lt;/p&gt;
&lt;p&gt;&lt;img align="middle" alt="Skyline Hall at Walker Art Center" height="606" src="http://i.imgur.com/ZIdWg.jpg" width="808"/&gt;&lt;/p&gt;
&lt;p&gt;I asked my colleague George Michael Brower about this, and if I may paraphrase&amp;#8230; &amp;#8220;we are in danger of making ourselves more and more insular&amp;#8221;, if we deny others to simply pick up and use &amp;#8220;found objects&amp;#8221;. He likens it to the chiptunes scene, where everyone in the audience also has their own chiptunes band.&lt;/p&gt;
&lt;p&gt;to be continued&amp;#8230;&lt;/p&gt;</description><link>http://mflux.tumblr.com/post/24711232534</link><guid>http://mflux.tumblr.com/post/24711232534</guid><pubDate>Fri, 08 Jun 2012 17:03:00 -0700</pubDate><category>eyeo</category><category>mariuswatz</category><category>caseyreas</category><category>processing</category><category>google</category><category>dataarts</category></item></channel></rss>
