<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Acko.net]]></title>
  <link href="http://acko.net/atom.xml" rel="self"/>
  <link href="http://acko.net/"/>
  <updated>2013-05-23T13:34:14-07:00</updated>
  <id>http://acko.net/</id>
  <author>
    <name><![CDATA[Steven Wittens]]></name>
    
  </author>

  
  <entry>
    <title type="html"><![CDATA[On WebGL]]></title>
    <link href="http://acko.net/blog/on-webgl/"/>
    <updated>2013-03-11T00:00:00-07:00</updated>
    <id>http://acko.net/blog/on-webgl</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'>

<h1>On WebGL</h1>
<h2>More than pretty pictures</h2>

<div style='display: none'><img alt='On WebGL' src='/files/on-webgl/cover.jpg' /></div>

<div class='c m2' />

<p>Like a dragon, WebGL slumbers. But you've seen them, right? Those seemingly magical demos that transform your ordinary browser into a lush 3D world with one click?</p>

<p>While available in Chrome and Firefox on the desktop, WebGL is still not widely supported. So far it's mostly used for demo projects and flashy one-off brochures. On the few mobile devices that support it, you need developer access to enable it. It's certainly nowhere near to being ready for prime time. So why should you care?</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a href='http://alteredqualia.com/three/examples/webgl_postprocessing_ssao.html' target='_blank'><img alt='City scene' src='/files/on-webgl/aq-ssao.jpg' /></a>
    <a class='credit' href='http://twitter.com/alteredq' target='_blank'>AlteredQualia</a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<h2>The Black Sheep</h2>

<p>The goal of WebGL is to bring the graphics capabilities of traditional apps and games into the browser, with performance as the main benefit. The graphics hardware does the work directly, leaving the CPU to just coordinate. Yet those developers look on with skepticism: "You mean we have to code in <em>JavaScript</em>?" There's grumbling about the limited capabilities too, which lag a few years behind the latest OpenGL and Direct3D APIs, and there's worries about copyright and modding.</p>

<p>First, we have to be honest: there's no question that native apps and 3D engines will continue to excel, bringing cutting edge graphics and performance. The layers of indirection in both HTML5 and WebGL cannot be circumvented.</p>

<p>But they do serve a purpose: to provide a safe sandbox for untrusted code from the web at large. Even triple-A games still occasionally crash, a result of their complexity, with thread synchronization, memory management and manual context-switching the price to pay. Random phishers shouldn't have that level of access to your system, nor should it be required.</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a href='http://alteredqualia.com/three/examples/webgl_loader_ctm_materials.html' target='_blank'><img alt='Car scene' src='/files/on-webgl/aq-loader.jpg' /></a>
    <a class='credit' href='http://twitter.com/alteredq' target='_blank'>AlteredQualia</a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<p>WebGL represents a different way of using high-performance graphics: not as a bare metal API with caveats, but as a safe service to be exposed, to be flicked on or off without a second thought. It may not sound like much, but the security implications are big and will only be solved carefully, over time. It's undoubtedly a big reason behind Apple and Microsoft's reluctance to embrace it.</p>

<p>We should also note that this isn't a one-way cross-over. HTML has already snuck into the real-time graphics scene. First we saw in-game web views and browsers, then UIs such as Steam's overlay. In fact, <em>all</em> of Steam is WebKit. The main benefit is familiarity: designers can use the well-known techniques of the web both inside and outside the game. This mirrors the way Adobe Flash entered the gaming space before, being used to drive menus and overlays in many games.</p>

<p>It's been said that the skills required for front-end web development and game development eventually converge on the same thing. The technologies certainly have.</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a href='http://cake23.de/turing-fluid.html' target='_blank'><img alt='Turing fluid patterns' src='/files/on-webgl/ck-cfd.jpg' /></a>
    <a class='credit' href='https://twitter.com/flexi23' target='_blank'>Felix Woitzel</a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<h2>The Procedural Canvas</h2>

<p>The web is the world's only universal procedural medium. Content is downloaded in partially assembled form, and you and your browser decide how it should be displayed. The procedural aspect has always been there, and today's practice of responsive design is just another evolution in procedural page layout. It all started with resizable windows and tables.</p>

<p>But when we decide to put a graphic into a page, we still bake it into a grid of pixels and send that down the pipe. This has worked great as a delivery mechanism, but is starting to show its age, due to high DPI displays and adaptive streaming.</p>

<p>It's also pushed the web further towards consumption: YouTube and Tumblr are obvious results. Both sites have a huge asymmetry between content creator and consumer, encouraging sharing rather than creating.</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a href='http://cake23.de/turing-pattern-gradient-attractor-feedback.html' target='_blank'><img alt='Turing pattern gradient attractor feedback' src='/files/on-webgl/ck-attract.jpg' /></a>
    <a class='credit' href='https://twitter.com/flexi23' target='_blank'>Felix Woitzel</a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<p>Real-time graphics level the playing field: once built, both creator and consumer have the same degree of control—at least in theory. All the work necessary to produce the end result is ideally being done 60 times per second. The experience of e.g. playing a game is like a sort of benign DRM, which requires you to access the content in a certain way. All native apps implement such 'DRM' by accident: their formats are binary and often proprietary, the code is compiled. Usually modding is supported in theory—that's what <em>Downloadable Content</em> is, an official mod—but the tools simply aren't included.</p>

<p>The web is different. No matter how obfuscated, all code eventually has to talk to an interface that is both completely open and introspective. You can hook into any aspect of it and watch the data. There isn't a serious web developer around who would argue that this is a bad thing, who hasn't spent time deconstructing a site through a web inspector on a whim.</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a href='http://codeflow.org/webgl/deferred-irradiance-volumes/www/' target='_blank'><img alt='Deferred irradiance volumes' src='/files/on-webgl/fb-div.jpg' /></a>
    <a class='credit' href='http://twitter.com/pyalot' target='_blank'>Florian Bösch</a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<p>This is where WebGL gets interesting. It takes the tools normally reserved for well, the hardcore geeks, and makes them much more open and understandable. I can certainly say from experience that coding with an engine like Three.js is an order of magnitude more productive than e.g. Ogre3D in C++. For most of the things I want to do with it, the performance difference is negligible, but there is much less code. Once you get your dev environment going, creating a new 3D scene is as simple as opening a text file. You can interact with your code live through the console for free.</p>

