Experiments behind “It Came Upon”

It has really awhile now, but I thought ok, we need to finish this – otherwise all these would probably be left in dust, and I’ll never proceed. So here is it, trying to finish touching on some of the technical aspects continuing from the post about “It came upon”.

Not all things were probably not done the best, nor right way, but there’s some hope that documenting it anyways might benefit someone, at the least myself in future looking back. There are many elements in that demo, so let me try listing the points in the order they appeared.

1. Dialog Overlays

Image and video hosting by TinyPic

The first thing after landing on the main page is a greeting contained in a dialog. Yes, dialogs like this are common on the net, but guess so different about this? Partially correct, if you are guessing rounded border radius without images using CSS3.

What I wanted to achieve was also a minimalistic javascript integration that is, no more checking for browser dimensions and javascript calculations. I thought that using the new css3 box model would work, but it was giving me headaches across browsers that I rely on a much older technology which actually works – table style. This allows the content to be centered nicely, and the only width I had to (or maybe even not) specified was the dialog width. Javascript was just used for toggling the visibility of the dialog style.display = 'table';

To see its inner guts, its perhaps best to look at the CSS with and the JS. Or perhaps read this for a stab at the CSS3 box border yourself.

2. Starfields

Star fields are a pretty common thing. The way implemented it was using three static Three.js particle systems (which aren’t emitters) and loop them such that once a starfield cross the static camera at a particle time, it would be looped to the back to be reused for a infinite starfield scene.

3. Auroras experiments.
I learn that sometimes easier to write experiments by starting afresh and simple, in this case with javascript + 2d canvas before doing it a webgl shader. Here’s the js version on jsdo.it so you can experiment with it.

Javascript Aurora Effect – jsdo.it – share JavaScript, HTML5 and CSS

This version runs from a reasonable speed to really slow, all depending on the canvas resolution, and number of octaves. The shapes of the aurora is generated with 3d simplex noise, for which 2 dimensions correspond to where each pixel is and the 3rd dimension being time. Just simple parameters can change the effects of perlin noise drastically, so not too good an idea to have too many factors if you do not understand what’s going on. I learnt that its difficult after what I thought was a failed experiment to create procedural moving clouds, and after I reread the basics of perlin noise, and started with a really simple example all over again. In this case, I felt the playing with the X and Y scales created the effect I wanted. These “perlin” levels were mixed with a color gradient containing spectrum of the auroras (which moves a little for extra dynamics). Next, added another gradient was also added top to bottom to emulate the different light intensity vertically.


For kicks, I created a GLSL shader version which potentially runs much faster than the canvas version. However, having too much time to integrate the Aurora with the demo, I used the canvas version instead. It was reduced 128 by 128, (chrome runs 256×256 pretty well, but not so for firefox then), a single octave, then used as a texture for a plane added to the scene. I also experimented with adding the texture onto an inverted sphere, which gave an unexpected but interesting look.


Finally, I thought there aren’t many known ways to create the aurora effects after searching, so this was just my approach although it might not be the simplest or best way either. Recently though I’ve found 2 other procedural generated aurora examples, which one might wish to look into if interested. http://glsl.heroku.com/e#1680.0 Eddie Lee also coded some really beautiful aurora effects for his kyoto project with GLSL in OpenGL, using 3D hermite spline curves wrappable perlin texture (more in that video description and shader source code!)

3. Night Sky Auroras + Trails

The long exposure star trails effect is created by not clearing the buffer. This technique is shown in the trails three.js example. Then played with the toggling on “timeline” (see next point).

4. Director class.
Perhaps its now time to introduce the Director class. For time based animations, you might need something to manage your timeline and animations. Mr doob has a library call sequencer.js (not to be confused with music sequencing!) which is used in various projects he worked on. The library to help load sequences or scene based on time. The Director class I wrote is somewhat similar, except it works on a more micro level, with direct support for animation by easing functions in tween.js. Perhaps this is also more similar to Marcin Ignac’s timeline.js library, except with the support to add Actions (instead of just tweens) at particular times.

