by Navis of Andromeda Software Development
Download the pdf here
The seed idea for the project Rupture was planted in early October 2008, a month and a half after we finished our NVision 08 demo. We thought about taking a well-deserved sabbatical of undetermined length. At about the same time, I was looking forward to a quiet winter spent testing new ideas and directions for our next thing that would come. I predicted that this would happen no earlier than summer 2009: a demo for either NVision, Evoke, or maybe even Assembly.
From these early days I wanted to do a good wireframe-based demo, something broader and smarter than "Eryx". So early enough I had my goal set on starting a relatively long production, a multi part demo featuring 3D wireframe graphics, with minimal use of 2D textures and traditional effects (layers, particles etc.) Of course that needed an extra edge, something to make the demo stand out. I toyed around with some techniques for "breaking" meshes into tetrahedra, as if they were volumetric, and applying a fake physical model to them, creating a net effect similar to the one in Debris. My original prototype was painting the wireframes as lines and covering the hidden surfaces with black triangles. A simple looking mesh (for example a cube) would be internally segmented to hundreds of tetrahedra, all precisely covering the volume of the cube. Through forces of gravity, wind, collisions, and explosions, the polyhedra would detach, making the cube appear as if it breaks down into pieces. In order to hide the tesselation, the tetrahedra would render their wireframe only when they were dislocated from their original position. This made for an interesting, clean effect - smooth wireframes on a black background. That was the technology behind the next demo, I thought: a demo with a story, maybe about destruction and .. ?
|"Rotating object demos are not cutting it any more."|
Still that wasn't enough. I left this to cool down in my head, feeling that there was no need to rush, at least until spring.
Then one day around late January, I spoke to Gloom/Excess, who happens to be a member of the org. team of the Gathering. He suggested that we do something for the party, if at all possible, be it a short demo or even a game. I explained that, for personal reasons, I wouldn't be able to visit any spring party, therefore even if we managed to make a demo we couldn't deliver it ourselves. Our conversation, however, put me into thought. What if we made a demo based on that concept I was toying with in November and actually pretend that the technicalities of delivery will be somehow resolved when the time comes. So we had about 3 months of time to develop it. It would be a hard one to start and finish as what was needed, first of all, was a complete revamp of our 3D engine. In more detail, the old support code for render to texture and shaders was getting seriously obsolete. I spent a week researching and implementing FBOs and GLSL - now the framework was alot cleaner and could support, through MRT, a range of effects that were almost impossible before. With these new weapons in my arsenal I could now extend the original "wireframe only" concept into something less minimalistic that had more potential for exploitation. A couple of trials later and I realized that I can produce the hidden wireframe image through a completely different pipeline instead of painting lines over black untextured triangles. This I manage by convoluting a rendering of the normal map with a slightly blurred version of that map (I would call that a deferred shading technique). This procedure highlights the edges between non-coplanar surfaces while the space over the coplanar surface is set to black. That simplifies things with the breakable meshes, as they don't pose a special case anymore. As soon as the detached piece (a tetrahedron) leaves its original position, the normals on its surface change with respect to the body that it was originally an integral part of. The extra benefit of all that is that objects can intersect with each other, or have strange topology and variable tesselation levels and still look good.
The next experiment I tried was to see if texturing would improve the aesthetic quality of rendering. At that point, even a scene with complex objects would look flat and unattractive. I decided that this wasn't going to be a purely minimalistic demo after all, not at least with the breakable objects effect in. So an extra layer of texturing was the only way to go. Another week of heavy experimentation passed and I found that the best combination was a mixture of normal lighting and inverse fresnel lighting, all peppered with some noise texturing that had object-space coordination derived uv's (non procedural uv mapping for use with, for example, lightmaps, which is one of my pet hates as it involves using Blender and 3D Studio, both of which I'm not that happy using. I was glad I didn't have to use any of them during this project, just Wings3D). I also tried the following techniques that didn't work for various reasons:
- Shadow mapping: slow (extra pass) and didn't really make all that much difference.
- Per object motion blurring: again slow (extra pass) and just wouldn't work for the kind of scenes I had in mind, where the background is in movement rather than the foreground object.
- Field of view effect: looked quite terrible with wireframes. FOV is one of those effects best left alone if they cannot be done perfectly. I've only seen perfect FOV in a couple of demos (Arise/Stravaganza is one of them). My version was not as good, so the idea had to be dropped altogether.
A very early days screenshot of the effect on a generic demo-object. The environmental reflection shading creates an interesting effect, but it breaks easily, so it wasn't used as heavily as shown here.
By the 31st of January everything was set and waiting. All support code, filters, and pipelines were there. What I needed now was to come up with a storyboard and slowly start adding the demo content.
1st Feb - 5th Feb
5 agonizing days. I'm trying to find a unifying theme, a story. Rotating object demos are not cutting it any more, and it is my honest belief that there must be an underlying story to glue everything together. I don't see the point of demomaking otherwise. I think about potential storylines all the time. I can't work, watch tv, or engage in conversation for more than 5 minutes, as my attention span is reduced to that of a toddler. I go to bed only to feel my eyeballs turning around under closed eyelids, for hours. By the end of the fifth day I crack it. This demo isn't going to be about a destruction, but rather about the attempt to escape destruction. Our "vehicle", or as I call it our "avatar" is going to be a train. Or a truck. Or a number of different automotives.
I draw my plans:
- Escape from planet XYZ before the final destruction takes place.
- Camera follows common automotives: train, truck, and yacht.
- Journey is futile, it all ends in tears.
Early wireframe-only rendering of truck. It was quite hard to make edges look smooth and continuous with AA turned on.
I imagine the last scene being a fly over of a city. The camera following a helicopter. First (or second, after introduction) scene is the one with a truck. Then, truck to train transition, still unknown how. Then train to yacht. Then yacht to motorcycle: yacht goes over a waterfall, transforms into a motorcycle somehow. Motorcycle to helicopter. Helicopter - city - the end. That should be enough for 4.30 minutes of content. Of course, that leaves the question of what to put around the automotives: in what sort of environment do they live? I can easily think of streets, railways, cities, the sea, tunnels... there is a plethora of options.
Time to start coding then!
|"Time to start coding then!"|
I guess I better start with some modeling. There are 4 models to make in Wings3D, I start with the easiest which is the truck. Fortunately, I have a very good library with reference models. Unfortunately, most of them have serious winding and topology errors. I load the models and try to copy the looks manually. It works! Truck and yacht are ready.
Some initial tests with the truck look very promising. The truck model is very imposing, it reminds me of the film "The Duel", which is about an evil truck. Late at night I have an idea for the transition from truck to train: what if the train smashes into the truck! That would look impressive. Only problem is that trucks and trains don't generally smash into each other as one goes over road and the other over rails. But what if the truck stopped over a crossing? To do that there must be a reason - usually a break-down. But that would be impossible to depict realistically: assuming that the truck is travelling fast (i.e. over 50km/h) it won't just stop over the rails. I figure out that the best way to stop the truck on rails is to force it to stop because of an event that takes place ahead of it. An accident or a cliff? Bingo!
All vehicle models as viewed in wings-3d, the only modeler I use for many years.
I'm beginning to feel more confident now. It looks like the transitions from one vehicle to another can be done realistically without breaking the narrative. I think it will be easier to plan what to do with each piece after I finish at least one part. I start with the yacht. I built my "sea" with hexagons, which look much better than ol' boring cubes and are as easy to tile. I guess hexagons will be reused later on in other environments too. The movement of the sea is a simple "plasma" made with sin/cos. Now the hard bit is to make a realistic splash.
Late night Monday coding and I curse my inadequacy: no matter how hard I try, how many textures or colors or movement patterns I change, the water looks very flat and artificial. I don't even try to add a particle system for the splash effect into the equation because I know it simply won't work. I give up in frustration and head to bed.
I clearly need to add geometrical detail to my sea of hexagons. It is not a matter of texture mapping any more. I need to have more geometry, more edges to highlight. I need objects with cracks and holes. The sea must be covered with cracked, imperfect hexagons; anything else is just too smooth and bland for this scene. At this point what I have in mind, and what I can technically do, are worlds apart. At the same time I have to keep the polygon count low. The task at hand is impossible! I try to forget about it for a moment and write a road and railway constructor function for future use. This one takes a 2D spline and paints a road or a railway using quad strips. At least this one looks pretty decent without any extra effort.
I'm still concerned about the truck scene. I'm thinking about 30-35 seconds of movement but still haven't got any idea of what is going to happen during those seconds, other than the camera following the truck. Lets say that the truck goes through a tunnel - how is the tunnel going to look and where do I start - it is all a big mystery. But I have a good idea: rather than spend all 35 seconds on the truck moving, I can have the truck stationary in garage for 15 seconds, then show it accelerating for another 10 and then another 10 at full speed with the camera moving around it. Maybe the truck can just appear slowly from nothing, through a laser beam that carves it over thin air. Good idea. For this effect I need to do a boolean operation between a plane and my truck model. How do we do that without resorting to blend-based effects? No idea. The project is quickly becoming a chimera. I'm faced with a number of complex technical problems, time is pushing, and I still haven't told my family about starting a new demo and having to take time off from life for the next three weeks. I need to resolve problems soon if I want to continue "project 60 seconds to destruction" as it is now called. I finish the day with some more modeling on Wings3D. At least my art pipeline is very efficient, as there is no need for major 2D artwork or complex 3D objects.
A major breakthrough. I discover the "discard" keyword in fragment shaders. It is all too simple now: having disabled backface culling, take a fairly low-polygon object, project a noise texture (or a sin/cos function) in object space and discard values above the threshold. This will generate cracks/holes over the object, implying much higher tesselation levels. I can use that in the truck sequence, but most importantly with the hexagonal sea. I have a working prototype of the yacht moving over beautiful water. The seaplane gives me an idea of using the same technique but instead of projecting a noise to project a full-motion video. The video of a woman. First scene: She is telling you about an eminent disaster. Another 30 seconds maybe off my mind!
Fridays are slow. I normally go home early from work, at around 12.30 midday. I feed my daughter (Stella) and put her to bed for her afternoon nap. Then I do some office work on my home machine. But this time I'm going to work on the demo till 5.00, when mum comes home from work. I guess I just have to spill the beans today and admit that the long working hours are because of a forthcoming demo. At least I can make a promise that we can use some of the prize money (*if* the demo is finished and *if* it wins anything) for a holiday or something for the family. Truth is, I don't do demos for this reason - but the situation is more complex nowadays and I cannot simply disappear for 20 odd nights for my hobby. After my confession nobody is happy and I commit to develop the demo transparently. Maybe I can take some time off work or start waking up very early in the mornings. It is going to be tough.
Day off and night out. Obviously.
Change of plans: instead of cutting through the truck, it will probably be better to do the same with the train. This way I can reveal the inner workings of a diesel engine, pistons, crankshafts, camshafts and all, ticking away the seconds. I can worry about the content in the truck part later. I realize that my original estimate of 35 seconds of content per vehicle might be a bit too much to afford; maybe there simply isn't enough material to keep the viewer interested. It needs another vehicle - how about a motorcycle? The sequence is now: introduction -> motorcycle, truck, train, boat, helicopter -> the end. It didn't take much time to imagine the details: Motorcycle moves like an arrow, going through objects, cutting them in the middle like a hot knife through butter (courtesy of boolean operation between the object and the motorcycle wavefront). Motorcycle cuts through the truck too. Camera moves to the truck, the truck stops over a cliff. Train smashes into truck, truck runs away. We peek into the engine. Giant hands hold the rails. Train smashes into a giant face. Goes through the other side, it is now a boat. Boat floats over water, something happens, helicopter, explosions, helicopter crashes, the end. Fairly good scenario for my target of 4.30 mins. It is now late Saturday night and I have just finished most of the motorcycle part. Alot of work went into it: the modeling of the city, the cameras, the burning road shader. It is pretty straight forward what I have to do next: the truck.
|"Right then, we need a train smashing into a few thousand polyhedra. Easy."|
I put the truck on an empty road, traveling at approximately half the speed of the motorcycle. When the motorcycle hits the truck from behind, it splits into two, only to reshape into one piece moments later (can't get the image of Terminator 2 out of my head now). It is an impressive effect, maybe the highlight of the demo so far. The problem is where to put the camera so that it captures the scene in its entirety. Talking about cameras, the rules are that, in the absence of music, they can only change on whole seconds. This way I can match the bpm in the future much more easily. It has worked in the past, it should work this time too. Although I do predict that camera cuts in this demo will probably be a lot more per minute than anything else we made in the past (certainly more than "Eryx", it had no camera cuts whatsoever!).
I sprinkle the space surrounding the road with more hexagons derived from the sea scene. It is quite easy to add content with this boolean operation based technique I developed this week. The tunnel follows: effectively a large horizontally extruded hexagon with a large hole in the middle and much smaller holes around the main hole. The whole affair takes me less than 5 hours - I have just extended the demo by 40 seconds. This is a fantastic achievement. The truck is now hanging over the edges of the cliff, waiting for that runaway train to smash into its frame.
Right then, we need a train smashing into a few thousand polyhedra. Easy. I fine-tune the movement of those particles by slowing down time by a factor of 100 and playing the same scene again and again until I get a satisfying effect. I'm getting close.
Another day spent playing with milliseconds. Yesterday and today I put in a total of 8 hours for about 800 milliseconds of effect. At this rate the demo is going to finish in time for The Gathering 2014. But it is worth it. I'm so pleased with the effect that I loop the camera around the same sequence three times. It is cheesy, maybe, but works quite well and I promise not to use it again in this demo.
Ah Friday, the day of rest. From work, that is. Because in the universe of "90 seconds to destruction" things are getting heated up! Train sequence is next. Train will just ride on the rails for a while, with the camera following it while the rest of the world is just passing by. I start with laying the tracks. That is a rather tedious process that involves a lot of typing low level OpenGL functions (GL_QUAD_STRIPS etc.) but since I've done this a million times before, I sail through.
More train work. It is quite easy to add detail to the train world. Just extrude the sides and use the boolean trick with the discards on the shader. Some arcane combination of sin/cos is enough to make it look complex enough. The train now moves over the rails for about 20 seconds. A good idea: make a hole on the side so that we can see the internal workings of the beast. The engine model is taken directly from our old demo "Zine #13 Headlines", but now instead of 5 cylinders we have 15, with triple overhead camshafts and other visually exciting but nonsensical mechanical features. A projection of a red-yellow-white gradient over the cylinders gives it a nice "spark". Without it the engine looks very flat. At this point, the train must either hit something or do something else, like fly over the edge of a cliff. I take these thoughts to bed.
It was quite easy: the train will go *through* something and then fall off the cliff. Starting with the motto "in your face" I steal an upper torso model from one of our previous demos and add a procedural hole over the mouth. Then cut the rails so that the train can fall "down". But there is no "down", really. In OpenGL world, the space coordinates of the train have to keep going forward, otherwise I have to do a lot of work making it all look realistic when it lands. My only option is to make the camera move around the train so as to give the impression that it is falling down. The process of finding the right camera function takes more than 3 hours straight and by the end of the evening I have, more or less, the bulk of the train scene finished.
It has been quite a while since my ASD colleagues have found out about the demo and began adding their contribution into the mix. There is a minimal amount of 2D to be done (some splash screens) and the 3D is more or less ready, or easily doable in Wings3d. But what about music - I hope aMusic is on it. There is not much time left; the calendar may say almost 6 weeks until the party but there is a lot of content and material to be mixed. But I trust him and Leviathan to deliver it on time, as they always do. I spend some time at work fine-tuning the train part. Now the train lands on rails again, and it feels like this time it's over. The length of the sequence is around 45 seconds, very similar to the previous two.
Cue next scene, the yacht. This should be easy. First make the train disappear, the same way it arrived. Then add the yacht on the hexagonal sea. Make the camera move once around the yacht for around 30 seconds.
Another 35 seconds are thus added and now the yacht just sails away into the proverbial sunset. I don't know if it will crash through a wall or fall down a cliff or a vortex. I cannot try all of them, so I take a chance with the vortex. More shader work to sculpt the geometry into a mean looking hole in the middle of the sea. I'll work on the details tomorrow.
The yacht has to fall down the vortex realistically and then appear again somehow at the bottom. But what is at the bottom of a vortex? That I don't know and I cannot do anything else until I find an answer. It could be the bed of the sea, in which case what do I do, tear the ground again? No point in continuing that scene right now. I take the day off the computer.
|"Good thing I have plenty of free time on Fridays, those cameras are very time consuming."|
The answer is: there is an inverse vortex at the other side and the yacht falls through that towards a city. Over a helicopter, like in Terminator 2. I can reuse the vortex effect and save myself a few seconds of content! So I build the three distinct cameras for this: Yacht falling into vortex, yacht still falling over abyss, yacht leaving vortex and falling into empty space. Good thing I have plenty of free time on Fridays. Those cameras are very time consuming. 5 straight hours of sin/cos fiddling and my head is spinning too.
One thing I always wanted to do was a "shaky" camera effect, like the one in Debris. I've experimented with different types of noise but nothing seems to work. So I have an idea, that I put to test tonight. First I draw a black square on a white clean surface - one of the walls in my house. Then I hold my video camera, hand extended, zoom level to max (so as to maximize the shaky effect) and record the square. I then extract the relative position and orientation of the square using simple image processing on all video frames. This concept works miracles! I will use this to add the shaky effect when the demo is ready.
More free time today to spend on fine-tuning the train and boat scene. I work on the colors in order to make the two scenes blend better. I think a slow fade-in rather than a hard camera cut between the scenes works much better. It feels much more natural this way. A dead moment then a kind of a deep breathe-in before the last part of the demo starts.
Not much work done today but I got the helicopter model done. I must wrap up this demo pretty soon as it is starting to create problems with my family life. Not much programming left though: just 3 scenes, the first (which is yet to be decided) and the last two. It will all be ok.
So how do we start the demo? As planned, with the video of the woman projected on the water-like surface. But what could that surface be? First idea: a flight information board at an airport. I like it. Problem is that the environment might be too tricky to model. Other idea is to put the surface on the bottom of a swimming pool. Could work, but it is pretty irrelevant. It is all a big puzzle and I get to bed very frustrated. I need to resolve this - fast.
Getting ready to record my wife Lisa in her role for the demo.
A voice recorder and a normal camera will do the trick.
I still have a headache from thinking about it. Maybe it should all be in a nice simple room, with the video projected on a mirror on the wall. I quickly model the concept in Wings3d and then try some shader magic to add what looks like rays of light coming through the windows. It looks very eerie, all quiet and cal - the perfect start for a fast paced demo. So, in a stroke of luck, I resolve the complex issue (it always is) of the opening scene in a single day. Things can't get much better than that!
Early in the morning I go to the hospital to have an operation that involves full-body anesthesia. I wake up feeling quite weird (a cross between feeling drunk and having a hangover). The operation was successful but I'm left with a swollen leg and orders to stay in bed for as long as it takes. Which means that my diary has to be broken at this point, as I'm not going to spend the next week reading or sleeping, and definitely not working on the demo.
Tired diesels. Getting inspiration even while on holidays in Greece.
The weeks pass without any progress from me, but aMusic and Leviathan's work has been fruitful. The bass line and first minutes of the demo are here, blending rather well with the visuals. We get the happy vibes from watching our effort becoming an entity with flesh and bones and a personality.
Still not back at work, but recovering fast. I can now sit in front of a monitor for a little while, so I get on with what is left of the demo: the final two scenes. iM has sketched up a city blueprint in Inkscape which I import in Wings3D. I then extrude the buildings, add roads and a marina. The camera will follow the helicopter which will fly off a helipad and then smash into the tall buildings. A day well spent modeling.
The whole part of the city was finished today in what I consider one of the most productive days I've ever had. It is extraordinary what can be achieved in such little time when you know exactly where you are aiming, and this time I didn't deviate a bit from the original plan. Ok maybe apart from that helicopter explosion bit (just before it smashes into a skyscraper) which originally was supposed to be a large explosion instead of a "chipping away" the layers that make the model. That was a bug, on the first run, I simply forgot to add any "explosion" vector to the particles, so they followed gravity and inertia. It looks much better this way though. The incident goes on to confirm that a demo is a collection of accidents.
Another great day "at the office", that is in front of my home pc without any interruptions from work or family. Last part done too! Much more straight forward than the helicopter/city part. The helicopter is now broken and dead (showing that the attempt to escape has failed), credits rolling (amoivikos texture), the end.
Over the next few days we made the final push with the demo. Me working on the timings and the guys in Greece on their music. Matching the visuals and music wasn't as hard as with some other demos, mainly because of the many camera cuts that were already synchronized to the bpm figure. The very last part in the production was probably the most stressful - testing the demo on different platforms (ATI & nVidia) and making sure it works as expected. Now the end of the run for this production has come and our child is ready to leave the nest and face the world.
(Rupture ranked 1st at The Gathering 2009. -ed)
Go back to articlelist