<p>More so, it integrates with the publishing tools we already know. I wonder for example how many hours of dev time the game industry has spent reinventing the wheel for fonts, menus, option screens, etc. To be fair, they often do so with amazing production value. But guess what: you now have CSS 3D, and soon you'll have CSS shaders. You don't need custom in-house tools when your designers can just use Chrome's Inspector and get the exact same result. Content delivery is easy: you have cloud storage, CDNs and memory caches at your disposal.</p>

<p>There is a missing link however: WebGL is a canvas inside the DOM, isolated from what's outside. But you could imagine APIs to help bring DOM content into a WebGL texture, taking over responsibility for drawing it. After all, most web browsers already use hardware acceleration to compose 2D web pages on screen. The convergence has already started.</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a alt='Landscape erosion simulation' href='http://codeflow.org/webgl/craftscape/' target='_blank'><img src='/files/on-webgl/fb-erode.jpg' /></a>
    <a class='credit' href='http://twitter.com/pyalot' target='_blank'>Florian Bösch</a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<p>The web has a history of transformative changes. CSS gave us <a href='http://csszengarden.com/'>real web design</a>, Flash gave us <a href='http://youtube.com/'>ubiquitous video</a>, Firebug gave us <a href='https://developers.google.com/chrome-developer-tools/'>Web Inspectors</a>, jQuery gave us <a href='http://sizzlejs.com'>non-painful DOM manipulation</a>, and so on. None of these ideas were new in computing when they debuted, the web merely adapted to fill a need. WebGL is an idea in a similar vein, a base platform for an ecosystem of specialized frameworks on top.</p>

<p>It can help lead to a WolframAlpha-ized <a href='http://en.wikipedia.org/wiki/LCARS'>LCARS future</a>, where graphics can be interactive and introspective by default. Why shouldn't you be able to click on a news graphic to filter the view, or download the dataset? For sure, this is not something that uniquely requires WebGL, and tools like d3.js are already showing the way with CSS and SVG. As a result, the <em>last mile</em> of interactivity becomes a mere afterthought: everything is live anyway. What WebGL does is raise the limit significantly on what sort of content can be displayed in a browser. It's not until those caps are lifted that we can say with a straight face that web apps can rival native apps.</p>

<p>Still, we shouldn't be aiming to recreate Unreal Engine in HTML / JS / GL, though someone will probably try, and eventually succeed. Rather we should explore what happens when you put a 3D engine inside a web page. Is it web publishing, or demoscene? Does it matter?</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2 tc'>
    <a href='http://www.ro.me/tech/hatching-glow-shader' target='_blank'><img alt='Stylistic cross hatch effect' src='/files/on-webgl/rm-crosshatch.jpg' /></a>
    <a class='credit' href='http://www.ro.me/tech/' target='_blank'>Ro.me team</a>
    <a alt='CSS 3D periodic table' href='http://mrdoob.github.com/three.js/examples/css3d_periodictable.html' target='_blank'><img src='/files/on-webgl/db-css3d.jpg' /></a>
    <a class='credit' href='http://twitter.com/mrdoob' target='_blank'>Mr.doob</a>
    <a href='http://workshop.chromeexperiments.com/projects/armsglobe/' target='_blank'><img alt='Chrome Workshop - Globe' src='/files/on-webgl/ch-globe.jpg' /></a>
    <a class='credit' href='http://workshop.chromeexperiments.com' target='_blank'>Chrome Workshop</a>
    <a alt='How to Fold a Julia Fractal - Complex math' href='http://acko.net/blog/how-to-fold-a-julia-fractal/' target='_blank'><img src='/files/on-webgl/ucd-julia.jpg' /></a>
    
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<h2>A Useful Baseline</h2>

<p>In this light, WebGL's often lamented limitation becomes its strength. WebGL is not modelled after 'grown-up' OpenGL, but mirrors OpenGL ES (Embedded Systems). It's a suite of functionality supported by most mobile devices, but eclipsed by even the crummiest integrated laptop graphics from 3 years ago.</p>

<p>This needn't be a worry for two reasons. First, WebGL supports extensions, which add to the functionality and continue to be specced out. A WebGL developer can inspect the capabilities of the system and determine an appropriate strategy to use. Many extensions are <a href='http://webglstats.com'>widely supported</a>, and even without extensions, all GL code is already subject to the platform's size limits on resources. WebGL is no different from other APIs, it just puts the bar a bit lower than usual.</p>

<p>Second of all, it means WebGL is the only 3D API that has a shot at being universal, from desks to laps to pockets to living rooms, and everything in between. Your game console could be an Android computer, handheld or appliance. Your TV might run Linux or iOS. So might your fridge. WebGL fits with where hardware and software is going, and adapting to various devices is nothing new for the web. I imagine we might see a standardized benchmark library pop up, and developer tools to make e.g. desktop Chrome mimic a cellphone's limited capabilities. </p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a href='http://acko.net/files/never-seen-the-sky/git/' target='_blank'><img alt='Never Seen The Sky - WebGL Demo' src='/files/on-webgl/ucd-aurora.jpg' /></a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<p>For the Christmas demo above, I included a simple benchmark that pre-selects the demo resolution based on the time needed to generate assets up front. Additionally, it was built on a 4 year old laptop GPU, so it should run well for the majority of viewers on first viewing. The same can't be said for cutting-edge demoscene demos, which often only run smoothly on top of the line hardware. I know I'm usually resigned to watching them on YouTube instead. As neat as tomorrow's tech is, for most people it only matters what they have today.</p>

<p>This is the biggest philosophical difference between WebGL and OpenGL. WebGL aims to be a good enough baseline that you can carry in your pocket as well as put on a big screen, and make accessible with a simple link. I don't expect graphics legends like John Carmack to take anything but a cursory glance at it, but then, it's not encroaching on his territory. It is a bit surprising though that the demoscene hasn't taken to the web more quickly. It has never been about having top of the line hardware, only what you use it for. Contests like JS1K continue to demonstrate JavaScript's expressiveness, but we haven't really seen the bigger guns come out yet.</p>

