This one's going to need some background, so here goes. One of the open secrets in the demoscene is the background of the demogroup tAAt. The thing is.. people on the demoscene work behind some alias or artist name (like my alias, 'Sol'). Eventually things tend to get a bit too serious, and you might want to just do some crap and release it and not worry about your "primary" alias as much. Most people joined tAAt on this premise; an alias for an alias, so to say.
So anyway, one of the traditions in tAAt has been to make new year demos, and I'm responsible (stretching that word quite far) for about half of them over the years. Most of my new year's tAAt demos have been based on a single idea, and I ran with said idea every time, whether it was a good one or a bad one in the end.
There have been more misses than hits, as might be expected.
Anyway, as I was shopping for music for this year's demo, !Cube said he had made music a couple years ago already, but I had refused to use it because it would have required more work than I was ready to put into it at the time.
Which was true.
The thing is, !Cube's music is.. well.. let's just say I've ran out of superlatives over the years. Whenever I'm writing a demo to his music, I have to push myself to feel that I'm giving the music the respect it deserves. Whether I've succeeded or not is another matter.
Anyway, I ended up using his music this year (again), and the result was one of the better tAAt new year demos (again).
You can watch a video capture of the demo on Youtube.
My demomaking process starts from listening to the soundtrack, with my eyes closed, and getting a feeling of the music. I got the idea of a side-scrolling landscape, trees, and letters falling from the sky. This was the start of it. Then I loaded up the music to audacity to see some timings, but unlike most of my demo projects, I did not spend a lot of time worrying about timings.
After I had the basic structure together, with the falling letters and trees (generated with SnappyTree and meshes loaded with Assimp, which I removed from the project later on, opting for simpler binary mesh streaming), I figured.. let's go with a deferred shader.
Note that you can click on any of the images for the 1024x512 versions (which is the FBO resolution - or internal rendering resolution - used in the demo)
The meshes for the letters were a pain to do. They're made in Blender, and I spent a whole evening just separating and merging meshes so I could import them into the demo as separate objects.
The shaders output to multiple render targets: color, depth and original coordinates for shadow map. I also exported normals at one point, but did not end up using them at all. I could have saved one render target by combining the depth with the original coordinates, but, meh.
(Note that most of the stuff here is done during a single render pass on a single, rather complex shader, so most of the images here don't really exist during rendering, and were generated for demonstration purposes only).
As a coder, I really like SSAO as it's one of those "low-cost, high-impact" things. Artists may disagree, and they're entitled to.
So, when rendering things out, I control the bloom with the alpha channel. The scroller is very toned down (but still has a very subtle bloom), the stars and logo are about midway there and the fireworks are at full blast (just compare the fireworks in the bloom image and the plain texture image!).
Talking of fireworks.. I considered doing some particles in photoshop, but, again, felt too lazy to write yet another shader and made these little spinning triangles instead. I like the way they turned up.
Yes, I'm aware the shadow maps are buggy. Did you notice while watching the demo? I wouldn't.
Now to some less-visual things.
The camera shake is implemented by changing the look-at matrix (both 'eye' and 'at' coordinates) up or down based on a simple curve: on each physics iteration, the camera shake is multiplied by -0.9. Since the physics loop runs at a different pace than the rendering loop, the result isn't quite as severe as the above graph suggests, but it's strong enough for youtube to suggest image stabilization..
Whenever a letter falls down to the desired level, it's motion is added to the camera shake (with a tweaking multiplier), so that subsequent drops make the shaking worse. As the project progressed, I kept making the camera shake less and less intense.
The background stars scroll at a specifically designed curve which is shown in the picture above. When the demo starts, the stars are still, and the viewer concentrates on the sideways-scrolling stuff. Slowly the scrolling ramps up, and unless you've been paying close attention to it, the appearance of the logo will be a surprise. Finally the scrolling slows down before stopping, to avoid jarring movement.
The firework explosions are made by generating a few hundred particles at a point with a random motion direction and a certain speed.
The speed is then reduced on each physics iteration. The result in particle position is graphed above; when young, the particle moves fast, but then slows down, giving the illusion of an explosion. A slight gravity constant is also added on each cycle.
I don't know why, but the sideways scrolling sweep just felt like a nice way to start.
The ending was inspired by the music; I thought of a very old television set shutting down. The implementation was simple; when doing the final "composition" render, I simply scaled the output rectangle in the vertical dimension, and then drew an additive quad on top of that (the only use of actual alpha blending in the whole demo!) to simulate the white-out.
I also considered adding dust particles when the letters dropped, as well as adding music sync to the letters, as well as the early fireworks, but .. well. I could have spent the rest of eternity polishing the demo, but there was fairly little to be gained at this point.
The whole demo is an OpenGL 2.0 application. Yes, it uses the built-in gl_ shader variables a lot, which is bad form, but hey, it's just a tAAt demo, right? "Works on my machine" and all that.
I ran it on my wife's computer which has an ATI graphics card (on purpose, so I can do compatibility testing), and boom - the demo looked weird. It looked as there would be 32x32 pixels or something. I updated the drivers and the demo worked fine.
Some laptop owners (who don't really have the option of updating their drivers) have since complained about the exact same result, and at this point I can do little but shrug about it. At least you can watch the demo through YouTube =)
If I were to write a "real" deferred rendering engine, I'd aim for OpenGL 3.3 (at least). But overall, this was a pretty successful experiment.
Comments, questions, etc. appreciated.