The API is something like
director = new THREE.Director();
director.addAction(0, function() { // add objects } )
.addTween(0, 4, camera.position, { x: -280, y: 280, z: -3000},
{ x: -280, y: 280, z: -2600}, 'Linear.EaseNone')
.addAction(4.0, function() {
// here's a discret action)
camera.position.set(700, 160, 1900);
callSomethingElese();
})

// To start just call
director.start();

// in your running loop just call
director.update();

// scenes also can be merged via
director.merge(scene2director);

To simply put, Director is a javascript which does time-based scheduling and tweening using for animations in a scene. I’ve planned to improve and release it but in the meantime you can look at the javascript source. (This is also integrated with point #)

5. Snow scene

The components that make up the main snow scene can actually be found in the comprehensive three.js examples. The main elements apart from snow are shadows, flares, text, and post processing.

I think I’ve covered why I’ve chosen the shadow, flare, text elements in the previous post so look into those examples linked above and I’ll just straight into the post-processing element.

6. Post processing

The only post-processing filter used here is a tilt-shift, which emulates a tile shift effect. Actually a tilt-shift lens has the ability to put items at different focal length in focus, or items at the same focal length to be blurred. Such lenses are usually used for architectural photography, but also has a reputation of creating “miniature landscapes”, which is characterized by the top and bottom blurring of a photo. This post processing filter does exactly that kind of effect rather than emulate the real lens. The effect is surprising kind of nice, it helps creates softer shadow and brings focus into the middle of the screen. I had initially wanted to port evan’s version which allows more controls of the amount of blurplane, unfortunately that happen in that time frame I had.

7. Snow Particles

There are 2 particles effects used here. One’s the Snow and the other’s for the disintegrating text particle effects.

I’ve used my particle library sparks.js to manage the snow here. The sprite for the particles are drawn using the Canvas element (like most of my particle examples). Perhaps it’d harder for me to express in words, so let the related code segment along with comments do the talking.

The 2 main elements for this effect is that its emitted from an rectangular area (ParallelogramZone) and its given random drift. The “heaviness” of the snow (which is controllable by the menu options) adjusts particleProducer.rate, which can simply turn the scene from no snow to a snow blizzard. (Director was also controlling the stopping and running of snow for the text scene)

8. Text Characters Generation

Before going to the text particles, a little comments on the text generation method used here. While we have already demonstrated dynamic 3d text generation in the three.js examples, there’s a slight modification used for the text effects.

Instead of regenerating the entire text mesh each time a letter was “typed”, each character’s text mesh is generated and cached (so triangulation is reduced if any letter is repeated) and added to a object3d group. This allows the ability to control, manipulate and remove each 3d character individually when needed but also more importantly created better performances. With that in place, the Text Typing recording and playback Effect was almost done.

9. Text Particles

After the end of each line, the text would then burst into particles. This was another area of experimentation for me. Converting text to particles could be done like this.

a. Paint text onto a 2d canvas.
b. Either, 1) randomly place particles and keep those that land within the painted text area, or
2) randomize particle to be part of the paint text area. Next move them along a z-distance.

Method 2 works pretty well for minimal “particle waste”.

However, I thought that matching typeface.js fonts to the 2d canvas might took me a little more time, so I decided to use the mesh to particle THREE.GeometryUtils.randomPointsInGeometry() method (first seen in @alteredq shadowmap’s demo which randomize particles to be on points of the mesh (sur)faces instead. While I preferred the previous approach, since it gave a nicer volumetric feel, the latter approach likewise worked and on the bright side, showed the better shape of the mesh when viewed at the sides.

10. Key recordings.
The animation of the 3d text messages were done using “live recording” with a Recorder class (inside http://jabtunes.com/itcameupon/textEffects.js). Every time a keypress is made, the event is pushed to the recorder which stores the running time and event. The events would then be serialized to JSON format, which can be loaded at another time. The recorder class also interfaces with the Director to push the events for playback. This is the way that user’s recordings are saved to JSON and stored on the server.

11. Audio Playback
The Jasmid library mentioned in previous post is utilized for browser based synthesizing for midi files. This version uses Web Audio API for chrome browsers and some tweaked buffer settings for better playing back when using firefox audio data API.

11. Snowman

I almost forgotten about the Snowman. That was “modelled” or procedurally generated using Three.js primitives (Spheres, cylinders etc). One revision before the final even had fingers on them. Yea, it was a little painful having to refresh the browser to see changes after changes was made so the web inspector console helped a little. Still, while animating with the Director.js class, there was even more trail and errors, and waiting for it playing back. It was only until later I added a .goto(time) for the Director class. But I made a few interesting accidental experimentations, like the impalement of the snowman was setting an object to a large negative scale.

As those who follow me on twitter might already know, I wrote the Three.js Inspector a couple weekends later, which would potentially made things much easier. Perhaps more on ThreeInspector in another post.

Concluding thoughts
Wow, you’ve read till here? Cool! It almost felt painful trying to finish this writeup (reminding me of school). If there’s anything I missed out, feel free to contact me or dig into the source. While this hasn’t been groundbreaking, they didn’t exist at a snap of a finger. So I’ve learnt to build experiments by small parts, and make modular integration. There’s room for refinements, better tools, and better integration. Signing off, stay till more updates on experiments! :)

Comments are closed.