<p>And it really is <em>good enough</em>. Here's 150,000 cubes, made out of 1.8 million triangles:</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a alt='150000 cubes' href='http://alteredqualia.com/three/examples/webgl_cubes.html' target='_blank'><img src='/files/on-webgl/aq-cubes.jpg' /></a>
    <a class='credit' href='http://twitter.com/alteredq' target='_blank'>AlteredQualia</a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<p>Next up is a fractal raytracer. At 30 frames per second, 512x512 pixels, 40 iterations per pixel, each folding 3D space 18 levels deep… that's 5.6 <em>billion</em> folds per second. This intricate visualization is little more than raw number crunching power. That's just the core loop and excludes set up and lighting. It's all driven by a couple kilobytes of JavaScript wrapped in some HTML, delivered over HTTP.</p>

</div></div><div class='c' /><div class='recessed'>
  <div class='imagefit m2'>
    <a href='http://acko.net/files/on-webgl/whittaker/raytrace-creepy.html' target='_blank'><img alt='Distance estimation with fractals' src='/files/on-webgl/ucd-de.jpg' /></a>
  </div>
</div><div class='g8 i2 m2'><div class='pad'>

<p>Why wouldn't you want to play with that? Come try WebGL, <a href='http://madebyevan.com/webgl-water/' target='_blank'>the water's fine</a>.</p>

<h2>Further reading</h2>

<ul>
  <li>Paul Lewis' <a href='http://aerotwist.com/tutorials/getting-started-with-three-js/'>excellent tutorials</a> on Three.js. He also runs the <a href='http://thewebglpodcast.com'>WebGL podcast</a>.</li>
  <li>The <a href='https://www.udacity.com/course/cs291'>Interactive 3D graphics</a> WebGL course on Udacity by Eric Haines.</li>
  <li>The <a href='https://www.shadertoy.com'>ShaderToy</a> and <a href='http://glsl.heroku.com'>GLSL</a> sandboxes.</li>
  <li>The <a href='https://twitter.com/search?q=webgl'>WebGL hashtag on Twitter</a>.</li>
</ul>

<p><em>Examples by the amazing <a href='http://twitter.com/alteredq'>AlteredQualia</a>, <a href='https://twitter.com/flexi23'>Felix Woitzel</a>, <a href='http://twitter.com/pyalot'>Florian Bösch</a>, the <a href='http://www.ro.me/tech/'>Ro.me team</a>, <a href='http://twitter.com/mrdoob'>Mr.doob</a>, <a href='http://workshop.chromeexperiments.com'>Chrome Workshop</a>, as well as myself. Many of these techniques are documented on <a href='http://www.iquilezles.org/'>Iñigo Quilez</a>'s comprehensive site.</em></p>

<p><em>Additional demos and comments are welcome on <a href='https://plus.google.com/112457107445031703644/posts/4qcrPNzEVjk'>Google Plus</a>.</em></p>
 
</div></div>]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Making MathBox]]></title>
    <link href="http://acko.net/blog/making-mathbox/"/>
    <updated>2012-11-14T00:00:00-08:00</updated>
    <id>http://acko.net/blog/making-mathbox</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'>

  <h1>Making MathBox</h1>
  <h2>Presentation-Quality Math with Three.js and WebGL</h2>

</div></div><div class='c' /><aside class='g4'><div class='pad tc'>
  <iframe class='mathbox' height='600' src='/files/mathbox/MathBox.js/examples/ProjectiveLine.html?80403e38' />
  A fun little graph involving rational functions on the <a href='http://en.wikipedia.org/wiki/Real_projective_line'>real projective line</a>.
</div></aside><div class='g8'><div class='pad'>

  <p>For most of my life, I've found math to be a visual experience. My math scores went from crap to great once I started playing with graphics code, found some demoscene tutorials, and realized I could reason about formulas by picturing the graphs they create. I could apply operators by learning how they morph, shift, turn and fold those graphs and create symmetries. I could remember equations and formulas more easily when I could layer on top the visual relationships they embody. I was less likely to make mistakes when I could augment the boring symbolic manipulation with a mental set of visual cross-checks.</p>

  <p>So, when tasked with holding a conference talk on <a href='http://www.youtube.com/watch?v=ONN3jBly364'>how to make things out of math</a> at <a href='http://www.full-frontal.org'>Full Frontal</a>, I knew the resulting presentation would have to consist of intricate visualizations as the main draw, with whatever I had to say as mere glue to hold it together.</p>

  <p>The problem was, I didn't know of a good tool to do so, and creating animations by hand would probably be too time consuming. With the writings of <a href='http://www.maa.org/devlin/LockhartsLament.pdf'>Paul Lockhart</a> and <a href='http://worrydream.com/KillMath/'>Bret Victor</a> firmly in mind, I also knew I wanted to start blogging more about mathematical concepts in a non-traditional way, showing the principles of calculus, analysis and algebra the way I learnt to see them in my head, rather than through the obscure symbols served up in engineering school.</p>

  <p>So I set out to create that tool, keeping in mind the most important lesson I've picked up as a web developer: one cannot overstate the value in being able to send someone a link and have it just work, right there. It was obvious it would have to be browser-based.</p>

</div></div><aside class='g4 i2 c'><div class='pad'>
  <p class='tc'>
    <a href='http://www.youtube.com/watch?v=ONN3jBly364&amp;list=UUyBAm31tEpZ17hka6ZvVqcg&amp;index=2&amp;feature=plcp'>
    <img alt='Video' src='/files/fullfrontal/video.jpg' style='top: 0' />
    Conference Video
    </a>
  </p>
</div></aside><aside class='g4'><div class='pad'>
  <p class='tc'>
    <a href='http://acko.net/files/fullfrontal/fullfrontal/slides-net/'>
    <img alt='Slides' src='/files/fullfrontal/slides.png' style='top: 0; -webkit-box-shadow: 0 2px 10px rgba(0, 0, 0, .3); -moz-box-shadow: 0 2px 10px rgba(0, 0, 0, .3); box-shadow: 0 2px 10px rgba(0, 0, 0, .3);' />
    Slide Deck
    </a>
  </p>
</div></aside><div class='g8 i2 c'><div class='pad'>

  <h2>Choose your Poison</h2>

  <p>Now, when people think of graphs in a browser, the natural thought is vector graphics and SVG, which quickly leads to <a href='http://d3js.org'>visualization powerhouse d3.js</a>. It really is an amazing piece of tech with a vast library of useful code to accompany it. When I wrapped my head around how d3's enter/exit selections are implemented and how little it actually does to achieve so much, I was blown away. It's just so elegant and simple.</p>

  <p>Unfortunately, d3's core is intricately tied to the DOM through SVG and CSS. And that means ironically that d3 is not really capable of 3D. Additionally, d3 is a power tool that makes no assumptions: it is up to you to choose which visual elements and techniques to use to make your diagrams, and as such it is more like assembly language for graphs than a drop-in tool. These two were show stoppers.</p>

  <p>For one, manually designing layouts, grids, axes, etc. every time is tedious. You should be able to drop in a mathematical expression with as little fanfare as possible and have it come out looking right. This includes sane defaults for transitions and animations.</p>

</div></div><div class='g12'>
  <iframe class='mathbox' height='500' src='/files/mathbox/MathBox.js/examples/Intersections.html?80403e38' width='960' />
</div><div class='g7'><div class='pad'>

  <p>For another, I've found that, when in doubt, adding an extra dimension always helps. The moment I finally realized that every implicit graph in N dimensions is really just a slice of an explicit one in N+1 dimensions, a ridiculous amount of things clicked together. And it took until years after studying signal processing to at long last discover the 4D picture of complex exponentiation that tied the entire thing together (projected into 3D below): it revealed the famous "magic formula" involving e, i and π to be a meaningless symbological distraction, a pinhole view of a much larger, much more beautiful structure, underpinning every Fourier and Z transform I'd ever encountered.</p>

</div></div><aside class='g5 m1'><div class='pad'>
  <p class='tc'><big>
    e<sup>iπ</sup> = -1
  </big></p>
  <p class='tc'>This particular formula is not that important.</p>

  <p class='tc'><big>
    e<sup>x+iy</sup> = e<sup>x</sup> &middot; e<sup>iy</sup> = e<sup>x</sup> ∠ y
    
  </big></p>
  <p class='tc'>This one is (∠ = rotate by).<br />Unfortunately it has a four dimensional graph.</p>
  
</div></aside><div class='g12'>
  <iframe class='mathbox' height='500' src='/files/mathbox/MathBox.js/examples/ComplexExponentiation.html?80403e38' width='960' />
</div><div class='g8 i2'><div class='pad'>

  <p>So, WebGL it was, because I needed 3D. Unfortunately that meant the promise of having it just work everywhere was tempered by a lack of browser support, but I would certainly hope that's something we can overcome sooner than later. Dear Apple and Microsoft: get your shit together already. Dear Firefox and Opera: your WebGL performance could be a lot better.</p>

  <h2>Shady Dealings</h2>

  <p>These days I don't really touch WebGL without going through <a href='http://mrdoob.github.com/three.js/'>Three.js</a> first. Three.js is a wonderful, mature engine that contains tons of useful high-level components. At the same time, it also does a great job in just handling the boilerplate of WebGL while not getting in the way of doing some heavy lifting yourself.</p>

  <p>Rendering vector-style graphics with WebGL is not hard, certainly easier than photorealistic 3D. Primitives like lines and points are sized in absolute pixels by default, and with hardware multisampling for anti-aliasing, you get somewhat decent image quality out of it. Though, as is typical for a Web API, we're treated like children and can only cross our fingers and <em>request</em> anti-aliasing politely, hoping it will be available. Meanwhile native developers <a href='http://www.nvidia.com/object/coverage-sampled-aa.html'>have full control</a> over speed and quality and can adjust their strategy to the specific hardware's capabilities. The more things change... And then <a href='http://code.google.com/p/chromium/issues/detail?id=159275'>Chrome decided to disable anti-aliasing altogether</a> due to esoteric security issues with buggy drivers. Bah.</p>

  <p>Now, when rendering with WebGL, you really have two options. One is to just treat it as a dumb output layer, loading or generating all your geometry in JavaScript and rendering it directly in 3D. With the speed of JS engines today, this can get you pretty far.</p>

</div></div><div class='g7'><div class='pad'>
  <p>The second option is to leverage the GPU's own capabilities as much as possible, doing computations in GLSL through so-called vertex and fragment shader programs. These are run for every vertex in a mesh, every pixel being drawn, and have been the main force driving innovation in real-time graphics for the past decade. With the goal of butter-smooth 60fps graphical goodness, this seemed like the better choice.</p>

  <p>Unfortunately, GLSL shaders are rather monolithic things. While you do have the ability to create subroutines, every shader still has to be a stand-alone program with its own main() function. This means you either need to include a shader for every possible combination of operations, or generate shader code dynamically by concatenating pre-made snippets or using #ifdef switches to knock them out. This is the approach taken by Three.js, which results in some <a href='https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLShaders.js'>very hairy code</a> that is neither easy to read nor easy to maintain.</p>

  <p>Having made a prototype, I knew I wanted to show continuous transitions between various coordinate systems (e.g. polar and spherical), knew I needed to render shaded and unshaded geometry, and knew I would need to slot in specific snippets for things like point sprites, bezier curves/surfaces, dynamic tick marks, and more. Sorting this all out Three.js-style would be a nightmare.</p>

</div></div><aside class='g5'>
<p class='codeblock'>
<code>uniform sampler2D texture;
varying vec2 vUV;

void main() {
  gl_FragColor = texture2D(texture, vUV);
}
</code></p>
<p>
A pixel or fragment shader that looks up a pixel's color in a texture.
</p>
<p class='codeblock'>
<code>uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
attribute vec4 position;
attribute vec2 uv;
varying vec2 vUV;

void main() {
  vUV = uv;

  gl_Position = projectionMatrix
              * modelViewMatrix
              * position;
}
</code>
</p>
<p>
A vertex shader that projects a 3D position into 2D by applying two matrices. It also provides UV coordinates for the texture look up.
</p>
</aside><aside class='g4 c'>
<p style='top: 0;'><img src='/files/mathbox/shadergraph.png' style='width: 93%' /></p>
<p class='codeblock'>
<code>var graph =
  factory
    .snippet('split')
    .group()
      .snippet('top')
    .next()
      .snippet('middle')
    .next()
      .snippet('bottom')
    .combine()
    .snippet('join')
    .end();
</code></p>
<p>
ShaderGraph's factory API lets you build shader chains with very little hassle. In this case, the names refer to IDs of &lt;<strong>script</strong>&gt; tags in the source.
</p>
</aside><div class='g8'><div class='pad'>

  <p>So I wrote a library to solve that problem, called <a href='https://github.com/unconed/ShaderGraph.js'>ShaderGraph.js</a>. It is best described as a smart code-concatenator, a few steps short of writing a full blown compiler. You feed it snippets of GLSL code, each with one or more inputs and outputs, and these get parsed and turned into lego-like building blocks. Each input/output becomes an outlet, and outlets are wired up in a typical dataflow style. Given a graph of connected snippets, it can be compiled back into a program by assembling the subroutines, assigning intermediate variables and constructing an appropriate main() function to invoke them. It also exports a list of all external variables, i.e. GLSL uniforms and attributes, so you can control the program's behavior easily.</p>

  <p>If I'd stopped there however, I'd have just replaced the act of manual code writing with that of manually wiring graphs. So I applied the principle of convention-over-configuration instead: you tell ShaderGraph to connect two snippets, and it will automatically match up outlets by name and type. This is augmented by a chainable factory API, which allows you to pass a partially built graph around. It allows different classes to work together to build shaders, each inserting their own snippets into the processing chain.</p>
  
<p>For example, to render a Bezier surface, the vertex shader is composed of: cubic interpolation, viewport transform (position + tangents), normal calculation and lighting. When transforming to e.g. a polar viewport, the surface normals are seamlessly recalculated. It really works like magic and I can't wait to use this in my next WebGL projects.</p>

</div></div><div class='g8 i2'><div class='pad'>
  
  <h2>Viewports, Primitives and Renderables</h2>

  <p>At its core, Three.js matches pretty directly with WebGL. You can insert objects such as a Mesh, Line or ParticleSystem into your scene, which invokes a specific GL drawing command with high efficiency. As such, I certainly didn't want to reinvent the wheel.</p>

  <p>Hence, MathBox is set up as a sort of scene-manager-within-a-scene-manager. It's a little sandbox that speaks the language of math, allowing you to insert various <em>primitives</em> like curves, vectors, axes and grids. Each of these primitives then instantiates one or more <em>renderables</em>, which simply wrap a native Three.js object and its associated ShaderGraph material. Thus, once instantiated, MathBox gets out of the way and Three.js does the heavy lifting as normal. You can even insert multiple mathboxen into a Three.js scene if you like, mixed in with other objects.</p>

<p><img alt='MathBox Architecture' class='squeeze' src='/files/mathbox/MathBox.js/resources/architecture.png' style='margin-left: -10px;' /></p>

  <p>For example, a vector primitive is rendered as an arrow: it consists of a shaft and an arrowhead, realized as a line segment and a cone. An axis primitive is an arrow as well, but it also has tick marks (specially transformed line segments), and is positioned implicitly just by specifying the axis' direction rather than a start and end point.</p>

  <p>To render curves and surfaces, you can either specify an array of data points or a live expression to be evaluated at every point. This turned out to be essential for the kinds of intricate visualizations I wanted to show, my slides being driven by timed clocks, shared arrays of data points, and live formulas and interpolations. I even fed in data from a physics engine, and it worked perfectly.</p>

  <p>This is all tied together through Viewport objects, which define a specific mapping from a mathematical coordinate space into the 3D world space of Three.js. For example, the default cartesian viewport has the range [–1, 1] in the X, Y and Z directions. Altering the viewport's extents will shift and scale anything rendered within, as well as reflow grids and tick marks on each axis.</p>

  <p>There are two more sophisticated viewport types, polar and spherical, which each apply the relevant coordinate transform, and can transition smoothly to and from cartesian. More viewport types can be added, all that is required is to define an appropriate transformation in JavaScript and GLSL. That said, defining a seamless transition to and from cartesian space is not always easy, particularly if you want to preserve the aspect-ratio through the entire process.</p>

  <h2>Interpolate all the things!</h2>

  <p>Finally, I had to tackle the problem of animation, keeping in mind a tip I learnt from the <a href='http://www.youtube.com/watch?v=4gZ5rsAHMl4'>ever so mindbending Vihart</a>: "If I can draw the point of a sentence, I don't actually need to say the sentence." This applies doubly so for animation: every time you replace a "before" and "after" with a smooth transition, your audience implicitly understands the change rather than having to go look for it.</p>

  <p>Hence, each primitive can be fully animated. Each has a set of options (controlling behavior) and styles (controlling GLSL shaders), and there is a universal animator that can interpolate between arbitrary data types in a smart fashion.</p>

  <p>For example, given a viewport with the XYZ range [[–1, 1], [–1, 1], [–1, 1]], you can tell it to animate to [[0, 2], [0, 1], [–3, 3]], and it just works. The animator will recursively animate each subarray's elements, and any dependent objects like grids and axes will reflow to match the intermediate values. This works for colors, vectors and matrices too. In case of live curves with custom expressions, the animator will invoke both the old and the new, and interpolate between the results.</p>

</div></div><div class='g8 i2'>
  <iframe class='mathbox paged' height='400' src='/files/mathbox/MathBox.js/examples/BezierSurface.html?80403e38' width='640' />
</div><div class='g8 i2'><div class='pad'>
  <p>However, executing animations manually in code is tedious, particularly in a presentation, where you want to be able to step forward and backward. So I added a Director class whose job it is to coordinate things. All you do is feed it a script of steps (add this object, animate that object). Then, as it applies them, it remembers the previous state of each object and generates an automatic rollback script. It also contains logic to detect rapid navigation, and will hurry up animations appropriately. This avoids that agonizing situation of watching someone skip through their slide deck, playing the same cheesy PowerPoint transitions over and over again.</p>

  <h2>Presenting Naturally</h2>
  
  <p>With MathBox's core working, it was time to build my slides for the conference. After a quick survey, I quickly settled on <a href='http://imakewebthings.com/deck.js/'>deck.js</a> as an HTML5 slidedeck solution that was clean and flexible enough for my purposes. However, while MathBox can be spawned inside any DOM element, it wouldn't work to insert a dozen live WebGL canvases into the presentation. The entire thing would grind to a halt or at least become very choppy.</p>
  
  <p>So instead, I integrated each MathBox graphic as an IFRAME, and added some logic that only loads each IFRAME one slide before it's needed, and unloads it one slide after it's gone off screen. To sync up with the main presentation, all deck.js navigation events were forwarded into each active IFRAME using <em>window.postMessage</em>. With the MathBox Director running inside, this was very easy to do, and meant that I could skip around freely during the talk, without any worries of desynchronization between MathBox and the associated HTML5 overlays.</p>
  
  <p>In fact, I applied a similar principle to this post. To avoid rendering all diagrams simultaneously and spinning up laptop fans more than necessary, each MathBox IFRAME is started as it scrolls into view and stopped once it's gone.</p>
  
  <p>I've also found that having a handheld clicker makes a huge difference while speaking—as it allows you to gesture freely and move around. So, I grabbed the infrared remote code from VLC and built a <a href='https://github.com/unconed/iremotepipe/'>simple bridge</a> from to Cocoa to Node.js to WebSocket to allow the remote to work in a browser. It's a shame Apple's decided to discontinue IR ports on their laptops. I guess I'll have to come up with a BlueTooth-based solution when I upgrade my hardware.</p>

  <h2>Towards MathBox 1.0</h2>

  <p>In its current state, MathBox is still a bit rough. The selection of primitives and viewports is limited, and only includes the ones I needed for my presentation. That said, it is obvious you can already do quite a lot with it, and I couldn't have been happier to hear that all this effort had the desired response at the conference. I wasn't 100% sure whether other people would have the same a-ha moments that I've had, but I'm convinced more than ever that seeing math in motion is essential for honing our intuition about it. MathBox not only makes animated diagrams much easier to make and share, but it also opens the door to making them interactive in the future.</p>

  <p>I plan to continue to evolve MathBox as needed by using it on this site and addressing gaps that come up, though I've already identified a couple of sore points:</p>

  <ul>
  <li><span class='strike'><span>I used tQuery as a boilerplate and because I liked the idea of having a chainable API for this. However, this also means it's currently running off an outdated version of Three.js. I need to look into updating and/or dropping tQuery.</span></span><br />MathBox has been updated to Three.js r53.</li>
  <li><span class='strike'><span>Numeric or text labels are completely unsupported. It should be possible to use my CSS3D renderer for Three.js to layer on beautifully typeset <a href='http://www.mathjax.org'>MathJax</a> formulas, positioning them correctly in 3D on top of the WebGL render.</span></span><br />I've added labeling for axes. I've integrated MathJax, but it's tricky because the typesetting is painfully slow in the middle of a 60fps render. But it's automatically used if MathJax is present.</li>
  <li>All styles have to be specified on a per-object basis. Some form of stylesheet, default styles or class mechanism to allow re-use seems like an obvious next step.</li>
  <li>There are undoubtedly memory leaks, as I was focused first and foremost on getting it to work.</li>
  <li>Expressions that don't change frame-to-frame are still continuously re-evaluated, which is wasteful. There is a <code>live: false</code> flag you can set on objects, but it triggers a few bugs here and there.</li>
  <li><span class='strike'><span>There needs to be a predictable, built-in way of running a clock per slide to sync custom expressions off of. In my presentation I used a hack of clocks that start once first invoked, but this lacks repeatability.</span></span><br />I added a <code>director.clock()</code> method that gives you a clock per slide.</li> 
  </ul>

  <p>Finally, it doesn't take much imagination to imagine a MathBox Editor that would allow you to build diagrams visually rather than having to use code like I did. However, that's a can of worms I'm not going to open by myself, especially because the API is already quite straightforward to use, and the library itself is still a bit in flux. Perhaps this could be done as an extension of the <a href='http://mrdoob.github.com/three.js/editor/'>Three.js editor</a>.</p>

  <p>You can see what MathBox is really capable of in the <a href='http://www.youtube.com/watch?v=ONN3jBly364&amp;list=UUyBAm31tEpZ17hka6ZvVqcg&amp;index=2&amp;feature=plcp'>conference video</a>. I invite you to <a href='https://github.com/unconed/MathBox.js'>play around with MathBox</a> and see what you can make it do. Contributions are welcome, and the architecture is modular enough to allow its functionality to grow for quite some time.</p>

</div></div>]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Making Love to WebKit]]></title>
    <link href="http://acko.net/blog/making-love-to-webkit/"/>
    <updated>2012-01-09T00:00:00-08:00</updated>
    <id>http://acko.net/blog/making-love-to-webkit</id>
    <content type="html"><![CDATA[<div class='g8 i2 first'><div class='pad'>
  <h1>Making Love To WebKit</h1>
  <h2>Parallax, GPUs and Technofetishism</h2>

  <p>
    If the world is going to end in 2012, Acko.net will at least go out in style: I've redesigned. Those of you reading through RSS readers will want to <a href='http://acko.net/'>enter through the front door</a> in a WebKit-browser like Chrome, Safari or even an iPad.
  </p>

  <p class='bubble'>
    The last design was meant to feel spacious, the new design <em>is</em> spacious, thanks to generous use of CSS 3D transforms.
  </p>

  <h3>CSS 3D vs. WebGL</h3>
  
  <p>
    This idea started with an accidental discovery: if you put a CSS perspective on a scrollable &lt;DIV&gt;, then 3D elements inside that &lt;DIV&gt; will retain their perspective while you scroll. This results in smooth, native parallax effects, and makes objects jump out of the page, particularly when using an analog input device with inertial scrolling.
  </p>

  <p>
    This raises the obvious question: how far can you take it? Of course, this only works on WebKit browsers, who currently have the only CSS 3D implementation out of beta, so it's not a viable strategy by itself yet. IE10 and Firefox will be the next browsers to offer it. There's WebGL in Chrome and Firefox that can be used to do similar things, but WebGL is its own sandbox: you can't put DOM elements in there, or use native interaction. And any amount of WebGL rendering in response to e.g. scrolling is going to involve some amount of lag. Still, I wasn't going put a lot of effort into making a CSS 3D-only design without some backup.
  </p>

  <p>
    That's why I actually built the whole thing on top of <a href='https://github.com/mrdoob/three.js/'>Three.js</a>, mrdoob's excellent JavaScript 3D engine. Aside from providing a comprehensive standard library for 3D manipulation, it also lets you swap out the rendering component. Out of the box, it can render to a 2D canvas, a WebGL canvas, or SVG.
  </p>

</div></div><div class='g7'><div class='pad'>

  <h3>The DOM Scenegraph</h3>
  
  <p>
    So I augmented it with a CSS 3D renderer (<a href='https://github.com/unconed/CSS3D.js'>GitHub</a>). It reads out the scene and renders each object using DOM elements, shaped and transformed into the right 3D position, orientation and appearance. They sit ‘in’ the page, and the browser projects and composits them for you. Of course, this only works for simple geometric shapes like lines or rectangles, but luckily that's all I need.
  </p>
  
  <p>
    It would be too slow to have to render out new elements for every frame, so the CSS 3D renderer's elements persist. Moving or rotating an object involves just changing a CSS property. Same for the camera: the entire scene is wrapped in a &lt;DIV&gt; that has its own 3D transform.
  </p>

  <p>
    So it's VRML all over again, but this time, it actually sort of performs. With our browsers being actual 3D engines, it's not a huge leap from here to having a &lt;MESH&gt; tag in HTML6, can-of-worms-factor not withstanding.
  </p>

  <p>
    Having built a quick prototype, I was satisfied with how well it worked, particularly in Safari on OS X, where the cross-pollination from the iPhone's mature tile-based GPU renderer has clearly paid off and there is no lag at all.
  </p>

</div></div><aside class='g5'>
  <p class='m3'><img alt='CSS 3D DOM' src='/files/making-love-to-webkit/dom.png' />The DOM tree of this page. Yup, nasty.</p>
</aside><div class='c' /><aside class='g5'>
  <p class='m3'><img alt='Acko.net old design' src='/files/making-love-to-webkit/old-acko.png' />Previous design (<a href='/tag/acko.net'>Archive</a>)</p>
  <p><img alt='Initial sketch' src='/files/making-love-to-webkit/sketch.jpg' />Initial sketch</p>
  <p><img alt='Initial sketch' src='/files/making-love-to-webkit/editor.png' />Scene editor</p>
</aside><div class='g7'><div class='pad'>

  <h3>
    Design Process
  </h3>

  <p>
    Now all that was needed was a design. Last time I drew out a manual perspective drawing in Illustrator, which was tedious, but still basically came down to designing a flat image. This time, it would have to work in 3D. I started with a quick sketch to get a feel for the perspective, now that it no longer needed to double as a flat frame for the site's content.
  </p>
  
  <p>
    Simple geometric shapes, parallel lines, consistent angles. Simple enough. But if real perspective was involved, I would have to place items so they would look good from multiple angles, and each would need convincing depth and shading. To do this all by hand, typing out coordinates and perpetually refreshing the page, would take forever.
  </p>
  
  <p>
    So instead I built a simple editor to speed up the process. It's super ghetto, and basically just exists to manipulate the colors, positions and orientations of objects in a Three.js scene. It spits out a JSON object describing them, which can then be unserialized again into a scene.
  </p>

  <p>
    This also helped maintain a consistent palette. The colors are built from a few base tints, brightened or darked in linear RGB—i.e. before gamma correction. This ensures even tones and allowed for easy color adjustments.
  </p>

  <p>
    The editor is almost entirely keyboard operated, but with its minimum amount of features I was at least able to place items in 3D, copy/paste objects and see it from any angle or position I wanted. To 'save', I just copied the output into a .JS file, where I could make manual tweaks too if necessary.
  </p>

  <p>
    As for the actual site and content, I wanted to keep it much more sober. Like many others these days, I want to treat blogging more like publishing. That way I can focus on crafting each post more like an article with illustrations and asides rather than just a text blog.
  </p>
    
  <p>
    Hence, while there's a big party upstairs, it's all <a href='http://www.amazon.com/Elements-Typographic-Style-Robert-Bringhurst/dp/0881791326'>typography</a> down below. The font of choice is <a href='http://processtypefoundry.com/fonts/klavika/'>Klavika</a>, a humanist/geometric sans-serif with just the right kind of “Dutch Art Museum Signage” meets “Cyberpunk” I was looking for. The layout is a responsive multi-column grid that collapses down for smaller screens and devices. Finally, a strict vertical rhythm is enforced in the lines to keep everything nice and tidy.
  </p>
  
</div></div><div class='g9'><div class='pad'>
  <h4>Editor</h4>
  <iframe frameborder='0' height='580' src='/load.html' width='680' />
  <p class='m0 l0'>
    <a class='editor-open' href='/editor.html' target='_blank'>Open editor in new window</a>
  </p>
</div></div><div class='g3'><div class='pad'>
  <h4>Controls</h4>
  <ul class='flat'>
    <li><kbd>Click</kbd>+<kbd>Drag</kbd> — Orbit camera</li>

    <li><kbd>Enter</kbd> — New object</li>
    <li><kbd>Space</kbd> — Clone object</li>
    <li><kbd>Backspace</kbd> — Delete object</li>
    <li><kbd>Tab</kbd> / <kbd>Shift</kbd>+<kbd>Tab</kbd><br />Cycle through objects</li>

    <li><kbd>W</kbd><kbd>A</kbd><kbd>S</kbd><kbd>D</kbd>&nbsp; <kbd>Q</kbd><kbd>E</kbd><br />Move object</li>
    <li><kbd>Shift</kbd>+<kbd>W</kbd><kbd>A</kbd><kbd>S</kbd><kbd>D</kbd> &nbsp; <kbd>Q</kbd><kbd>E</kbd><br />Resize object</li>
    <li><kbd>Ctrl</kbd>+<kbd>W</kbd><kbd>A</kbd><kbd>S</kbd><kbd>D</kbd> &nbsp; <kbd>Q</kbd><kbd>E</kbd><br />Move camera</li>

    <li><kbd>[</kbd><kbd>]</kbd> — Lower/raise units</li>
    <li><kbd>Z</kbd><kbd>X</kbd><br />Orbit distance</li>
    <li><kbd>T</kbd>/<kbd>T</kbd>/<kbd>U</kbd><br />Tag/untag/untag all</li>
  </ul>
</div></div><div class='g8 i2'><div class='pad'>
  <h3>She cannae take the power cap'n!</h3>
  <p>
    307 objects later it was finished, and not a single image was used. Unfortunately, as you can see there are tons of glitches in the editor—though some objects only have one side by design, and it works a lot better in a separate window. CSS 3D was never meant to do this, and you often see incorrect depth layering and flickering. Luckily most of these are caused by the floating grid markers and aren't a problem in the final view. The rest was resolved by splitting up objects or dual layering problematic surfaces, but some minor problems remain. Also for some reason, the background &lt;DIV&gt;'s click areas extend beyond their visible area, causing some click layering issues that I had to work around. Text resizing in the browser also leads to breakage, though multi-touch zoom works in Safari.
  </p>
  
  <p>
    Performance in Safari is wonderfully smooth too, but Chrome OS X starts to lag a bit. Luckily the effects are turned off as soon as they go off screen, so any lag should be confined to the top of the page. Finally, there's also a random bug where sometimes the page will refuse to scroll if the mouse is over a 3D object, which is unfortunate, but also near-impossible to reproduce reliably.
  </p>
  
  <p>
    In theory the iPad would perform second, but it has its own issues. The use of page-in-page scrolling disables inertia, but this is entirely beyond my control. The other issue is that sometimes, the iPad will decide to render the page content at lower resolution, making it hard to read. I guess the CSS wizardry confuses its GPU texture management. A refresh usually fixes this.
  </p>
  
  <p>
    I also discovered some funny ways of abusing CSS 3D for weird effects. If you have a WebKit browser, scroll to the top and enter the Konami code for an impressionistic version of the same thing.
  </p>
    
  <p>
    I guess I'm now the proud owner of the first unofficial CSS 3D ‘ACID’ test. I'm eager to see how the next browser handles it. If it ends up being a silly idea in the long run, I can always just switch the output to WebGL, but for now I'm willing to run with it. I put in a universal CSS 3D detector and prefixes for all the major browsers.
  </p>
  
  <p>
    For non-CSS 3D browsers, I simply rendered the header into a static image. It's not as fun without the shifting perspective, but it adds its own kind of optical illusion as you scroll down.
  </p>
  
  <h3>
    Putting it all together
  </h3>
  
  <p>
    To power the site, I got rid of Drupal and replaced it with the nimble <a href='http://jekyllrb.com/'>Jekyll</a>. Hat tip to <a href='http://walkah.net/'>James Walker</a>, who did the same thing just a few days earlier and put all the code on GitHub to learn from.
  </p>
    
  <p>
    I've been really impressed with Jekyll's simple workflow, and though it's all static HTML, it's a refreshing change of pace. And thanks to client-side JS, it doesn't preclude adding interactive elements at all. I can treat my site as just a database of documents retrievable over HTTP, and wrap the logic around that.
  </p>
  
  <p>
    So I created a nice client-side navigator that transitions between pages, using 2D transforms, which also work on Firefox. It uses the HTML5 pushState API and replaces regular links with AJAX requests. Aside from being a faster way to navigate around, it also lets me link up multiple articles in a series elegantly. When you go back to a previous screen, it literally presses the browser's back button, thus avoiding creating a long, useless history trail. You go back exactly the way you came, scrolling back to where you were, just like the real back/forward buttons do. For example, click over to my <a href='/blog/making-worlds-introduction/'>Making Worlds</a> series of posts. You can come back right away.
  </p>
  
  <p>
    I didn't use any libraries or router frameworks for this, simply because I wanted to have done it all myself at least once. As it now says on my <a href='/about'>About page</a>, quoting Feynman: <em>"What I cannot create, I do not understand"</em>. The only way to grok the intricacies of something like browser history state, which we all use every day, is to dive in and replicate it. Otherwise, you'll just take carefully choreographed behavior for granted and your mental model will be incomplete.
  </p>

  <p>
    To keep code size down, I compiled a custom build of Three.js with only the parts I need. I also used YUI compressor to minify the CSS and JS. However, I don't mean to obfuscate the code: the important bits will make their way onto Github soon enough.
  </p>
  
  <p><em>Update: The CSS 3D renderer and editor are now <a href='https://github.com/unconed/CSS3D.js'>available on GitHub</a>.</em></p>
  
  <h3>
    And Done?
  </h3>

  <p>
    I migrated over most of the content and did some house cleaning while I was at it. Most things should be back, but further fixes will be made. I also haven't implemented any commenting solution so far, but I'll be adding it back somehow as soon as I figure something out. In the mean time, there's <a href='https://plus.google.com/112457107445031703644/posts/HDJMgpDRAey'>a Google Plus thread</a>.
  </p>

  <p>
    The final result looks like something that would perhaps once unironically be labeled <strong>The Information Superhighway</strong> in a magazine from the 90s, though with less neon green. I like it.
  </p>

</div></div>]]></content>
  </entry>
  
</feed>
