Congratz with another football victory Espanol! Since almost half of the T22 team is made of sundried Paco Loco, I got to support them a bit (even though the bastards shattered our World Cup dreams two years ago in the grand finale).
Vacation is over again, time to sweat again till somewhere December. Did we do anything interesting past 2 weeks? Friends & I visited a rock festival in Belgium (Rock Werchter) and there we're some family-duties in Poland. I don't speak a word Polish, so all this ideal son-in-law does is drinking dad’s beer from the fridge. Nevertheless, I did some useful programming while drinking, and observed the remains of the communistic era a bit.
Realtime glossy reflections here by doing raymarching through 3D textures filled with the surrounding scene. Pretty cool, and it runs pretty fast on my 2008 laptop but... the grain artefact stinks like socks. The reason is the reflection is done on low-res buffers with low-res data.
Rock Werchter (though it's more about poop)
-----------------------------------
But let's tell something about that rock festival first. Came and left with a mixed feeling. The line-up was pretty great. To name just a few; Jack White, Elbow, DeadMau5 (not rock, but after hearing guitars all day, you know) and my favorites Cypress Hill and Pearl Jam. Didn't see but also there were the Chili Peppers and another favorite, The Editors. Cool and all, but I always wonder if those artists really enjoy what they're doing, asides living the life of a rockstar, big house, five cars, being in charge. I mean, for us mortals the performance sounds overwhelming and we audience feels flattered if Gary Lightbody sais "Iek haouw vaan joelie" (Love you in broken Dutch). But don't forget these guys play the same jingle every festival. Rapper B-Real is wondering “How he could just kill a man?!” for 20 years already. I guess most of them just play their hour full, say love you, receive their cash, fuck you, and then get out of there ASAP.
Nevertheless, Elbow was crystal clear, Cypress Hill made us feel a L.A. gangster for a moment, Bombay Bicycle Club was also surprisingly enjoyable, and especially Eddy Vedder gave a hell of a show and behaved like a real guitar hero. So, what's the mixed feeling about then? Well, it isn't the music. It's just that I'm not made for the whole camping shit around it (this festival takes 4 days). I enjoyed sleeping in tents 15 years ago being member of sort of a cheap equivalent on the boy Scouts, but those days you didn't wake up with beer-hangovers in a 40 degree sun-baked tent. You would get a (healthy) breakfast and explore the forest or something, instead of sitting in the mud & sun, waiting/hoping to get that headache disappear. And then the crown on the turd; back then our "toilet" (craphole) was shared with 15 or 20 kids, instead of 2.000 drunk-puking- diarrhea men. Do you know Pyramid Head from Silent Hill? Imagine his uh... Pyramid head being made of brown chunky turds, 35 degree Celsius, smiling at you each time you visit the toilet and forgot not to look in the hole. My girl asked me what happened to me when I got back home. “You know what happened to professor Brundle in The Fly?”, I asked here. You would get a fusion with the toilet contents if being in there for more than four seconds. And yeah, if you drink beer, toilet visits are hourly business. If not for pissing, then to empty your alcohol tortured body with one happy rectum bang, like a combi between Rambo on the M60 and the Probotector/Contra Spread-Gun.
All of that might have been bearable if I didn't have a sore back. Don't know what I did, but after a few hours already, the lower-back started hurting, commanding me to sit down. On the mud, pizza-plate, piss, plastic beercup covered ground of course. I came to see artists, not the legs of 80.000 people (although seeing that "forest of legs" around me with Deadmau5 in the air was quite a bizarre sight... maybe an idea for T22). Probably walking around with lot’s bags in Poland, sleeping on a couch, and sitting in a train for almost 20 hours (back from Poland) was a bit too much for my rusty back. Hey, getting a day older as well! Finally, maybe even the whining about dirty campings and a sore back would be gone if I was a true music lover. But I'm not. I listen and enjoy, but I won't shout, dance, or fall in coma when Michael Jackson enters the stage. Over-enthusiast people give me the creeps. So, on day 3 I decided to go home a bit earlier as planned.
Conclusion: Make your own private toilet with wheels, a coolbox, and a cylinder that can pull it up so you can sit, watch the stage, drink, and piss whenever needed. Or a more realistic solution, if you’re like me, just stay for 1 day only when your real favorite artists perform.
Don't mention the black dots, those are just flies. The same technique for Glossy reflections can also be used to sample G.I. and Ambient Occlusion. The low resolution and low amount of sampling rays still make it a bit... unusable. Tried thousand-and-one Ali Baba tricks, but usually the consequences are either bad performance, light-leaking, not suitable for large scenes, or all of it together.
Fear and loathing in Polska
-----------------------------------
Enough Pooptales, Poland then. The first half of the vacation we visited my girls mom and dad again. I'm not really their son-in-law by the way, we're not married (yet). Anyhow, it wasn't the first time, no big surprises this time, so I won't write the same stories about alcoholics, cozy country village-life, and other typical Polska folklore again. But if you are interested, check these earlier posts:
- Poland 2010
- More Poland, and Auswitz
Neither did we see much of the European Cup football tournament being held in Poland & Ukraine btw. Our (sleeping)train traveled through the south parts of Poland, away from the football cities. I kept my eyes open for ugly (Soviet) buildings & flats, which are of course part of the Tower22 inspiration. As said several times before, it's not that Poland is stuffed with half collapsing concrete monster flats and abandoned nuclear silo’s. For one reason, a typical Soviet apartment block isn't that high (8 to 15 stores), at least not here in Poland. Second, Poland evolves as well (luckily), so old crap will either get a facelift or disappears sooner or later. Third, most of the South-West country is filled with dense forest and agricultural fields instead of stinky industry-villages. And the south-central part looks pretty charming actually. In the summer at least. The words "Soviet-village" make me think of decayed concrete buildings, blackened by factory fumes, between graffiti covered metal skeletons of old trucks, tanks, play-yards, somewhere in an extreme cold snowy wasteland. Sure, the connoisseur can find such sights here, but most of the landscape here is made of rolling hills, forest, rivers and pretty charming villages with houses & yards that are bigger than the average Dutch house. Although I must say the winter transforms it in an ugly gray monster. Not that Holland -or any other country- looks that nice below a package of gray rainy clouds, but the lack of maintenance on the buildings and infrastructure reveals itself when the trees, busy street-life and garden barbeques aren't helping. No, for Tower22 inspiration you'd better visit Poland during the Winters. Or maybe autumn, my favorite time of the year.
My vacation photo's, dobre.
It's quite funny that working on a game like this makes you open your eyes. For one thing, I always try to keep track of how things get indirectly illuminated. You know, the ambient-lighting story. But also, from a more artistic perspective, you'll focus on things a normal person would ignore. People must have been thinking "what is that idiot shooting?", when I was taking photo's while the train passed a whole row of infamous large factory red-white striped chimneys that each self-respecting Polish village has. A local just walks by and doesn't notice rusty gas-pipes, graffiti walls or sober apartment blocks. The average Polish guy just looks bored, tired, or "dangerous" in the case of youngsters who still need to overcome their insecurities. Women keep their eyes on shops. Though smaller cities here lack exuberant shopping centra, so women switch over to their second favorite activity: watching & criticizing other people/women. Then a tourist would focus on the good stuff. Rich decorated buildings, mountains, historical remains, et cetera... if there were tourists. Who the hell visits a small Polish village? But my focus is on gray walls, containers, old mining factories, rusty signs, weird stairs going to dark corners in the street a normal person would pass, old train wagons, holes in the pavement, and the ugliest parts a building has to offer. The best sights are the ones where you wonder "why?!". Why are two different color corrugated metal plates used to cover that hole? Why is that door only 130 cm tall? Why is there Zebra-skin wallpaper in this little restaurant room that probably wasn't a toilet first? Probably due the lack of money and urgency to perfectly design things, you often walk into half-finished improvised, charming, erh, junk here.
Polish Urban mysteries
-----------------------------------
But honestly there wasn't that much new "cool inspiration". As said, Poland is cleaning up itself slow but steadily, and been there / done that. Although... a few things are worth a mention:
* The good old Air-Raid.
In a small village like Milowka, the firemen are usually handymen -or something else- doing the fire extinguishing as an extra (volunteer) job. So that means they won't be standby at the fire-station. Instead, the siren has to pull them out of their beds, pub, or whatever they were doing. It sounds quite impressive, and you know shit will hit the fan as soon as the sky starts groaning. Each time I visit Poland there is at least 1 big thunderstorm, and that automatically inherits forest fires, burning sheds, toasted electronics, and thus a cool air-raid.
* PKP, that is Polskie Koleje Państwowe, which is Polish State Railways
The Polish rail network is not (fully) controlled by computers yet. Most stations have two houses next to the track, being used to control the rail switches. One of them being old, deserted, graffifucked and with shattered glass. And another house, being populated with one person, usually an older woman, hanging bored out the window, watching as the train passes by. I wonder though, how often does this go wrong? It looks boring but it's quite a responsible job. Fall asleep, forget a switch and boom. In fact, Poland had a large train accident very recently, killing 16 people. And yes, the cause seems to be a “human error”. But back to those houses… Each time when passing by I wondered why they need a whole building for one or two grandma’s hanging out a window. What’s inside those things? Gigantic levers? Just curious.
* Mysterious towers
Another typical Polish sight nearby those train-houses; these towers;
What are those? First I thought about storage towers for water, coals or grain or something. But the windows on the sides reveal those are just hollow cylinders. Doesn't make much sense to fill these with water. It seems people work(ed) at the tops, but as what? You're not going to tell me they have yet another rail-control building. Operating two or four switches at a small village station doesn't require a house, another abandon house, AND a weird tower right?
* Blockwave gas-pipes
More railway fun, though I think I can explain this one. But enlighten me if I got it wrong. Quite often you can see thick, block-pattern shaped pipes along the railways in cities. Most probably those were/are gas or maybe even oil pipes. Smaller pipes going into the city, tapping from these main pipes? Or maybe transporting gasses/fluids between the stations and factories that are nearby usually. But why this block-pattern? So you can walk or drive under the pipe each 20 meters? Eastern Europe mysteries!
* Church rock
Not much of a mystery, but quite odd for a guy like me nevertheless. Dunno about other villages, but in Milowka, the church plays a song at 21:00. Each day. And each day it's the same song. Something about virgin Maria and the three kings. As you know, Poland is quite catholic (that's why the average Polish man is never drunk and paints like an angel). A church playing music isn't that special, but there is something about that tune. It doesn't sound like Quasimodo & bronze bells. It's trumpet music, sounding a bit sad and triumphant at the same time... A bit like a Saving Private Ryan tune. I like it.
Most of you probably won't give owlcrap about block-pattern gaspipes or why rail switches are controlled in a house, but I'll try to extract interesting little details for our game out of it. The world is full of (rusty) miracles if you look a bit further!
Friday, July 6, 2012
Saturday, June 16, 2012
The Hollow Man
The first and last post for June. Harvesting season started, and usually that means long days at work. Quickly programming and testing new machines, and trying to fix machines and the mood of their drivers when there are troubles. Quite a lot of work, but very rewarding if you see all your computer screens and automatic regulations doing magic with hydraulics and cylinders. Anyhow, time for a short break and another family visit in Poland. And who knows, maybe we can encourage our Dutch football team there! Although… winning with two points difference from Portugal… I think our orange dream ends early this year.
Busy, busy. Always a good diversion from the lack of progress on that other thing, you know, Tower22. Plenty of posts about a Radar Station, but how about n-e-w stuff hmmm? Let me answer this tactically… There are three kinds of progress: lot’s-of-talk (no progress), visible progress, and invisible progress. Let’s say we belong in the last category. Not that we didn’t make any visible progression. Several objects and textures were made, and I’m especially happy with the two concept-artists who joined and did quite a lot of drawings last months.
Making rooms
The main priority right now is to create rooms, textures, interior objects, and more rooms. Creating a few floors from the actual game. To get a good test-case for all the programming work, to get something playable. Unfortunately, that’s where the “visible progress” halts; it takes ages to finish a room. Not because it’s an insane amount of work to make a room + textures + objects (although at first when your asset library is empty, it actually is a lot of work), but because… because… everyone seems to be busy all the time. The ideas are there, the floorplans are there, also the concept drawings of room X Y and Z are on the table. The programming work is far enough to get it rendered and even “played” (walking around and stuff). And last but not least, each one knows what to do. So, what’s the hold up?
Two years earlier, I would make most stuff myself, or just borrow it from another game. Making rooms went a whole lot quicker, but of course, at the price of lower quality as I’m not that much of a 3D modeler or texture drawer. And you probably recognized some Halflife2 floortiles or footstep sounds ;). Obviously, if you want to make a good looking game, you’ll need artists with more talent to make each and every fart. Don’t underestimate the amount of things to make even for a stinky Soviet apartment interior. Several floor textures, wallpapers, decals, footstep-on-linoleum sounds, closet here, lamp there. Doors, kitchen, junk to place on that kitchen, and the list goes and on.
Count the assets
If you have a team of artists with sufficient time, you can relative quickly step through an asset list and create some momentum. With that I mean, once you made a few rooms, you can start reusing objects, sounds or textures for a next room so the development speed will accelerate. But Tower22 feels like a tractor running on Kentucky fried gravy stuck in the mud on a slope. Usually only one to three persons have some time do things in a week, so if two assets arrive in the mailbox each week while the total asset count is 20 for a room, it will get a looong journey. But unfortunately, that is reality at the moment, as most artists are busy with work (got to earn money right?), girlfriends, moving over to another place, and so on. And I wouldn’t be surprised if some just don’t really like to spend too much time on T22. Hey, I can’t force anyone. All I can try is to motivate them, and keep things going with clear short-term goals. But in the end, it’s their decision what they do in their free hours of course.
Maybe that’s the price I’m paying for asking talented artists. Students or less skilled artists are likely going to have more time (and will) to help you on whatever 3D model, drawing or other related game content. They are already happy they can help on a real game anyway! Skilled boys and girls on the other hand usually have their hands full on similar (paid / freelance) work. If you spend the whole day making 3D objects for Resident Evil 12, you probably aren’t that motivated anymore to make some more for T22 once you get home. I can understand that, and I’m not the pushing kind of guy. But at the same time this “permissiveness” isn’t really boosting the development speed of course. Should I take a step back, accept the fact you just can’t expect people who are skilled AND have a lot of time, and allow less talented people to help on the project? Maybe. A lead-artist who can guide and train them would be very helpful then. But honestly, I just want to see and hear quality, nothing less. Rather finish something with lower quality than nothing at all? No. All or nothing baby.
Progressbar.Visible := false;
Programming progress then? Quite a lot, but again, mostly “invisible”. That’s because a particular technique often needs a lot of preparations first. Studying the matter, pouring it in a multi-useful, clear way into the engine, expanding your tools so you can make use of it. And then finally apply it in a room and take a snapshot to show it (visible progress). Let’s give some examples, so you’ll know what I’ve been doing last months. For one, I tried to improve the performance. Implemented Unified Buffer Objects, made the loading times a lot quicker by using pre-compiled shaders, squeezed the rendering pipeline, and started on “Deferred Tiled Rendering”. I’ll be back on that in detail in some day. Either how, before you can implement it, you first need to know more about how GPU’s work, and “Compute Shaders”. So, support for OpenCL has been added to the engine. Actual Deferred Tile Rendering doesn’t work yet though, because may laptop is too old to perform required atomic operations. Hopefully the laptop finally dies by per accidentally dropping it in a potato harvester so I can get a new one from work hehe. Anyhow, the point is, even if Deferred Tiled Rendering had been implemented, you wouldn’t see any difference other than higher framerates (hopefully).
No, we won't win the war with photograp and rusty can objects. Nevertheless, also the little ones matter.
Second little thingy. I implemented AVI video streaming support. Basically you’ll read decode movie frames each time, then convert it to an OpenGL texture and apply it as usual. Thanks to some standard Microsoft libraries, the whole decoding part is monkey peanuts actually. But integrating AVI support carefully in the engine and tools takes some extra work. The goal was to import and use AVI files in exact the same way as any other texture. So that means you can apply movies on everything in the game. Computer screens, lights projecting a movie on a wall, animated floors, Monsters with television heads playing Tellsell, et cetera. Well, it succeeded. Yet it’s still “invisible progress”, as we don’t have a finished movie file to use yet :|
Another thing. Gameplay! All that talk about graphics always. Wouldn’t it be nice, also for the artists, to actually walk around in our rooms? Run a bit, make a jump, open a door, shoot something. You know, game stuff. A lot of programming work has been done here as well, but no end-results such as flying around with Jetpacks, solving Myst puzzles, or shooting smart monsters yet. What I did is making a “framework”. It doesn’t do anything, but using this framework you can attach a custom “behavior DLL” (a program) to each object or monster, or the game in general. These DLL’s decide what to show in the main menu, how to operate your inventory, how monster X should act and think, how fast your player can run, and so on. Every specific game detail will be implemented in these modules. The engine itself is just a toolbox that offers these DLL modules a lot of functions to do things (an “API”). Render something, spawn an object, play a sound, check if monster A can see monster B, et cetera. It works like an event-response system. The engine detects something, for example, if a barrel falls down and hits the ground. The specific DLL behind that barrel will decide what to do, and calls the API. Spawn particles, decrease health, play a “Bang!” sound, et cetera.
When programming these DLL modules, you’ll notice how much little details there are. Almost forgot… you need game rules right? Can your player jump or swim? How many times do you need Boss X in the balls before he dies? On which conditions does the “Game Over” screen appear? It all sounds pretty simple, as we have countless of games with comparable mechanics. Yet Tower22 isn't a shooter ala Half-life or Resident Evil 5. So, each detail requires smart thinking. I’m talking about paperwork. Milton Bradley (MB board games) weren't busy with sculpting Monopoly pieces or drawing board-textures. At least, the essence of their work was to write down brilliant ideas. Addictive play, innovative understandable rules, and how to make the perfect game to transform cozy family nights into a massive fight. So, what we did is starting a (private) Wiki to write down *everything* about the game. And, thanks to concept-artists, supported with visuals this time. As you all know, pictures say more than a thousand words. Hence, my busy guys don’t even read thousand words.
Hmmm, not a very nice shot of that livingroom right? But remember how the Radar Station transformed from boring concrete hollow boxes to something nice!
Ok, last example. I saw this movie
got jalous, and restarted The Never Ending Story on realtime G.I. Everyone who has spend time on this knows G.I. is extremely difficult to get it done with compelling results at reasonable speed. So, weeks (and also the coming vacation weeks) will spend on the matter, but don’t expect any visible results soon. All in all, you can’t say I’m doing nothing. It’s just that I can’t take a cool snapshot to show you!
So… no “visible progress”? Not really no, sorry. However, we’re making another demo movie. Which is actually a short part of the game, and focuses more on horror again. I planned to release that movie somewhere this summer (and hopefully attract more help again), but as you may have understand from the text, probably it will be late autumn again ;) Better late than never!
All right, got to catch a train to Poland now…. That sounded a bit weird.
Count the assets
If you have a team of artists with sufficient time, you can relative quickly step through an asset list and create some momentum. With that I mean, once you made a few rooms, you can start reusing objects, sounds or textures for a next room so the development speed will accelerate. But Tower22 feels like a tractor running on Kentucky fried gravy stuck in the mud on a slope. Usually only one to three persons have some time do things in a week, so if two assets arrive in the mailbox each week while the total asset count is 20 for a room, it will get a looong journey. But unfortunately, that is reality at the moment, as most artists are busy with work (got to earn money right?), girlfriends, moving over to another place, and so on. And I wouldn’t be surprised if some just don’t really like to spend too much time on T22. Hey, I can’t force anyone. All I can try is to motivate them, and keep things going with clear short-term goals. But in the end, it’s their decision what they do in their free hours of course.
Maybe that’s the price I’m paying for asking talented artists. Students or less skilled artists are likely going to have more time (and will) to help you on whatever 3D model, drawing or other related game content. They are already happy they can help on a real game anyway! Skilled boys and girls on the other hand usually have their hands full on similar (paid / freelance) work. If you spend the whole day making 3D objects for Resident Evil 12, you probably aren’t that motivated anymore to make some more for T22 once you get home. I can understand that, and I’m not the pushing kind of guy. But at the same time this “permissiveness” isn’t really boosting the development speed of course. Should I take a step back, accept the fact you just can’t expect people who are skilled AND have a lot of time, and allow less talented people to help on the project? Maybe. A lead-artist who can guide and train them would be very helpful then. But honestly, I just want to see and hear quality, nothing less. Rather finish something with lower quality than nothing at all? No. All or nothing baby.
Progressbar.Visible := false;
Programming progress then? Quite a lot, but again, mostly “invisible”. That’s because a particular technique often needs a lot of preparations first. Studying the matter, pouring it in a multi-useful, clear way into the engine, expanding your tools so you can make use of it. And then finally apply it in a room and take a snapshot to show it (visible progress). Let’s give some examples, so you’ll know what I’ve been doing last months. For one, I tried to improve the performance. Implemented Unified Buffer Objects, made the loading times a lot quicker by using pre-compiled shaders, squeezed the rendering pipeline, and started on “Deferred Tiled Rendering”. I’ll be back on that in detail in some day. Either how, before you can implement it, you first need to know more about how GPU’s work, and “Compute Shaders”. So, support for OpenCL has been added to the engine. Actual Deferred Tile Rendering doesn’t work yet though, because may laptop is too old to perform required atomic operations. Hopefully the laptop finally dies by per accidentally dropping it in a potato harvester so I can get a new one from work hehe. Anyhow, the point is, even if Deferred Tiled Rendering had been implemented, you wouldn’t see any difference other than higher framerates (hopefully).
No, we won't win the war with photograp and rusty can objects. Nevertheless, also the little ones matter.
Second little thingy. I implemented AVI video streaming support. Basically you’ll read decode movie frames each time, then convert it to an OpenGL texture and apply it as usual. Thanks to some standard Microsoft libraries, the whole decoding part is monkey peanuts actually. But integrating AVI support carefully in the engine and tools takes some extra work. The goal was to import and use AVI files in exact the same way as any other texture. So that means you can apply movies on everything in the game. Computer screens, lights projecting a movie on a wall, animated floors, Monsters with television heads playing Tellsell, et cetera. Well, it succeeded. Yet it’s still “invisible progress”, as we don’t have a finished movie file to use yet :|
Another thing. Gameplay! All that talk about graphics always. Wouldn’t it be nice, also for the artists, to actually walk around in our rooms? Run a bit, make a jump, open a door, shoot something. You know, game stuff. A lot of programming work has been done here as well, but no end-results such as flying around with Jetpacks, solving Myst puzzles, or shooting smart monsters yet. What I did is making a “framework”. It doesn’t do anything, but using this framework you can attach a custom “behavior DLL” (a program) to each object or monster, or the game in general. These DLL’s decide what to show in the main menu, how to operate your inventory, how monster X should act and think, how fast your player can run, and so on. Every specific game detail will be implemented in these modules. The engine itself is just a toolbox that offers these DLL modules a lot of functions to do things (an “API”). Render something, spawn an object, play a sound, check if monster A can see monster B, et cetera. It works like an event-response system. The engine detects something, for example, if a barrel falls down and hits the ground. The specific DLL behind that barrel will decide what to do, and calls the API. Spawn particles, decrease health, play a “Bang!” sound, et cetera.
When programming these DLL modules, you’ll notice how much little details there are. Almost forgot… you need game rules right? Can your player jump or swim? How many times do you need Boss X in the balls before he dies? On which conditions does the “Game Over” screen appear? It all sounds pretty simple, as we have countless of games with comparable mechanics. Yet Tower22 isn't a shooter ala Half-life or Resident Evil 5. So, each detail requires smart thinking. I’m talking about paperwork. Milton Bradley (MB board games) weren't busy with sculpting Monopoly pieces or drawing board-textures. At least, the essence of their work was to write down brilliant ideas. Addictive play, innovative understandable rules, and how to make the perfect game to transform cozy family nights into a massive fight. So, what we did is starting a (private) Wiki to write down *everything* about the game. And, thanks to concept-artists, supported with visuals this time. As you all know, pictures say more than a thousand words. Hence, my busy guys don’t even read thousand words.
Hmmm, not a very nice shot of that livingroom right? But remember how the Radar Station transformed from boring concrete hollow boxes to something nice!
Ok, last example. I saw this movie
got jalous, and restarted The Never Ending Story on realtime G.I. Everyone who has spend time on this knows G.I. is extremely difficult to get it done with compelling results at reasonable speed. So, weeks (and also the coming vacation weeks) will spend on the matter, but don’t expect any visible results soon. All in all, you can’t say I’m doing nothing. It’s just that I can’t take a cool snapshot to show you!
So… no “visible progress”? Not really no, sorry. However, we’re making another demo movie. Which is actually a short part of the game, and focuses more on horror again. I planned to release that movie somewhere this summer (and hopefully attract more help again), but as you may have understand from the text, probably it will be late autumn again ;) Better late than never!
All right, got to catch a train to Poland now…. That sounded a bit weird.
Thursday, May 31, 2012
Making of Radar demo #8: Morphing Animations
As promised, a Blog update about monster-animations without the usual delay. Ready for the European Football tournament btw? I'm ready, at least for drinking beer in the pub while the match is playing on a screen somewhere behind me. Let's hope Portugal, Germany or Denmark doesn't end my good excuse to visit the pub in the middle of the week abruptly.
Right. The "RadarBlob" monster wasn't supposed to be animated at first. Simple, lack of time. I still need to upgrade the entire skeleton-animation system. Support for other files (now it's only Milkshape...), additive blending, making good use of modern GPU techniques, ragdolls, et cetera. Another reason for skipping animation was the lack of a good animator. Which is also the reason I still haven't implemented a renewed system. First I want a human player or monster with good animations. Sorry, but I can't code blind or on "dummies", need real test-subjects!
But... while looking at the static, "frozen", monster, I wondered how the heck we could finish that demo movie a little bit spectacular. The model, textures and shading had been improved, but other than that it was as interesting as a vase. It would look even more ridiculous if the sound would be playing dangerous music, angry monster digesting sounds and steam blowers while nothing would really happen visually. No, we needed movement, even if it was something simple. But how to do that fast & easy? The answer: Morphing Animations.
Teenage Morphing hero Blobs
------------------------------
Morphing. It sounds like a technique the Power Rangers would use, but in 3D terminology it means as much as changing shape-A into shape-B. It's pretty simple, and as well an ancient technique. Quake1 already used morphing animations for its monsters and soldiers. How it works? Imagine a ball made of 100 vertices. New 3 seconds later, imagine the same sphere, but squeezed. The 100 vertices moved to another place in order to give a "squeezed" appearance to the same ball. The initial pose and the squeezed pose 3 seconds later can be called 2 "Keyframes". If we store those keyframes into the computer memory (thus storing all 100 vertex-positions per keyframe), we can interpolate the vertex positions between those 2 keyframes over the timeline. Useful, so we don't have to store hundreds or thousands of frames.
The math is pretty simple, and also the file-formats are straight forward. Just store the vertex-positions (and normals) at certain keyframes. Another important note, Morphing animations are very flexible, making it suitable for organic abstract shapes like our RadarBlob. Unlike Skeleton animations where the vertices are bound to a bone, we can place the vertices everywhere we like. You can change a humanoid into the Hulk, or a cube. Just as long the vertex-count and their polygon-relation stays the same.
Yet Morphing animations aren't that common anymore. They have some serious issues. First, in the old Quake times, models were much simpler. A relative low vertex-count (a few hundred or so), and just a few, relative simple, animations. These days our monsters have much higher polycounts, and more + longer animations. The CPU would have to loop through much bigger vertexlists to interpolate all positions, and also the memory would get a hit to store it all. For example, our RadarBlob has ~8.000 vertices. In optimized form with indices, it has ~3.100. It would mean the CPU has to update 3100 vertices, for each monster, each frame. And storing a single keyframe would cost at least 3100 x 12(bytes) = 36 kb. In practice it doubles, as you may also want to store normals.
Why Skeletor is more powerful
------------------------------
It's not that a modern CPU wouldn't be able to deal with these numbers. Hey, don't forget the hardware also grew in numbers since the Quake era. Yet it feels wrong to do it this "brute force" way. And it is wrong, I'll show you how the GPU can help down below. But last but not least, another good reason why Skeleton animations took over are the static restrictions. You can calculate the vertex-positions at the fly, but more likely you'll read them from an animation file (like the good old MD2 files). The animations here are "fixed", you can't just alter specific body parts during the animation. For example, having the upper-body or head/eyes follow a dynamic target gets difficult. Ragdoll animations, which is based on fully dynamic behavior, calculated by collision volumes falling on the ground, are nearly impossible in combination with Morphing animations. You can use Verlet or Cloth physics to alter the vertex-positions, but it will make the character fall like a combination between pudding & a deflated sexdoll.
Skeleton animations do not store vertex positions or anything. Instead, it stores a "skeleton", a bunch of joints and their relations ("bones"). Vertices on their turn will be assigned to one or more bones. Your left hand for example would be assigned to the "Left-wrist" bone. Fingers on the same left hand are assigned to sub-bones. If the wrist rotates or moves, all sub-bones rotate and move along with it, and so will the assigned vertices do. Yes, in essence this still means we have to recalculate all vertex-positions individually by multiplying their positions with their host-bone matrices. But skeletons have three major strengths over Morphing:
Morphing, the Revival
------------------------------
Ok, we know now why we shouldn't use Morphing, but yet we did. Look, if you make use of modern techniques, Morphing can still be a faster solution than skeletons, it's easier to implement, and it still suits better with organic shapes. I mean, how the hell would you make a suitable skeleton for this abomination?
I tried, but no…
We didn't need bullet-Time Trinity animations, just a disgusting sack of hydraulic blubber breathing a bit. So, Morphing would be a fine choice sir, the waiter said. But how to get it a bit fast? First we would need to get rid of the CPU. I'm not a fan of moving *everything* to the GPU just to say "Got a 100% GPU solution here!", those Quad-cores need to move their lazy asses as well. But it's just a fact that GPU's are much faster when it comes to process big array that require vector math. Updating vertices on the CPU would be a disaster anyway, as it would prevent you from using Vertex-Buffer-Objects, unless you stream back the updated vertices each cycle. No go.
The VBO just contains the monster in its original pose. When we render it, the Vertex-Shader will do the position-interpolation math, instead of a CPU. The math is simple, just "lerp" the vertex between the current and the next-frame vertex-position, then proceed as usual.
In other words, a 256 x 256 image would be able to store 21 keyframes for this particular model. When using a 512x512 texture the number quadruples, and don't forget you could use a different image for each animation eventually. Anyway, the Vertex-Shader has to fetch 2 of those pixels for each vertex. You can fill the image anyway you want, but I just filled it the optimal way. Each vertex gets an unique ID, a number between 0 and 3100 in this RadarBlob-case. This ID is stored along with the vertex in the VBO. In my case I stored it in the Texture coordinate.z. So the texture-lookup index of a vertex could be calculated as follow:
That's pretty much it. Feed the Vertex-Shader a texture that contains all animated positions, and you're good to go. Uhmmmm... how to get those textures? I quickly made a little program that imports a sequence OBJ files. Then it would just loop through all vertices and store it in an array that would be suitable to build a OpenGL texture with later on:
Sounds easy, and it is pretty easy, yet I'll have to WARN about a few things:
* Make sure all OBJ files have the exact same vertex-count and order. If one file has a different storage, your animation will turn into a polygon massacre.
* In case you want to smooth / share vertices to make use of indices, do it before storing them into this texture. The numbering and order must match with the model VBO in your (game)app later on.
* Centrate the OBJ files in the same way you would do in your program, or you'll get an offset on all coordinates.
Whaaa, FLAT shading?!
------------------------------
If you try the code above, it seems to work nicely at a first glance, but take your magnifier and flashlight Sherlock. See that? The lighting on the models seems.... weird. The RadarBlob breaths, but the lighting doesn't seem to change along with the movement. No shit Sherlock, that's because you didn't alter the normals yet (unless you already got suspicious and added some more code ;))!
If you rotate a polygon, the normal has to rotate with it in order to keep the lighting results correct. Only problem is that you can't do this in a vertex-shader, unless you know all neighbor vertex-positions as well. That's possible, but it requires a lot more sampling and duplicate calculations just to get the normal correct. Good thing we have Geometry Shaders these days. Geometry Shaders are actually aware of the entire polygon, as it takes primitives for breakfast. In other words, you'll get the three (morphed) vertex-positions, so you can relative easily recalculate a normal and eventually the (bi)Tangents as well.
Problem solved? If you love FLAT shading, then yes. Otherwise, you prepare to get shocked. The lighting will be correct, but the smoothing seems to be entirely gone. What happened?! Congratz, you just screwed up the smoothing and found out how flat shading works. Making a smooth shade basically involved bending/averaging normals on polygons that share the same vertices.
Your Geometry Shader however just calculated the (correct!) normal for each single triangle. What it should do is smooth the normals with neighbor triangles but... again, that is not possible unless you store & pass additional data for each vertex. By default, a GS has no access to neighbor primitives.
The good old CPU morphing methods didn't just store the altered vertexpositions for each keyframe, it also stored the (bended) normals, and interpolated between them. So, why not just take the easy route and do this as well? Make a second texture that contains the normals, in the same fashion as we did with the vertex-positions. Oh, and don't forget to smooth the model already BEFORE you insert the normals into this texture! Then in the vertex-shader, also sample the 2(or 3) normals and interpolate them.
Big chance you're using normalMapping as well, so you will also need the tangents and maybe biTangents. You could either make some more textures, but if you are concerned about having so many textures, you can also give the Geometry-Shader a second chance. Now that the GS received smoothed normals, it will calculate smoothed (bi)Tangents as well:
Hard to notice, but another little animation was oil streaming down. Just a timed fade-in of an oil texture. To make it "stream", the fade-mask moved from up to down.
Final tricks
------------------------------
We just made a Morphing solution that uses modern techniques to optimize performance such as VBO's (allowing to keep all data stored on the GPU instead of transferring vertex-data each time), without bothering the CPU to do the interpolation math,
Two more tricks I'd like to explain is having an "influence factor", and updating data inside a VBO. Morphing animations just aren't flexible when it comes to dynamic controls. But there is at least one simple trick you can apply: "influence". In the demo movie, you'll see the RadarBlob breathing much faster and more intense at the last seconds. We didn't make multiple animations though. We just speeded up the animation-timer, and increased this mysterious "influence factor". Well, if you took a good look at the code you already saw how it works: you just do a second interpolation between the original vertex pose, and the animated pose.
Last but not least, don't forget you can actually store the updated positions/normals into a (second) VBO. In the case of Tower22, this monster will get rendered many times per cycle. Three shadowcasting lamps are on its head, so it will appear in their depthMaps. Also the water reflection and glossy wall reflections will need this monster. All in all, this guy may get rendered up to 12 times in a single frame. Now the interpolation math isn't that hard, but the recalculation of the tangents and all the texture applies concerned me a bit. So instead of re-doing all those steps for each pass, I update the monster VBO first, using Vertex-Streaming / Transform-Feedback. So first store the morphed vertex-positions/normals/tangents for the current time into a secundary VBO, then for all passes just apply the 2nd VBO so we don't have to calculate anything anymore. See the links below for some details about this technique:
http://tower22.blogspot.com/2011/08/golden-particle-shower.html
Case closed.
Right. The "RadarBlob" monster wasn't supposed to be animated at first. Simple, lack of time. I still need to upgrade the entire skeleton-animation system. Support for other files (now it's only Milkshape...), additive blending, making good use of modern GPU techniques, ragdolls, et cetera. Another reason for skipping animation was the lack of a good animator. Which is also the reason I still haven't implemented a renewed system. First I want a human player or monster with good animations. Sorry, but I can't code blind or on "dummies", need real test-subjects!
But... while looking at the static, "frozen", monster, I wondered how the heck we could finish that demo movie a little bit spectacular. The model, textures and shading had been improved, but other than that it was as interesting as a vase. It would look even more ridiculous if the sound would be playing dangerous music, angry monster digesting sounds and steam blowers while nothing would really happen visually. No, we needed movement, even if it was something simple. But how to do that fast & easy? The answer: Morphing Animations.
Teenage Morphing hero Blobs
------------------------------
Morphing. It sounds like a technique the Power Rangers would use, but in 3D terminology it means as much as changing shape-A into shape-B. It's pretty simple, and as well an ancient technique. Quake1 already used morphing animations for its monsters and soldiers. How it works? Imagine a ball made of 100 vertices. New 3 seconds later, imagine the same sphere, but squeezed. The 100 vertices moved to another place in order to give a "squeezed" appearance to the same ball. The initial pose and the squeezed pose 3 seconds later can be called 2 "Keyframes". If we store those keyframes into the computer memory (thus storing all 100 vertex-positions per keyframe), we can interpolate the vertex positions between those 2 keyframes over the timeline. Useful, so we don't have to store hundreds or thousands of frames.
for each vertex
.....currentVertexPosition = lerp( frame1VertexPos, frame2VertexPos, frameDelta );
* frameDelta = a value between 0 and 1. 0.25 means we're at 25% towards frame2
The math is pretty simple, and also the file-formats are straight forward. Just store the vertex-positions (and normals) at certain keyframes. Another important note, Morphing animations are very flexible, making it suitable for organic abstract shapes like our RadarBlob. Unlike Skeleton animations where the vertices are bound to a bone, we can place the vertices everywhere we like. You can change a humanoid into the Hulk, or a cube. Just as long the vertex-count and their polygon-relation stays the same.
Yet Morphing animations aren't that common anymore. They have some serious issues. First, in the old Quake times, models were much simpler. A relative low vertex-count (a few hundred or so), and just a few, relative simple, animations. These days our monsters have much higher polycounts, and more + longer animations. The CPU would have to loop through much bigger vertexlists to interpolate all positions, and also the memory would get a hit to store it all. For example, our RadarBlob has ~8.000 vertices. In optimized form with indices, it has ~3.100. It would mean the CPU has to update 3100 vertices, for each monster, each frame. And storing a single keyframe would cost at least 3100 x 12(bytes) = 36 kb. In practice it doubles, as you may also want to store normals.
Why Skeletor is more powerful
------------------------------
It's not that a modern CPU wouldn't be able to deal with these numbers. Hey, don't forget the hardware also grew in numbers since the Quake era. Yet it feels wrong to do it this "brute force" way. And it is wrong, I'll show you how the GPU can help down below. But last but not least, another good reason why Skeleton animations took over are the static restrictions. You can calculate the vertex-positions at the fly, but more likely you'll read them from an animation file (like the good old MD2 files). The animations here are "fixed", you can't just alter specific body parts during the animation. For example, having the upper-body or head/eyes follow a dynamic target gets difficult. Ragdoll animations, which is based on fully dynamic behavior, calculated by collision volumes falling on the ground, are nearly impossible in combination with Morphing animations. You can use Verlet or Cloth physics to alter the vertex-positions, but it will make the character fall like a combination between pudding & a deflated sexdoll.
Skeleton animations do not store vertex positions or anything. Instead, it stores a "skeleton", a bunch of joints and their relations ("bones"). Vertices on their turn will be assigned to one or more bones. Your left hand for example would be assigned to the "Left-wrist" bone. Fingers on the same left hand are assigned to sub-bones. If the wrist rotates or moves, all sub-bones rotate and move along with it, and so will the assigned vertices do. Yes, in essence this still means we have to recalculate all vertex-positions individually by multiplying their positions with their host-bone matrices. But skeletons have three major strengths over Morphing:
1- You only have to store the joint-matrices(or quaternion’s) per keyframe. An average humanoid game-skeleton only has 30 to 50 joints or so. Saves a lot of RAM, and makes the files smaller.
2- You can dynamically alter a single, or multiple bones, and all child-bones + their vertices will nicely follow. Very useful for aiming, looking at, ragdoll physics, IK, or other dynamic behavior that can't be stored in pre-calculated animation files.
3- You can easily combine animations. The legs run while the upper-body shoots bazooka's, while the face talks shit.
Morphing, the Revival
------------------------------
Ok, we know now why we shouldn't use Morphing, but yet we did. Look, if you make use of modern techniques, Morphing can still be a faster solution than skeletons, it's easier to implement, and it still suits better with organic shapes. I mean, how the hell would you make a suitable skeleton for this abomination?
I tried, but no…
We didn't need bullet-Time Trinity animations, just a disgusting sack of hydraulic blubber breathing a bit. So, Morphing would be a fine choice sir, the waiter said. But how to get it a bit fast? First we would need to get rid of the CPU. I'm not a fan of moving *everything* to the GPU just to say "Got a 100% GPU solution here!", those Quad-cores need to move their lazy asses as well. But it's just a fact that GPU's are much faster when it comes to process big array that require vector math. Updating vertices on the CPU would be a disaster anyway, as it would prevent you from using Vertex-Buffer-Objects, unless you stream back the updated vertices each cycle. No go.
The VBO just contains the monster in its original pose. When we render it, the Vertex-Shader will do the position-interpolation math, instead of a CPU. The math is simple, just "lerp" the vertex between the current and the next-frame vertex-position, then proceed as usual.
// Get the vertex positions for the current and next frame float3 frame1Pos= tex2D( positionTex, frame1TX ).xyz; float3 frame2Pos= tex2D( positionTex, frame2TX ).xyz; // Interpolate float3 vPos = lerp( frame1Pos, frame2Pos, frameDelta ); // Output out.vPos = mul( modelViewProjMatrix, float4( vPos, 1.f ) );But... how does the Vertex-Shader know what the current and next frame positions are? Easy Does It, we use a texture. This (16 bit floating point) texture contains ALL vertex-positions for ALL keyframes. That's sounds like a whole lot, but don't forget a whole lot pixels fit in a 2D image. A single RGB pixel can hold a XYZ position (in local space), so do the math:
* RadarBlob: 3100 vertices
* 256 x 256 2D texture = 65.536 pixels
* 65.536 / 3100 = 21
In other words, a 256 x 256 image would be able to store 21 keyframes for this particular model. When using a 512x512 texture the number quadruples, and don't forget you could use a different image for each animation eventually. Anyway, the Vertex-Shader has to fetch 2 of those pixels for each vertex. You can fill the image anyway you want, but I just filled it the optimal way. Each vertex gets an unique ID, a number between 0 and 3100 in this RadarBlob-case. This ID is stored along with the vertex in the VBO. In my case I stored it in the Texture coordinate.z. So the texture-lookup index of a vertex could be calculated as follow:
uniform int frameNumber. // Current keyFrame index (0..x) uniform float frameDelta // Current position between current and next frame (0..1) // index = Frame offset + vertex offset within frame // index = 3100 * frameNumber + vertexID int frame1Index = modelVertexCount * frameNumber + in.vertexTexcoord.z; int frame2Index = modelVertexCount * (frameNumber+1) + in.vertexTexcoord.z; // Change the 1D lookup index to a 2D texture coordinate, for a 256 x 256 pixel image float2 frame1TX = float2( frame1Index % 256, floor(frame1Index / 256) ); float2 frame2TX = float2( frame2Index % 256, floor(frame2Index / 256) ); // Add half a texel to access the center of a pixel in the texture. // You also may want to turn of linear-filtering for the 256x256 texture btw const float2 HALFTEX = float2( 0.5f / 256.f, 0.5f / 256.f ); frame1TX += HALFTEX; frame2TX += HALFTEX; // Get the vertex positions for the current and next frame float3 frame1Pos= tex2D( positionTex, frame1TX ).xyz; float3 frame2Pos= tex2D( positionTex, frame2TX ).xyz; // Interpolate float3 vPos = lerp( frame1Pos, frame2Pos, frameDelta ); // Eventually you can also lerp between the original pose if you like dynamic control // on the animation "influence" vPos = lerp( in.originalVpos.xyz, vPos, animationInfluence ); // Output out.vPos = mul( modelViewProjMatrix, float4( vPos, 1.f ) );
That's pretty much it. Feed the Vertex-Shader a texture that contains all animated positions, and you're good to go. Uhmmmm... how to get those textures? I quickly made a little program that imports a sequence OBJ files. Then it would just loop through all vertices and store it in an array that would be suitable to build a OpenGL texture with later on:
for each OBJfile
.....for each vertex in OBJfile
..........array[index++] = vertex.xyz
Sounds easy, and it is pretty easy, yet I'll have to WARN about a few things:
* Make sure all OBJ files have the exact same vertex-count and order. If one file has a different storage, your animation will turn into a polygon massacre.
* In case you want to smooth / share vertices to make use of indices, do it before storing them into this texture. The numbering and order must match with the model VBO in your (game)app later on.
* Centrate the OBJ files in the same way you would do in your program, or you'll get an offset on all coordinates.
Whaaa, FLAT shading?!
------------------------------
If you try the code above, it seems to work nicely at a first glance, but take your magnifier and flashlight Sherlock. See that? The lighting on the models seems.... weird. The RadarBlob breaths, but the lighting doesn't seem to change along with the movement. No shit Sherlock, that's because you didn't alter the normals yet (unless you already got suspicious and added some more code ;))!
If you rotate a polygon, the normal has to rotate with it in order to keep the lighting results correct. Only problem is that you can't do this in a vertex-shader, unless you know all neighbor vertex-positions as well. That's possible, but it requires a lot more sampling and duplicate calculations just to get the normal correct. Good thing we have Geometry Shaders these days. Geometry Shaders are actually aware of the entire polygon, as it takes primitives for breakfast. In other words, you'll get the three (morphed) vertex-positions, so you can relative easily recalculate a normal and eventually the (bi)Tangents as well.
Problem solved? If you love FLAT shading, then yes. Otherwise, you prepare to get shocked. The lighting will be correct, but the smoothing seems to be entirely gone. What happened?! Congratz, you just screwed up the smoothing and found out how flat shading works. Making a smooth shade basically involved bending/averaging normals on polygons that share the same vertices.
Your Geometry Shader however just calculated the (correct!) normal for each single triangle. What it should do is smooth the normals with neighbor triangles but... again, that is not possible unless you store & pass additional data for each vertex. By default, a GS has no access to neighbor primitives.
The good old CPU morphing methods didn't just store the altered vertexpositions for each keyframe, it also stored the (bended) normals, and interpolated between them. So, why not just take the easy route and do this as well? Make a second texture that contains the normals, in the same fashion as we did with the vertex-positions. Oh, and don't forget to smooth the model already BEFORE you insert the normals into this texture! Then in the vertex-shader, also sample the 2(or 3) normals and interpolate them.
float3 frame1Nrm= tex2D( normalTex, frame1TX ).xyz;
float3 frame2Nrm= tex2D( normalTex, frame2TX ).xyz;
float3 vNrm = lerp( frame1Nrm, frame2Nrm, frameDelta );
.......vNrm = normalize( vNrm ); // don't forget. You naughty boy.
Big chance you're using normalMapping as well, so you will also need the tangents and maybe biTangents. You could either make some more textures, but if you are concerned about having so many textures, you can also give the Geometry-Shader a second chance. Now that the GS received smoothed normals, it will calculate smoothed (bi)Tangents as well:
TRIANGLE TRIANGLE_OUT void main( AttribArrayiPos : POSITION, AttribArray iTexcoord : TEXCOORD0, AttribArray iNormal : TEXCOORD1 // Smoothed! ) { // Just some remapping, lazy code float3 vert[3]; vert[0] = iPos[0]; vert[1] = iPos[1]; vert[2] = iPos[2]; float3 nrm[3]; nrm[0] = iNormal[0]; nrm[1] = iNormal[1]; nrm[2] = iNormal[2]; float2 tx[3]; tx[0] = iTexcoord[0].xy; tx[1] = iTexcoord[1].xy; tx[2] = iTexcoord[2].xy; float3 tangent[3]; float3 biTang[3]; for ( int i=0; i<3; i++) { /* SORT */ if ( tx[0].y < tx[1].y ) { float3 tmpV = vert[0]; vert[0] = vert[1]; vert[1] = tmpV; float2 tmpTX = tx[0]; tx[0] = tx[1]; tx[1] = tmpTX; } if ( tx[0].y < tx[2].y ) { float3 tmpV = vert[0]; vert[0] = vert[2]; vert[2] = tmpV; float2 tmpTX = tx[0]; tx[0] = tx[2]; tx[2] = tmpTX; } if ( tx[1].y < tx[2].y ) { float3 tmpV = vert[1]; vert[1] = vert[2]; vert[2] = tmpV; float2 tmpTX = tx[1]; tx[1] = tx[2]; tx[2] = tmpTX; } /* CALCULATE TANGENT */ float interp; if ( abs(tx[2].y - tx[0].y) < 0.0001f ) interp = 1.f; else interp = (tx[1].y - tx[0].y) / (tx[2].y - tx[0].y); float3 vt = lerp( vert[0], vert[2], interp ); interp = tx[0].x + (tx[2].x - tx[0].x) * interp; vt -= vert[1]; if (tx[1].x < interp) vt *= -1.f; float dt = dot( vt, nrm[i] ); vt -= nrm[i] * dt; tangent[i] = normalize(vt); /* SORT */ if ( tx[0].x < tx[1].x ) { float3 tmpV = vert[0]; vert[0] = vert[1]; vert[1] = tmpV; float2 tmpTX = tx[0]; tx[0] = tx[1]; tx[1] = tmpTX; } if ( tx[0].x < tx[2].x ) { float3 tmpV = vert[0]; vert[0] = vert[2]; vert[2] = tmpV; float2 tmpTX = tx[0]; tx[0] = tx[2]; tx[2] = tmpTX; } if ( tx[1].x < tx[2].x ) { float3 tmpV = vert[1]; vert[1] = vert[2]; vert[2] = tmpV; float2 tmpTX = tx[1]; tx[1] = tx[2]; tx[2] = tmpTX; } /* CALCULATE BI-TANGENT */ if ( abs(tx[2].x - tx[0].x) < 0.0001f ) interp = 1.f; else interp = (tx[1].x - tx[0].x) / (tx[2].x - tx[0].x); vt = lerp( vert[0], vert[2], interp ); interp = tx[0].y + (tx[2].y - tx[0].y) * interp; vt -= vert[1]; if (tx[1].y < interp) vt *= -1.f; dt = dot( vt, nrm[i] ); vt -= nrm[i] * dt; biTang[i] = normalize(vt); } // for // Output triangle emitVertex( iPos[0] : POSITION, iTexcoord[0] : TEXCOORD0, iNormal[0] : TEXCOORD1, tangent[0] : TEXCOORD2, biTang[0] : TEXCOORD3 ); emitVertex( iPos[1] : POSITION, iTexcoord[1] : TEXCOORD0, iNormal[1] : TEXCOORD1, tangent[1] : TEXCOORD2, biTang[1] : TEXCOORD3 ); emitVertex( iPos[2] : POSITION, iTexcoord[2] : TEXCOORD0, iNormal[2] : TEXCOORD1, tangent[2] : TEXCOORD2, biTang[2] : TEXCOORD3 ); } // GP_AnimMorphUpdate
Hard to notice, but another little animation was oil streaming down. Just a timed fade-in of an oil texture. To make it "stream", the fade-mask moved from up to down.
Final tricks
------------------------------
We just made a Morphing solution that uses modern techniques to optimize performance such as VBO's (allowing to keep all data stored on the GPU instead of transferring vertex-data each time), without bothering the CPU to do the interpolation math,
Two more tricks I'd like to explain is having an "influence factor", and updating data inside a VBO. Morphing animations just aren't flexible when it comes to dynamic controls. But there is at least one simple trick you can apply: "influence". In the demo movie, you'll see the RadarBlob breathing much faster and more intense at the last seconds. We didn't make multiple animations though. We just speeded up the animation-timer, and increased this mysterious "influence factor". Well, if you took a good look at the code you already saw how it works: you just do a second interpolation between the original vertex pose, and the animated pose.
Last but not least, don't forget you can actually store the updated positions/normals into a (second) VBO. In the case of Tower22, this monster will get rendered many times per cycle. Three shadowcasting lamps are on its head, so it will appear in their depthMaps. Also the water reflection and glossy wall reflections will need this monster. All in all, this guy may get rendered up to 12 times in a single frame. Now the interpolation math isn't that hard, but the recalculation of the tangents and all the texture applies concerned me a bit. So instead of re-doing all those steps for each pass, I update the monster VBO first, using Vertex-Streaming / Transform-Feedback. So first store the morphed vertex-positions/normals/tangents for the current time into a secundary VBO, then for all passes just apply the 2nd VBO so we don't have to calculate anything anymore. See the links below for some details about this technique:
http://tower22.blogspot.com/2011/08/golden-particle-shower.html
Case closed.
Thursday, May 24, 2012
Making of Radar demo #7: a little bit of koreander on top
Almost through. To conclude this "Making off", I'd like to cover how we made / animated the monster, finalized the rooms, and last but not least, how the sounds were done. But that's for the next post, as I still have to ask David how he did it. My audio-knowledge doesn't go much further than a FMOD implementation and MC Hammer :)
Pimp my Radar
------------------------
As we arrived in December, quite a lot of the textures and assets had been done by then. Yet, some rooms still felt empty, out of place, or just not right. Placing another concrete wallpaper or toying around with decals (those are transparent overlays such as the wall-dirt, cracks, cigarette butts or signs) can help a lot, and also simple light-flare sprites added a lot of swing. But even better was to grab Julio's hand and walk through each room for final adjustments.
So you made a bunch of rooms with fancy graphical tricks and quality textures. But what is the "message" or function of each room? As mentioned before, by nature a concrete bunker isn't the most exciting place. To make the (rather long) movie-fly-through somewhat interesting, each room needed at least one eye-catcher. For example, the otherwise boring tunnels were filled with green lamps and airvent "gasses". For each room, we took a few screenshots, and then Julio Photosouped them. Mainly the light-setup was enhanced (ambient light, contrasts, fog), and objects or decals were added. A hole in the left wall, some wires on the right wall, empty bottle on the table, poop on the ceiling fan, that kind of stuff.
Those "perfected" versions of the rooms then got back in the mailbox, and were used as a master-reference model. Basically my task was to tweak shaders, lights or the scene setup until it matched as close as possible with the reference image. And in some cases, those images caused some extra modeling/texture work for Sergi and Julio. Other floors, pipes, canisters, et cetera. Maybe not the fastest method to get things done, but all in all, the quality of the rooms got a serious boost. Below a short overview of what the Nanny did in the Radar household.
You know those TV programs where a bunch of guys (+ a woman standing in their way) making over your house?
Call me "RadarBlob"
-----------------------
Another last-minute secret guest was our monster -his name is "RadarBlob" by the way, nice to meet you too-. Even with better looking rooms, the whole demo trip was still a bit dull. Originally I planned to show some physics instead. Throwing barrels from the stairs and into the water. But since there were too many physics issues for a good Bob Hope show, (at that time we were upgrading to a newer version of the Newton physics engine as well) something else had to draw the attention. Since Tower22 is a horror-game, why not do something with erh… monsters?
With the limited time, we had to keep the monster simple. No AI or complex scripted stuff, and neither animations (hence we don't even have a real animator yet). The room where the monster was placed was just a meaningless space so far. Filled with water... It would have been quite an anti-climax to end the movie in that room, so I made a drawing of a turd-like thing, connected with hydraulic hoses to the ceiling. Yeah, I love the monster & mechanics combi. Reminds me of Doom, Quake, and all the hydraulic systems we deal with at my work.
Uhmmm... luckily Robert quickly made a more impressive, muscular turd variant. So, while we were pimping the rooms, Robert made a high-poly model and first-version textures. The first in-game versions still looked a bit dull though. It needed to be bigger in order to become a bit scary, and thus a new room with a higher ceiling. Also the specular lighting required a lot of tweaks to make it more nasty and icky. Unfortunately there was no time to make an advanced skin lighting technique (on the wish list, for sure), so I just uses sharp specular highlights and a bit of “RIM” (wrap-around or “backlighting”) to fix it. Furthermore, Julio upgraded the textures and added some ice chunks as well to add some sense in the scene. Icy water next and nitro-tanks… Let’s unfreeze the beast during the last demo minute.
Still sucks.
Ah, have a Snickers, and there was Julio's master reference drawing. It's nice to be creative.
Maybe using some kind of animation wouldn't be bad either. Leaking oil streams, steam particles blowing out, and a "breath" animation to make it come alive. Only problem was/is that the skeleton-animation features haven't been updated in the engine yet, and we ran out of time. Asides, using bones for an organic blob like this probably wouldn't be the most handy way to animate it anyway. So instead, we went for good old "Morphing" animations.
In the next post, that will hopefully quickly follow for a change, I'll show some more in-depth details about how we did that.
Pimp my Radar
------------------------
As we arrived in December, quite a lot of the textures and assets had been done by then. Yet, some rooms still felt empty, out of place, or just not right. Placing another concrete wallpaper or toying around with decals (those are transparent overlays such as the wall-dirt, cracks, cigarette butts or signs) can help a lot, and also simple light-flare sprites added a lot of swing. But even better was to grab Julio's hand and walk through each room for final adjustments.
So you made a bunch of rooms with fancy graphical tricks and quality textures. But what is the "message" or function of each room? As mentioned before, by nature a concrete bunker isn't the most exciting place. To make the (rather long) movie-fly-through somewhat interesting, each room needed at least one eye-catcher. For example, the otherwise boring tunnels were filled with green lamps and airvent "gasses". For each room, we took a few screenshots, and then Julio Photosouped them. Mainly the light-setup was enhanced (ambient light, contrasts, fog), and objects or decals were added. A hole in the left wall, some wires on the right wall, empty bottle on the table, poop on the ceiling fan, that kind of stuff.
Those "perfected" versions of the rooms then got back in the mailbox, and were used as a master-reference model. Basically my task was to tweak shaders, lights or the scene setup until it matched as close as possible with the reference image. And in some cases, those images caused some extra modeling/texture work for Sergi and Julio. Other floors, pipes, canisters, et cetera. Maybe not the fastest method to get things done, but all in all, the quality of the rooms got a serious boost. Below a short overview of what the Nanny did in the Radar household.
You know those TV programs where a bunch of guys (+ a woman standing in their way) making over your house?
The barracks: > Added junk, rusty beds, cold wind from the outside, light flares
The dressroom:> Wires with plastic sheets, large rusty ceiling fan
The stair: > Added some pipes, a lamp, and a canister
Central room > Snow and wind. Added particle clouds, a better skybox, red lamps.
Toilets > We actually hided that useless room with lightshafts :)
ControlRoom > Terminal, alarm, red lights
Lower central > Water, waterdrips, more lamps, a bit of snowdust clouds
Tunnels > Green lampflares, airvent "clouds", large trunks, rack
Monsterroom > Ice, particles, monster, nitro-tanks
Warehouse > Ceiling pipes, floor damage, wet floor pools, filled the racks
Call me "RadarBlob"
-----------------------
Another last-minute secret guest was our monster -his name is "RadarBlob" by the way, nice to meet you too-. Even with better looking rooms, the whole demo trip was still a bit dull. Originally I planned to show some physics instead. Throwing barrels from the stairs and into the water. But since there were too many physics issues for a good Bob Hope show, (at that time we were upgrading to a newer version of the Newton physics engine as well) something else had to draw the attention. Since Tower22 is a horror-game, why not do something with erh… monsters?
With the limited time, we had to keep the monster simple. No AI or complex scripted stuff, and neither animations (hence we don't even have a real animator yet). The room where the monster was placed was just a meaningless space so far. Filled with water... It would have been quite an anti-climax to end the movie in that room, so I made a drawing of a turd-like thing, connected with hydraulic hoses to the ceiling. Yeah, I love the monster & mechanics combi. Reminds me of Doom, Quake, and all the hydraulic systems we deal with at my work.
Uhmmm... luckily Robert quickly made a more impressive, muscular turd variant. So, while we were pimping the rooms, Robert made a high-poly model and first-version textures. The first in-game versions still looked a bit dull though. It needed to be bigger in order to become a bit scary, and thus a new room with a higher ceiling. Also the specular lighting required a lot of tweaks to make it more nasty and icky. Unfortunately there was no time to make an advanced skin lighting technique (on the wish list, for sure), so I just uses sharp specular highlights and a bit of “RIM” (wrap-around or “backlighting”) to fix it. Furthermore, Julio upgraded the textures and added some ice chunks as well to add some sense in the scene. Icy water next and nitro-tanks… Let’s unfreeze the beast during the last demo minute.
Still sucks.
Ah, have a Snickers, and there was Julio's master reference drawing. It's nice to be creative.
Maybe using some kind of animation wouldn't be bad either. Leaking oil streams, steam particles blowing out, and a "breath" animation to make it come alive. Only problem was/is that the skeleton-animation features haven't been updated in the engine yet, and we ran out of time. Asides, using bones for an organic blob like this probably wouldn't be the most handy way to animate it anyway. So instead, we went for good old "Morphing" animations.
In the next post, that will hopefully quickly follow for a change, I'll show some more in-depth details about how we did that.
Sunday, May 13, 2012
Loading... please wait
What the hell is wrong with computers, or wait, what the hell is wrong with software these days? You would expect that future computers can handle our typical tasks without a sweat, but that's not exactly the case. Are the rising hardware-specs fooling us, or does the software get slower each iteration? Here an emotional plea from someone who still gots bothered by sluggish, hanging, syrup computers.
Holy shit, Intel-Inside!
In 1998 -I'll pick a year that Windows started working a bit-, we were able to browse the internet –still an ‘innocent’ toy back then-, write an e-mail(what?!), print a Word(Perfect) document, manage the disk via Explorer, and even better, play Halflife. Of course, we also had charming blue-screens and it wasn't all that fast. Booting the computer took centuries, you couldn't open too many programs at the same time, and internet was as slow as the brown paste Robocop eats. But that was mainly due the cables and hyperslow modems, being interrupted by a malformed robot-voice of your mother if she tried to call at the same time.
I don't know the exact numbers, but in our house, I believe we had a Pentium 233 or 300 at that time. Single core of course. The average user probably thought “multi-threading” was another word for warpspeed in Startrek back then. Memory... 128 MB or something? There was a Soundblaster, a 4 or 8 Gb harddrive called "Bigfoot" to make it sound even more awesome, and a 15 inch monitor that could be used to fire holes in boats with a pirate cannon. A 16x speed (16!) CD-Rom drive. And a disk-drive, just in case you needed to fix Windows. And yes, I've seen my father doing that a few thousand times. Not sure whether that was really necessary, or he just liked screwing around with Windows and the BIOS. We never really had stabile computers, that’s for sure.
Videocards. These days, for me, the videocard is the most important instrument in a computer. But back then it was a piece of luxery, not really needed. I believe we had a Voodoo 'something' card. And I never understood how it would make games run faster or more beautiful. Don't blame me, 1998 was also the year I started programming (after some Q-Basic in 1997). Anyhow, “Software rendering”, which means the CPU did all the 3D work instead of a specialized piece of hardware, was common.
Tower22 has become kitchen-interior rendering software.
Holy shit, 4 Intels inside!
Anyway, compare those numbers with what we have now. At least two or four 2.000 to 3.000 mHz cores. In dumb-theory, that should be about 20 to 40 times faster than the Pentium 300. In reality, it might be even faster for very specific tasks that fully utilize parallel processing, since Intel and AMD spend a lot of magic in Multithreading, Hyperthreading, and whatsoever. RAM memory exploded from 128/256 MB to 4 gigs, or 8+ in case you have a 64-bit system. At least 16 times more memory to work with (+ faster chips/buslines). Harddrives? I remember removing "big files" of 1 megabyte or more once in a while to make space for a new 300 MB game. Now I still have to remove "big programs" once in a while to make space on the 300 Gb drives. And 300 Gb isn't that much really, people manage to stuff terabytes with games/videos/porn. For the info, 1 terabyte is enough to back-up 125x 8Gb disks, or capture 212 single-layer DVD's. Hence, old disks couldn't even store 1 DVD. Then again DVD didn't exist yet, instead we had ~700 MB CD-Roms. I won't compare CD-Rom reading speeds. Last time I used that thing was.... no idaa. USB and online file transfer took over. As we laughed at our fathers with their 8” floppies and LP’s, our kids will laugh at us Compact-Disc generation.
Last but not least, we have videocards these days. Big expensive ones. Videocards on themselves may have 1+ gig of memory (can be used to hold your game geometry and textures for example), and a hotdamn fast set of GPU's. Now I can clearly see the videocards doing their work when it comes to running games. Every 2 or 3 years, I'll buy a new card (or sooner in case it burned again due stuck fans). And a game like Tower22 often doubles or triples the framerate. Good job. As for you, just compare your PC game collections. 1998: Halflife, Sin, Carmageddon II versus 2010+: Crysis2, Battlefield, GTA V (almost!), ... Now as an old whiner I'm not saying all games are better these days, but if you can't see the (graphical) progress, you're as blind as a beaten-up mole.
Holy shit, nothing happens inside!
…Then WHY am I not seeing this progress in other software? When writing an e-mail, Windows Live mail often hangs for 10 or 20 seconds because it's doing... something. An e-mail! Just text! Nice to have 4Gb RAM on my 32-bit system, but ~50% is used by Windows and background trash (yes, I check the starting-up programs with msconfig). Why is a chatting program like Skype using 100 MB? Internet is shit too. On my comp, there are always 4 to 8 pages open in the background. Consuming hundreds of megabytes. And I'm not talking about Radioplayers, video-streamers or Flashgames. Just forums and stuff. Pfff, Flash Games. how is it possible a simple zombie-killer flashgame takes up almost 100% CPU? It's a fucking Flash game, not Battlefield 6000. The NES did a better job. Using Chrome here by the way, Internet Explorer is even worse. If I click the "e" icon, I want to Google something within the next 3 seconds. Not first wait half a minute. Each iteration of IExplorer seems to get worse, even though they threw away a lot of useless features only housewives who had followed an internet-course would use. Jesus Christ, we have Fiberglass here, and it still feels like pushing turds through a 8mm plastic pipe.
More to complain? Sure, how about booting up. No matter how many times I tell Adobe to get the fuck out, it still keeps coming with updates. Every time. Is Adobe Reader so crappy it really needs an update every day? Probably it just doesn't install its updates very well, and keeps asking. Talking about updates. What on Earth is Windows Vista doing? Even if my computer is shut off from the internet, it still manages to find "updates" sometimes. And of course that always happens if I need to turn off quickly, or unannounced in the middle of the night. The Toshiba Laptop battery-alarm suddenly starts screaming like a Russian nuclear bomb silo. What happened? Vista decided to restart the (closed) laptop suddenly, and of course dozens of opened text/image files weren't saved. Yes I'm probably doing something wrong, but explain that to your grandma. Auto-update ok, but you'll have to be retarded to make a feature work like that.
Toying around with blurry reflections and glossy specular highlights for materials like this linoleum floor last week.
Sometimes it feels as if computers are slowing down deliberately after 1 or 2 years. Back in the old days you would buy a TV or VCR, expecting it to work for at least 60 years so your grandchildren could inherit it in case cold-bad times would come. Nowadays, everything falls apart after a few years. Hey people have money enough, make sure they buy our shit on a regular base. Same with mobile devices. Apart from disintegrating after a year, they keep relative slow as well. I’m pretty damn sure an average phone or industrial handheld still can’t do the good old Pentium tricks like running Halflife (software render) on a 800x600 resolution while downloading "Intergalactic"(RIP MCA) with Napster at the same time. I know that has to do with fitting mini-sized chips in a small casket, but look at the numbers… An industrial handheld barcode scanner with Windows CE/Mobile for example often runs on an ARM 533 mHz processor, with 128 MB RAM. That should be faster than the good old Pentium in theory. In practice, it doesn’t even run a single (.NET) program at decent speed. And if it crashes, it just hangs instead of getting a cool blue-screen. What a rip-off!
Software: Culture of Greed
All in all, the same old tasks are just as slow as 14 years ago. Except that the devices aren’t that big anymore, and websites, explorers, Word editors or email programs have more features and a "slick" look now. And sure, computers are doing a lot more simultaneously these days, it’s not the hardware's fault. And in my case, the computer partially got slow due the huge amount of programs. Virus scanners, Dropbox, creative tools + their drivers, and about 20 different programming tools. Now Delphi is pretty nice and quiet, but others interfere with the system like a meddlesome aunt.
Yet, that shouldn't be a problem if all programs back of as long as I don't call them. But each of them dumps crap in the register, has invisible stuff going on, bothers with all kinds of extra functions, and acts like a spoiled princes claiming all computer resources. That might be the main problem; the programming philosophy. I can’t speak for all, but it seems designers lend on the “infinite” resources of nowadays computers. 4 Gigs of RAM, so reserving 100 Megabytes more just in case can't hurt right? The user probably likes our cool product to start-up automatically, and check for updates in the background. Processor speed? Who cares, dual cores mate. Again, all of this wouldn't be a problem, if there weren't many more programs trying to do the same simultaneously. You can't have 10 kings on one throne. Yep, having more resources makes lazy, and I speak from experience since I’m also familiar with the other side; a few megahertz microcontrollers with 1kb memory. Such systems force you to make smarter solutions, caring about each bit. While on a modern PC, you can turn a simple application into behemoth for the sake of “easy maintainable programming”.
Microsoft should know better with their Live and Internet Explorer products. I can’t really speak for Windows 7 yet, but Vista gave a wrong example as its programs were using too much memory and CPU cycles as well. Why does Live Mail work on web-based technologies anyway? It's asking for performance problems. Sure, it may give some more options in these modern cloud / social-media / device-synchronizing times. But in the end, I just want check or write a mail and don't give a crap about all those features unless I explicitly ask for it. Usually I'm using Notepad over Word, or the old PaintShop V over PaintShop XI. You know why? Because it starts in a second, rather than half a minute, including loads or prompts and questions. Software-designers should try to make things more simplistic again, don't you agree?
Ah, that's better.
Holy shit, Intel-Inside!
In 1998 -I'll pick a year that Windows started working a bit-, we were able to browse the internet –still an ‘innocent’ toy back then-, write an e-mail(what?!), print a Word(Perfect) document, manage the disk via Explorer, and even better, play Halflife. Of course, we also had charming blue-screens and it wasn't all that fast. Booting the computer took centuries, you couldn't open too many programs at the same time, and internet was as slow as the brown paste Robocop eats. But that was mainly due the cables and hyperslow modems, being interrupted by a malformed robot-voice of your mother if she tried to call at the same time.
I don't know the exact numbers, but in our house, I believe we had a Pentium 233 or 300 at that time. Single core of course. The average user probably thought “multi-threading” was another word for warpspeed in Startrek back then. Memory... 128 MB or something? There was a Soundblaster, a 4 or 8 Gb harddrive called "Bigfoot" to make it sound even more awesome, and a 15 inch monitor that could be used to fire holes in boats with a pirate cannon. A 16x speed (16!) CD-Rom drive. And a disk-drive, just in case you needed to fix Windows. And yes, I've seen my father doing that a few thousand times. Not sure whether that was really necessary, or he just liked screwing around with Windows and the BIOS. We never really had stabile computers, that’s for sure.
Videocards. These days, for me, the videocard is the most important instrument in a computer. But back then it was a piece of luxery, not really needed. I believe we had a Voodoo 'something' card. And I never understood how it would make games run faster or more beautiful. Don't blame me, 1998 was also the year I started programming (after some Q-Basic in 1997). Anyhow, “Software rendering”, which means the CPU did all the 3D work instead of a specialized piece of hardware, was common.
Tower22 has become kitchen-interior rendering software.
Holy shit, 4 Intels inside!
Anyway, compare those numbers with what we have now. At least two or four 2.000 to 3.000 mHz cores. In dumb-theory, that should be about 20 to 40 times faster than the Pentium 300. In reality, it might be even faster for very specific tasks that fully utilize parallel processing, since Intel and AMD spend a lot of magic in Multithreading, Hyperthreading, and whatsoever. RAM memory exploded from 128/256 MB to 4 gigs, or 8+ in case you have a 64-bit system. At least 16 times more memory to work with (+ faster chips/buslines). Harddrives? I remember removing "big files" of 1 megabyte or more once in a while to make space for a new 300 MB game. Now I still have to remove "big programs" once in a while to make space on the 300 Gb drives. And 300 Gb isn't that much really, people manage to stuff terabytes with games/videos/porn. For the info, 1 terabyte is enough to back-up 125x 8Gb disks, or capture 212 single-layer DVD's. Hence, old disks couldn't even store 1 DVD. Then again DVD didn't exist yet, instead we had ~700 MB CD-Roms. I won't compare CD-Rom reading speeds. Last time I used that thing was.... no idaa. USB and online file transfer took over. As we laughed at our fathers with their 8” floppies and LP’s, our kids will laugh at us Compact-Disc generation.
Last but not least, we have videocards these days. Big expensive ones. Videocards on themselves may have 1+ gig of memory (can be used to hold your game geometry and textures for example), and a hotdamn fast set of GPU's. Now I can clearly see the videocards doing their work when it comes to running games. Every 2 or 3 years, I'll buy a new card (or sooner in case it burned again due stuck fans). And a game like Tower22 often doubles or triples the framerate. Good job. As for you, just compare your PC game collections. 1998: Halflife, Sin, Carmageddon II versus 2010+: Crysis2, Battlefield, GTA V (almost!), ... Now as an old whiner I'm not saying all games are better these days, but if you can't see the (graphical) progress, you're as blind as a beaten-up mole.
Holy shit, nothing happens inside!
…Then WHY am I not seeing this progress in other software? When writing an e-mail, Windows Live mail often hangs for 10 or 20 seconds because it's doing... something. An e-mail! Just text! Nice to have 4Gb RAM on my 32-bit system, but ~50% is used by Windows and background trash (yes, I check the starting-up programs with msconfig). Why is a chatting program like Skype using 100 MB? Internet is shit too. On my comp, there are always 4 to 8 pages open in the background. Consuming hundreds of megabytes. And I'm not talking about Radioplayers, video-streamers or Flashgames. Just forums and stuff. Pfff, Flash Games. how is it possible a simple zombie-killer flashgame takes up almost 100% CPU? It's a fucking Flash game, not Battlefield 6000. The NES did a better job. Using Chrome here by the way, Internet Explorer is even worse. If I click the "e" icon, I want to Google something within the next 3 seconds. Not first wait half a minute. Each iteration of IExplorer seems to get worse, even though they threw away a lot of useless features only housewives who had followed an internet-course would use. Jesus Christ, we have Fiberglass here, and it still feels like pushing turds through a 8mm plastic pipe.
More to complain? Sure, how about booting up. No matter how many times I tell Adobe to get the fuck out, it still keeps coming with updates. Every time. Is Adobe Reader so crappy it really needs an update every day? Probably it just doesn't install its updates very well, and keeps asking. Talking about updates. What on Earth is Windows Vista doing? Even if my computer is shut off from the internet, it still manages to find "updates" sometimes. And of course that always happens if I need to turn off quickly, or unannounced in the middle of the night. The Toshiba Laptop battery-alarm suddenly starts screaming like a Russian nuclear bomb silo. What happened? Vista decided to restart the (closed) laptop suddenly, and of course dozens of opened text/image files weren't saved. Yes I'm probably doing something wrong, but explain that to your grandma. Auto-update ok, but you'll have to be retarded to make a feature work like that.
Toying around with blurry reflections and glossy specular highlights for materials like this linoleum floor last week.
Sometimes it feels as if computers are slowing down deliberately after 1 or 2 years. Back in the old days you would buy a TV or VCR, expecting it to work for at least 60 years so your grandchildren could inherit it in case cold-bad times would come. Nowadays, everything falls apart after a few years. Hey people have money enough, make sure they buy our shit on a regular base. Same with mobile devices. Apart from disintegrating after a year, they keep relative slow as well. I’m pretty damn sure an average phone or industrial handheld still can’t do the good old Pentium tricks like running Halflife (software render) on a 800x600 resolution while downloading "Intergalactic"(RIP MCA) with Napster at the same time. I know that has to do with fitting mini-sized chips in a small casket, but look at the numbers… An industrial handheld barcode scanner with Windows CE/Mobile for example often runs on an ARM 533 mHz processor, with 128 MB RAM. That should be faster than the good old Pentium in theory. In practice, it doesn’t even run a single (.NET) program at decent speed. And if it crashes, it just hangs instead of getting a cool blue-screen. What a rip-off!
Software: Culture of Greed
All in all, the same old tasks are just as slow as 14 years ago. Except that the devices aren’t that big anymore, and websites, explorers, Word editors or email programs have more features and a "slick" look now. And sure, computers are doing a lot more simultaneously these days, it’s not the hardware's fault. And in my case, the computer partially got slow due the huge amount of programs. Virus scanners, Dropbox, creative tools + their drivers, and about 20 different programming tools. Now Delphi is pretty nice and quiet, but others interfere with the system like a meddlesome aunt.
Yet, that shouldn't be a problem if all programs back of as long as I don't call them. But each of them dumps crap in the register, has invisible stuff going on, bothers with all kinds of extra functions, and acts like a spoiled princes claiming all computer resources. That might be the main problem; the programming philosophy. I can’t speak for all, but it seems designers lend on the “infinite” resources of nowadays computers. 4 Gigs of RAM, so reserving 100 Megabytes more just in case can't hurt right? The user probably likes our cool product to start-up automatically, and check for updates in the background. Processor speed? Who cares, dual cores mate. Again, all of this wouldn't be a problem, if there weren't many more programs trying to do the same simultaneously. You can't have 10 kings on one throne. Yep, having more resources makes lazy, and I speak from experience since I’m also familiar with the other side; a few megahertz microcontrollers with 1kb memory. Such systems force you to make smarter solutions, caring about each bit. While on a modern PC, you can turn a simple application into behemoth for the sake of “easy maintainable programming”.
Microsoft should know better with their Live and Internet Explorer products. I can’t really speak for Windows 7 yet, but Vista gave a wrong example as its programs were using too much memory and CPU cycles as well. Why does Live Mail work on web-based technologies anyway? It's asking for performance problems. Sure, it may give some more options in these modern cloud / social-media / device-synchronizing times. But in the end, I just want check or write a mail and don't give a crap about all those features unless I explicitly ask for it. Usually I'm using Notepad over Word, or the old PaintShop V over PaintShop XI. You know why? Because it starts in a second, rather than half a minute, including loads or prompts and questions. Software-designers should try to make things more simplistic again, don't you agree?
Ah, that's better.
Sunday, April 29, 2012
Making of Radar demo #6: The Byteplumber
So far we covered mostly creative-production aspects of this demo. Making ideas, 3D modeling rooms, doing objects, and so on. So, what was my task as a programmer? Just hanging around a bit?
Well, as you know, the Tower22 engine isn't exactly finished. I can't recall the exact things that had to be done for this demo, but the listing was quite long... endless really. Once we decided to decorate the place with a snowy theme, one of the main new features that had to be implemented was stuff to make it look cold. Ice and falling snow particles for example. Furthermore, we needed water, And while doing so, I thought having water-ripples caused by the falling snow/drip particles would look nice too. Some more visual effects were:
Let's not forget that games require more than just graphics, although this Tech-Demo was merely a compilation of rooms and effects, supported by spooky tunes. Spooky tunes... I still had to finish some unfinished business with FMOD, a third-party sound engine. And the camera-flight through those rooms needed some help as well. Portal-culling had to be improved and cleansed from some nasty disappearance-bugs, and while trying to capture a movie, I realized having a recording-playback tool would be nice too. The movie has been recorder quite a lot times, but the camera path had to be the same each time. Impossible to manually do that, so instead a camera-position logger has been added.
Usually adding a new feature ends up in a lot more work in order to integrate it nicely into the engine, and to prepare it for eventual other usage as well. That particle system for example is not only dealing with falling snow of course. Before even starting, the imagination flooded with fires, smoke, clouds, stinky flies around corpses, 80ies laser-Tron effects, green gasses, fog fields, rain, tornado's, mushroomcloud-laying-motherfuckers, and who knows what. So, I didn't just make a particle generator for snow, I made an all-round particle generator. And the extra effort paid off later on with the waterdrops, gasses and snowdust in the same demo. If you need to add or change something, do it well.
The ice required a new pass in the engine, as it uses a simple sort of sub-surface-scattering. First the the surface will get litten normally, then it gets rendered again, scattering its own light and the background contents.
Between adding features, I also had to support the modelers. Not just by giving instructions and feedback, but also by providing their tools of course. An engine is not just a library that can be used to render/drive a game. It includes the editors, tools, documents, and so on. After all, your artists rely on that. If I want them to make a rotating fan or animated screens on a computer, the editor needs functions to create those.
The Fly is Dead, yeah
========================================
Another thing that takes a (too) big portion, is bug-solving. Bugless programming is as realistic as having a relation and never arguing. Fixing things is part of the job. However, the engine sometimes feels like a Jenga Tower(22). Instead of removing blocks, we are inserting blocks. But at the same time, something else gets pushed out of the tower. Some typical bugs like "#$% barrel object doesn't cast shadows anymore" have been fixed dozens of times.
Sniff, smells like bad design? Maybe, although I would like to call it "lack of manpower". The engine has hundred-thousands code-lines, stuffed in unfinished sub-modules. In a real game-company, -you know, where they have more than one programmer-, each programmer(team) is assigned to a specific module, and will deliver something documented, tested, finished. At least, that's what they should do. But here at... erh, we don't even have a name, I'm programming everything. So, there is little to no time to finish modules, let alone document things. Instead, I work "on demand". Whenever artist X needs a certain effect, or if the game needs a new mechanic, I'll implement it. Of course, the modules have been designed with all possible functionality in mind so it's not that I have to hack in future add-ons, like stuffing a body in too small garbage bag. But since I work in small fragments on each module, the chance on bugs increases as some code-parts are left unfinished, untested, or if I forget a couple of conditions when adding a new feature months later.
Yes, it would be better to finish a module completely rather than stopping somewhere halfway. Then again, there is little time, and its often pretty meaningless to work on something that won't be needed yet. For example, I could renew the whole animation-module. But as long as there is no playermodel with a proper stand-walk-run animation-set, its not very motivating to start on it. In fact, it probably only makes bad code, as it can't be tested right away. I call this "blind coding". You make something, but you have no idea if it really works and fits the needs yet. Coding in advance only works if the goals are very clear, and with some test-subjects. Otherwise -> a waste of time.
Last but not least, I would hate to spend weeks/months on the same dull module. It's a relief to switch over from graphics to physics, or from sound to gameplay once in a while. Hey, I'm not spending so much unpaid hours of free time to torture myself! In the end, having fun in what you do might be the biggest key to success. Although I got to admit fixing bugs is goddamn annoying. Progress is the things that really rewards, not spending a couple of nights on the same old bug again. It's like the police catching the same toothless alcoholic prostitute every weekend.
Sometimes bugs can turn out pretty cool through. Forgot what the hell went wrong here, but it looks kinda angry.
========================================
Don’t worry, we’ll get there. Bit by bit. Each time when a new room or object is finished, the tools, engine, shaders and other related modules get bigger, faster, richer, tested, and better oiled. It might not happen in a truly professional way, but as said, programming is a story without an ending anyway. Do you really think the programmers at Valve or Crytek stopped one day during development, as their part was completely finished? Of course not. There are always glitches, bugs, missing features, non-optimized code. And otherwise modern-technology passes by with merciless speed, forcing you to upgrade or even rebuild certain parts again. And again. Unlike making a 3D model, a programming task is never really finished. That can be frustrating sometimes. Honestly, it makes me “restless”. Ever since I started programming and wanted to make a game ~13 years ago, I can’t just play take a pause, watch a movie, play a videogame or chill out with a fishing rod anymore. Because the programming is never finished, there is always that urgent feeling that something needs to be done. Not spending time on “the job” makes me feel useless. I’ll go to bed with it, and wake up with it.
Sure, I still have time left for my work, family, and drinking beer with the guys. But I need to be careful this hobby won’t become a sick obsession. Then again, we all have obsessions, don’t we? Some spend years on fixing old crappy cars. Some are obsessed by sixpack-abs and visit the gym every day. Others are obsessed by sixpacks of beer, and your mother is obsessed by cleaning the house and will fight the lost battle against dust. It’s this drive that makes us good at things. And what does it gives us at the end? Hell, I don’t know. The sports-guy will get old and fat eventually, mom has to dust the house again one day later, the car-lover doesn’t give a shit about cars that work again, he will start on another piece of junk. As for Tower22...? It will be my 5 minutes of fame when it gets finished ;)
Well, as you know, the Tower22 engine isn't exactly finished. I can't recall the exact things that had to be done for this demo, but the listing was quite long... endless really. Once we decided to decorate the place with a snowy theme, one of the main new features that had to be implemented was stuff to make it look cold. Ice and falling snow particles for example. Furthermore, we needed water, And while doing so, I thought having water-ripples caused by the falling snow/drip particles would look nice too. Some more visual effects were:
- LightshaftsAnd probably I forgot a few things. But if you thought that would be all, you're wrong. Most of the time being spend on "programming the engine", happens on invisible, magical things. And fixing bugs. Many of the points above have already been implemented once, but using old clunky code. More than often it happens I discard the old module, and replace it with modern techniques. The particles for example. Making a bunch of snowflakes falling down softly isn't the most difficult since unsliced bread. However, after looking some tasty modern-particle demo's, I decided we needed a GPU approach too. Which means the graphics-card will update the particle positions/physics instead of the CPU.
- Snowdust particles
- (Compressed) DDS textures
- Gas particles
- Sharper looking graphics / improved specular
- Parallax Offset Mapping
- Waterpool decals
- FXAA (Post screen Anti Aliasing for smoothing the edges a bit)
- Heat-haze sprites
- Monster morphing animation (the "breathing")
Let's not forget that games require more than just graphics, although this Tech-Demo was merely a compilation of rooms and effects, supported by spooky tunes. Spooky tunes... I still had to finish some unfinished business with FMOD, a third-party sound engine. And the camera-flight through those rooms needed some help as well. Portal-culling had to be improved and cleansed from some nasty disappearance-bugs, and while trying to capture a movie, I realized having a recording-playback tool would be nice too. The movie has been recorder quite a lot times, but the camera path had to be the same each time. Impossible to manually do that, so instead a camera-position logger has been added.
Usually adding a new feature ends up in a lot more work in order to integrate it nicely into the engine, and to prepare it for eventual other usage as well. That particle system for example is not only dealing with falling snow of course. Before even starting, the imagination flooded with fires, smoke, clouds, stinky flies around corpses, 80ies laser-Tron effects, green gasses, fog fields, rain, tornado's, mushroomcloud-laying-motherfuckers, and who knows what. So, I didn't just make a particle generator for snow, I made an all-round particle generator. And the extra effort paid off later on with the waterdrops, gasses and snowdust in the same demo. If you need to add or change something, do it well.
The ice required a new pass in the engine, as it uses a simple sort of sub-surface-scattering. First the the surface will get litten normally, then it gets rendered again, scattering its own light and the background contents.
Between adding features, I also had to support the modelers. Not just by giving instructions and feedback, but also by providing their tools of course. An engine is not just a library that can be used to render/drive a game. It includes the editors, tools, documents, and so on. After all, your artists rely on that. If I want them to make a rotating fan or animated screens on a computer, the editor needs functions to create those.
The Fly is Dead, yeah
========================================
Another thing that takes a (too) big portion, is bug-solving. Bugless programming is as realistic as having a relation and never arguing. Fixing things is part of the job. However, the engine sometimes feels like a Jenga Tower(22). Instead of removing blocks, we are inserting blocks. But at the same time, something else gets pushed out of the tower. Some typical bugs like "#$% barrel object doesn't cast shadows anymore" have been fixed dozens of times.
Sniff, smells like bad design? Maybe, although I would like to call it "lack of manpower". The engine has hundred-thousands code-lines, stuffed in unfinished sub-modules. In a real game-company, -you know, where they have more than one programmer-, each programmer(team) is assigned to a specific module, and will deliver something documented, tested, finished. At least, that's what they should do. But here at... erh, we don't even have a name, I'm programming everything. So, there is little to no time to finish modules, let alone document things. Instead, I work "on demand". Whenever artist X needs a certain effect, or if the game needs a new mechanic, I'll implement it. Of course, the modules have been designed with all possible functionality in mind so it's not that I have to hack in future add-ons, like stuffing a body in too small garbage bag. But since I work in small fragments on each module, the chance on bugs increases as some code-parts are left unfinished, untested, or if I forget a couple of conditions when adding a new feature months later.
Yes, it would be better to finish a module completely rather than stopping somewhere halfway. Then again, there is little time, and its often pretty meaningless to work on something that won't be needed yet. For example, I could renew the whole animation-module. But as long as there is no playermodel with a proper stand-walk-run animation-set, its not very motivating to start on it. In fact, it probably only makes bad code, as it can't be tested right away. I call this "blind coding". You make something, but you have no idea if it really works and fits the needs yet. Coding in advance only works if the goals are very clear, and with some test-subjects. Otherwise -> a waste of time.
Last but not least, I would hate to spend weeks/months on the same dull module. It's a relief to switch over from graphics to physics, or from sound to gameplay once in a while. Hey, I'm not spending so much unpaid hours of free time to torture myself! In the end, having fun in what you do might be the biggest key to success. Although I got to admit fixing bugs is goddamn annoying. Progress is the things that really rewards, not spending a couple of nights on the same old bug again. It's like the police catching the same toothless alcoholic prostitute every weekend.
Sometimes bugs can turn out pretty cool through. Forgot what the hell went wrong here, but it looks kinda angry.
========================================
Don’t worry, we’ll get there. Bit by bit. Each time when a new room or object is finished, the tools, engine, shaders and other related modules get bigger, faster, richer, tested, and better oiled. It might not happen in a truly professional way, but as said, programming is a story without an ending anyway. Do you really think the programmers at Valve or Crytek stopped one day during development, as their part was completely finished? Of course not. There are always glitches, bugs, missing features, non-optimized code. And otherwise modern-technology passes by with merciless speed, forcing you to upgrade or even rebuild certain parts again. And again. Unlike making a 3D model, a programming task is never really finished. That can be frustrating sometimes. Honestly, it makes me “restless”. Ever since I started programming and wanted to make a game ~13 years ago, I can’t just play take a pause, watch a movie, play a videogame or chill out with a fishing rod anymore. Because the programming is never finished, there is always that urgent feeling that something needs to be done. Not spending time on “the job” makes me feel useless. I’ll go to bed with it, and wake up with it.
Sure, I still have time left for my work, family, and drinking beer with the guys. But I need to be careful this hobby won’t become a sick obsession. Then again, we all have obsessions, don’t we? Some spend years on fixing old crappy cars. Some are obsessed by sixpack-abs and visit the gym every day. Others are obsessed by sixpacks of beer, and your mother is obsessed by cleaning the house and will fight the lost battle against dust. It’s this drive that makes us good at things. And what does it gives us at the end? Hell, I don’t know. The sports-guy will get old and fat eventually, mom has to dust the house again one day later, the car-lover doesn’t give a shit about cars that work again, he will start on another piece of junk. As for Tower22...? It will be my 5 minutes of fame when it gets finished ;)
Wednesday, April 18, 2012
Scrooge McDuck
One of the charms of this project, is that it's being made with very limited resources. Not that Tower22 is anywhere near finished, but it feels a little bit like making the impossible possible. The Tower22 headquarters is my couch and bed. We work with Commodore 64's, ancient programming languages (Delphi 7), and a handful of cowboys doing this in the spare hours. Programming is done while sleeping, models are sculpted on the toilet, sound is recorded while feeding our kids. And neither do we have a budget or art-subsidies. I pay with "good job!" emails, or ok, constructive feedback if you will. Hey, recently one of our guys got a (paid) job in the games industry and thanked for the stuff he learned with Tower22. That gives little tingles, like a proud grandpa.
Some hint me about funding websites like "Kickstarter". Now I'm not an expert, but as far as I know, these are websites that help (Indie)projects with a (small) budget. Not to buy private jets and E3-booth with robot-babes. You know, just a budget to buy a new videocard, a CD with sound effects, or maybe even to allow one or two persons to exchange some working days without their families starving. Not sure where the money comes from, probably from individuals who like to see a game happen and donate. Or maybe with good old magic. So Rick, why not grab some cash, say your boss he can stick those harvesting machines in his @ss, and chill out on the sofa with Tower22?
Well, first of all I like my jobs, I'm a loyal slave. But moreover, I'm dead scared of funders and George Washington papers. My momma always said "Nothing for free in this world boy", with a lovely black lady Chicken-Tonight voice. No she didn't say that, but they did raise me with common sense. No-one on this planet gives money just because they like you. They want something in return. Something that sells, generates more money. If EA Games knocks on the non-existent Tower office-door, with a bag of money, they expect us to finish a selling game within X years. And as soon I say "sure thing doc", they got me at the balls with a rusty vice. If our little (not so experienced) team fails to deliver, they will take my baby. A bit like how Duke Nukem Forever got finished(rushed) by another team in the end.

Every room gets multiple sketches. Tons of work, but every detail should be done with love. This one was done by newcomer Pablo btw.
But... nothing wrong with that right? Of course people expect something in return, We're not living in a yippie-hippie world. And even there people would expect services in return. Trade a cow for a donkey, publish Tower22 in return for your wife, et cetera. If I give money to a painter I don't expect him to fix the sink either, paint the damn house. Yet, there are still some problems. A publisher invests, then wants to make money. And as we all know, games play on safe. Not a miracle, because these days games aren't produces by 2 programmers in a basement anymore. Shit no, we're talking about armies of artists, expensive engines and studios, Bill Clinton and Mr. Ed the Talking Horse doing the voiceovers, complete American football teams, and very large basements of programmers. And not to forget all the marketing of course. Millions of dollars are invested, so publishers are very reserved with experimental ideas.
But I can already tell you that the Tower22 game ideas are not founded on typical selling-bombs like slow-mo bullet modus, chattering gasmasked alien soldiers, and auto-save every 5 meters that makes the game accessible for the whole family(= sellable), including your Labrador. Man, my generation was raised with impossible Super Mario jumps, no-save at all in NES games, and extremely annoying games that made the joypads fly around. Hardcore gamers (in nerd-jargon), and that's what you can expect from Tower22 as well (imagine a Gomer Pyle face now). But with a publisher on the buttons and money, a game like this will likely result in something we didn't exactly want.
But wait a minute. We were talking about small funding. To buy coffee and a new mouse and stuff. Yet, that still makes me nervous. My momma always said "Son, thou shall not steal", with a mother Theresa voice on her deathbed. No, she didn't said that, and she is still alive. But they did raise me with decency. If Billy donates 2 dollars to Tower22, then I want to make sure Billy can get a copy of this game sooner or later. No matter how small his donation was, he has faith in us, so we owe him. And honestly, at this point there is no guarantee Tower22 will be there soon, or even will be finished some day at all.
Last but not least, my momma always said "Money poisons, my dear.", with flowers and braids in her hair, barefeet, and hairy armpits. No, she didn't said that, and I don't know how her armpits look. But they did raise me non-materialistic. We make Tower22 because we are passionate. Not to get rich. Sure, a budget increases the chances. In fact, it might be the difference between a hardcopy on the shelves or keep-on-dreaming. But if someone offers help, I want to make sure he/she is doing it because he/she really loves drawing/modeling/composing/programming, and likes to see Tower22 happening. As soon as there is money, people may get greedy. Pay me more, or I'll walk away to another company with your ideas. And who is getting what with a small budget? Ten- thousand dollars sounds like a lot, but divide it through 10 people. The remainder is not even enough to pay my house two for months. Pay-per-service sounds more fair, but how to judge what a 3D cardboard-box model is worth anyway?

More corridor, this time from Borja, another newcomer doing concept art. Yes, I'm happy we finally have 2 guys doing environment sketches!
Is funding out of the question then? No, it is not, and my momma didn't say not to do it either. But before taking that step, whether grabbing 2 dollar from Billy’s pocket, or receiving big money bags + cans of helpers by a big publisher, I want to make sure we are heading the right way first. With that I mean the team must be talented, motivated and big enough to produce a substantial part of the game. That also includes some self-reflection. My part, the game-idea + engine, must work too. If first testplays turn out to be damn boring, or if the engine is as stable as a North Korean rocket, we need to change plans. The engine is in a too early stage, and the amount of content-production manhours is still too little/fluctuating to make a good planning & hard guarantees.
Hmmm... that doesn't sound very hopeful! But hold on. The team doubled the last few months. Not that more people automatically leads to more and better results -don't forget each of them also needs to be guided properly-, but in this case its certainly a step forward. I'll introduce them in a next post. Anyway, let's say if we can make a bunch of good looking / SCARY, *playable*, floors, I may look again at Kickstart or the likes. Because at that point, we proved for ourselves we are able to do it, plus we can estimate how long it takes a bit.
And let me reveal something else then. Finishing the entire game in this setup is indeed impossible, unless you are patient and play Tower22 on a classic PC in future times where we fly with cars and make love with holograms. The target for now, asides attracting some more artists with 1 or more future demo movies, is to make the first ~40% of the game, and release it (for an Indie price). Yeah that's right, a game. To play. But not the complete thing. Although I must say the game storyline is perfectly suitable to split in two, I'm not a big fan of the "Episode" approach. But in our case we have little choice. If part1 is a success, getting funds and more horsepower to realize an even better second part will be much easier. And if it fails, we'd better return to our Magic cards collections and kitchen gardens. My momma always said "A man has gotta know when to stop." ;)
Some hint me about funding websites like "Kickstarter". Now I'm not an expert, but as far as I know, these are websites that help (Indie)projects with a (small) budget. Not to buy private jets and E3-booth with robot-babes. You know, just a budget to buy a new videocard, a CD with sound effects, or maybe even to allow one or two persons to exchange some working days without their families starving. Not sure where the money comes from, probably from individuals who like to see a game happen and donate. Or maybe with good old magic. So Rick, why not grab some cash, say your boss he can stick those harvesting machines in his @ss, and chill out on the sofa with Tower22?
Well, first of all I like my jobs, I'm a loyal slave. But moreover, I'm dead scared of funders and George Washington papers. My momma always said "Nothing for free in this world boy", with a lovely black lady Chicken-Tonight voice. No she didn't say that, but they did raise me with common sense. No-one on this planet gives money just because they like you. They want something in return. Something that sells, generates more money. If EA Games knocks on the non-existent Tower office-door, with a bag of money, they expect us to finish a selling game within X years. And as soon I say "sure thing doc", they got me at the balls with a rusty vice. If our little (not so experienced) team fails to deliver, they will take my baby. A bit like how Duke Nukem Forever got finished(rushed) by another team in the end.

Every room gets multiple sketches. Tons of work, but every detail should be done with love. This one was done by newcomer Pablo btw.
But... nothing wrong with that right? Of course people expect something in return, We're not living in a yippie-hippie world. And even there people would expect services in return. Trade a cow for a donkey, publish Tower22 in return for your wife, et cetera. If I give money to a painter I don't expect him to fix the sink either, paint the damn house. Yet, there are still some problems. A publisher invests, then wants to make money. And as we all know, games play on safe. Not a miracle, because these days games aren't produces by 2 programmers in a basement anymore. Shit no, we're talking about armies of artists, expensive engines and studios, Bill Clinton and Mr. Ed the Talking Horse doing the voiceovers, complete American football teams, and very large basements of programmers. And not to forget all the marketing of course. Millions of dollars are invested, so publishers are very reserved with experimental ideas.
But I can already tell you that the Tower22 game ideas are not founded on typical selling-bombs like slow-mo bullet modus, chattering gasmasked alien soldiers, and auto-save every 5 meters that makes the game accessible for the whole family(= sellable), including your Labrador. Man, my generation was raised with impossible Super Mario jumps, no-save at all in NES games, and extremely annoying games that made the joypads fly around. Hardcore gamers (in nerd-jargon), and that's what you can expect from Tower22 as well (imagine a Gomer Pyle face now). But with a publisher on the buttons and money, a game like this will likely result in something we didn't exactly want.
But wait a minute. We were talking about small funding. To buy coffee and a new mouse and stuff. Yet, that still makes me nervous. My momma always said "Son, thou shall not steal", with a mother Theresa voice on her deathbed. No, she didn't said that, and she is still alive. But they did raise me with decency. If Billy donates 2 dollars to Tower22, then I want to make sure Billy can get a copy of this game sooner or later. No matter how small his donation was, he has faith in us, so we owe him. And honestly, at this point there is no guarantee Tower22 will be there soon, or even will be finished some day at all.
Last but not least, my momma always said "Money poisons, my dear.", with flowers and braids in her hair, barefeet, and hairy armpits. No, she didn't said that, and I don't know how her armpits look. But they did raise me non-materialistic. We make Tower22 because we are passionate. Not to get rich. Sure, a budget increases the chances. In fact, it might be the difference between a hardcopy on the shelves or keep-on-dreaming. But if someone offers help, I want to make sure he/she is doing it because he/she really loves drawing/modeling/composing/programming, and likes to see Tower22 happening. As soon as there is money, people may get greedy. Pay me more, or I'll walk away to another company with your ideas. And who is getting what with a small budget? Ten- thousand dollars sounds like a lot, but divide it through 10 people. The remainder is not even enough to pay my house two for months. Pay-per-service sounds more fair, but how to judge what a 3D cardboard-box model is worth anyway?

More corridor, this time from Borja, another newcomer doing concept art. Yes, I'm happy we finally have 2 guys doing environment sketches!
Is funding out of the question then? No, it is not, and my momma didn't say not to do it either. But before taking that step, whether grabbing 2 dollar from Billy’s pocket, or receiving big money bags + cans of helpers by a big publisher, I want to make sure we are heading the right way first. With that I mean the team must be talented, motivated and big enough to produce a substantial part of the game. That also includes some self-reflection. My part, the game-idea + engine, must work too. If first testplays turn out to be damn boring, or if the engine is as stable as a North Korean rocket, we need to change plans. The engine is in a too early stage, and the amount of content-production manhours is still too little/fluctuating to make a good planning & hard guarantees.
Hmmm... that doesn't sound very hopeful! But hold on. The team doubled the last few months. Not that more people automatically leads to more and better results -don't forget each of them also needs to be guided properly-, but in this case its certainly a step forward. I'll introduce them in a next post. Anyway, let's say if we can make a bunch of good looking / SCARY, *playable*, floors, I may look again at Kickstart or the likes. Because at that point, we proved for ourselves we are able to do it, plus we can estimate how long it takes a bit.
And let me reveal something else then. Finishing the entire game in this setup is indeed impossible, unless you are patient and play Tower22 on a classic PC in future times where we fly with cars and make love with holograms. The target for now, asides attracting some more artists with 1 or more future demo movies, is to make the first ~40% of the game, and release it (for an Indie price). Yeah that's right, a game. To play. But not the complete thing. Although I must say the game storyline is perfectly suitable to split in two, I'm not a big fan of the "Episode" approach. But in our case we have little choice. If part1 is a success, getting funds and more horsepower to realize an even better second part will be much easier. And if it fails, we'd better return to our Magic cards collections and kitchen gardens. My momma always said "A man has gotta know when to stop." ;)
Monday, April 9, 2012
Making of Radar demo #5: Objects
Ever bought or rent a new empty house? Then you must be familiar with the “that looks smaller than I thought” symptom. It only takes a few steps to cross the room. But you may have also seen TV programs about people who “collect”, those who managed to stuff their house with million boxes, cats, old junk that might become handy some day, and a wife somewhere between the trash piles. That suddenly gives a whole new dimension to the space.
In games, the dimensions of a room can look misleading easily. Nowadays we can use 2048x2048 textures, entrophy, many decals, and secondary detail(normal)Maps to enhance the detail, but older games had to improvise with a handful of blurry, stretched textures. But even high quality textures still don’t contain the amount of detail a real surface has, and a wrong scaling of the texture makes the room look smaller or bigger than it should. On top, there is the 3D camera view that doesn’t match a real life eye view. In other words, we need filling for the rooms to clarify the dimensions of a room. A door, washing machine or couch gives a better idea of what a virtual metre is.

Contents gone, floor and left wall textures stretched x2

And of course, it also takes objects to define the purpose of a room. Place some metal bunkbeds and Bob Hope girl posters and you have a Vietnam barrack. Paint it pink and replace the poster with Justin Bieber and you have a girls room. Put down some pee-stained mattresses, needles and pipes, and you have a crackhouse. There is a lot you can do with a floor, 6 walls and a ceiling. So, grab an IKEA catalog, argue with your girlfriend and start filling the rooms. Three Björn chairs here, the green Aslög sink there, a mahogany Helga toilet pot over there. Oh wait… we were doing a (“Soviet”) Radar Station…
The rooms had been defined, though not all of them had a purpose yet. So I took a (imaginary) snapshot of each and made a simple sketch of what & where could be placed. Then each room would result in a list of assets to-do for Sergi, who did most of the objects for the Radar Station. But what the hell would the Russians need in a Radar Station? Well, you can find a lot of answers on websites like www.englishrussia.com. The Russians made a good habit of photographing old forgotten hospitals, schools and rocket silo’s. Too bad we realized this a little bit too late, so most of the contents we’re wild guesses. A military Radar Station, let’s see. Computers, charts, documents. A place to sleep and brush teeth for the soldiers. Facilities to lay bricks. And lot’s of storage space for… No idea what a radar crew would store. Explosive barrels? Not really, but barrels are fun nevertheless. Boxes with documents, spare computer parts, canned dogfood.
Come to think of it, we forgot some entertainment for a bunch of bored soldiers, waiting forever on the nuclear threat. Maybe a billiard would have been nice. Then again, we’re talking about a Soviet army base here, not an American one. Not that I served the red army and have experience, but pictures like THESE
THESE tell me there wasn’t much luxery for those poor bastards. For that reason: place empty vodka bottles, cigarettes, and books. Too bad we didn’t have time to make all those. Sergi did 1 or 2 objects per week, and we had about 11 weeks so do the math. I ordered all the required assets on priority, so pencil drawn hairy women pocket sexbooks were low on the list. Big important stuff first. But the point is, do your homework to make things authentic. Again, Tower22 has nothing to do with Stalin, iron curtains or Russia. Yet we chose the decayed buildings from that era as a design guideline, so googling for Russian factories, North Korean apartments or old-tech technology from that time is part of the job. Just mixing everything without thinking is like an orange 70ies flower wallpaper with a modern Ivar dinertable. Disgusting. Although just mixing up everything is pretty Soviet style actually…

You can imagine its pretty hard to get everyone turned up when showing your ideas with horrible pics like these.
Anyway, to the 3D Batmobile then. Sergi had 1 or 2 objects to make each week, using 3DS Max btw. The program doesn’t matter much though, some use Maya or Blender as well, just as long it can export OBJ files. Usually we would search for a few photo’s to make sure our minds were on the same track. Then a game model was made. Wanna to know polycounts? Depends on the object, how big it is, how important it is, and how many times it will be used. The monster, nitrogen-tanks and big computer terminal take more than 6 to even 10 thousand triangles (when close to the camera), other stuff varies from a few hundred to a few thousand triangles. A modern GPU can easily shit out hundredthousands of triangles. Yet that still doesn’t mean you shouldn’t care. Spending thousands of triangles on small details such as ashtrays, wall sockets or a piece of cloth is overdone. A large, dominant object like the big computer terminal in the Radar Station on the other hand, will be in the spotlights and deserves some extra triangular love.
Quantities also matter of course. GPU’s generally don’t like to get interrupted, so always try to batch and do much stuff with as little calls as possible. Group/order on object, share the same textures if possible, and maybe use modern techniques like instancing in case the same objects appear in real big number. A dense Crysis jungle for example. Hundreds of trees and plants need to be rendered somehow, so it’s wise to use instancing, use the same textures to reduce texture toggling, and to keep the polycount relative low on those. In the case of Tower22, it’s not likely the same objects will appear in dense clusters though. It’s not that a dusty apartment contains twenty computer desks. The limited view distance allows to give some more triangles, though we still need to think about exceptional cases where we can actually see a lot.
LOD
A pretty simple trick to reduce the load is Level-of-Detail (LOD). Ever saw lantarnpoles suddenly (diss)appearing in GTA? Noticed the sinks being thrown at your head getting more detailed in a Halflife2 deathmatch game? It’s the LOD doing its magic. Hopefully you didn’t see it happen in the T22 demo movies, but it happens all the time. The big computerterminal for example has about 12k triangles in its “highest” detail. But after a couple of meters, all those little screws, buttons, and potmeters aren’t needed anymore, as you barely can see them anymore. So why waste thousands of triangles on invisible details?

Guess the 6.126 differences and win fantastic prizes.
Smaller objects like a trashcan or small pieces of debris won’t even have a Low(est) LOD, making them disappear. It’s also possible to switch over to a simple sprite / impostor for distant objects. Not sure about Crysis, but that’s how Farcry for example managed to render its jungle covered islands. Anyway, each object in Tower22 gets a couple of lower detailed meshes, usually by deleting some details by hand, and/or simplifying the mesh with a plugin in your favourite 3D modeling application.
Material sharing
A bigger performance problem is the variety of textures and different “materials”. In Tower22, a material is a collection of shaders (vertex, fragment and sometimes a geometry shader), shader parameters (colors, factors) and textures (diffuseMap, specularMap, normalMap, whateverMap). Before an object is rendered, first its material should be applied. Apply “stinkyLeatherCouch” material, then render the stinkyLeatherCouch 3D model. That way the GPU knows how to draw that thing. Switching to another material (= passing other parameters, toggling active shaders, binding other textures) takes time though. Not much, but yet the performance gets a serious kick if you do it hundreds of times. That’s why the engine sorts everything on material. In case there are 10 stinky leather couches, we only have to apply the corresponding material first and then render the 10 models. Saves a headache, but as mentioned before, Tower22 typically does not use a lot of the same objects at once. That doesn’t mean there are little objects neither, they just vary a lot.
Take a look in your own livingroom. Couch, chair, saloontable, carpet, vase, another vase, plant, cabinet, TV, DVD stash, wall socket, painting,… do I need to continue? Ok, clock, remote control, ugly decorations you didn’t buy yourself, candles, more stupid vases, junk from the kids, a book or two… enough. In 3D world, those are all different models basically. Unless you combine them to one. For example, the cabinet with the TV and DVD stash could be modeled as 1 bigger object, using just one material as well. But what if you want to shoot the TV of the cabinet? If you want to play with destructive physics, you still need to separate the objects… but that doesn’t mean they can’t share the same texture anymore! It’s not uncommon to share the same textures, shader and parameters amongst multiple objects that have (nearly) the same rendering characteristics and are likely to appear together in the same rooms. A bunch of books, kitchen pots and pans, debris blocks, cardboard boxes, plants, trees, or the IKEA Stömpekopf (ok this is the last time) furniture set that comes with a 1 seat, 2 seats, 3 seats couch and saloon table. The warehouse racks in the movie have up to 6 different cardboard boxes, but all using the same material. Thus only 1 material switch instead of 6. Winning.

Quite a lot decals we're used, but many of them using this single texture.
Physics and hitzones
What else can be said about objects in Tower22? Oh yes, maybe that an object is more than just a 3D model and a texture. Some objects require animations, but I'll save that for another time. Furthermore, models -if desired- can be kicked around with the laws of Newton. Physics and (bullet) collision detection requires some additional info though. First, we need a collision “hull”. To ease the computations, one or more simplified meshes are used to define the collision shape of an object. Each hull has its own info too, a physical material and hitzone ID. A car for example could be made of metal, rubber(tires), and glass parts. Each with different sounds and effects when they get hit. A special gastank hitzone could trigger an explosion when being hit by bullets. Very useful for making weak or armored spots on a tank or boss character. But also useful for making interfaces with objects. For example, point & click the cursor at the drawer of a desk to open it.

The yellow lines show the physical hull variants of the screen objects (and map geometry). Usually those are simple box or cylinder shaped primitives.
Object attachments
Asides defining physical properties, it’s also possible to attach other (sub) objects and sprites to a host object. For example, the computer screens on the big computer we’re animated sprites. And the rotating fan was made of two objects; a metal frame, and the rotating blades. The connection between the objects is either a static one, a simple motor that makes the child object shake, move or rotate, or a physical joint. A physical joint is well… based on “real” physics. Or at least simulated physics, such as a ball & socket or hinge joint. Useful for ropes, chains, cowboy saloon doors, tires, corkscrew motions, lamps swinging on the ceiling, ragdolls breaking their necks, et cetera. Making connections is useful for adding optional components to your model, such as a helmet on your ugly head, or putting various weapons in the players hands. And of course it's useful to rip apart sub-objects again once things get blasted.
Apart from regular objects, we can also attach more advanced entities such as (shadow casting) lights (car headlights, helmet lamps, gun lasers, ...), particle generators (smoke exhausts, smoking cigarettes, fire barrels) and invisible fields that can alter gravity, teleport other entities, heal or harm, act like a magnet or triggers boyancy which means the player starts swimming once nearby this object. Absolutely useless, but fun nevertheless.
Editor
In case you are thinking “how the heck are these awesome dudes stuffing all that data in a3DS Max or Lightwave file?!”: we don’t. We save LWO or OBJ files, containing raw mesh data. A bunch of vertices and texcoords is all we need. Like explained for the maps previous times, these files are imported in the T22 “Object Editor”. Then these files are interpreted either as LOD’s or physical hull meshes (in the case of a lightwave file we look at the material name so everything can be imported at once). All additional data and properties such as normals, tangents, names, mass kilograms or attachments with other entities are then defined inside this editor. And once the collection is complete, we can test the object inside… the Radar Station. Remember, we made that map as a playground for testing your new IKEA (oops did it again) Smêgma barstool in various circumstances. Dark rooms, bright rooms, skylight, water buyoancy, throw it down the stairs, let it slide on ice, and so on. Once we’re happy fonzies, the workspace gets exported to our own internal object format, which then we can place wherever we like in our maps. Finally.

In games, the dimensions of a room can look misleading easily. Nowadays we can use 2048x2048 textures, entrophy, many decals, and secondary detail(normal)Maps to enhance the detail, but older games had to improvise with a handful of blurry, stretched textures. But even high quality textures still don’t contain the amount of detail a real surface has, and a wrong scaling of the texture makes the room look smaller or bigger than it should. On top, there is the 3D camera view that doesn’t match a real life eye view. In other words, we need filling for the rooms to clarify the dimensions of a room. A door, washing machine or couch gives a better idea of what a virtual metre is.

Contents gone, floor and left wall textures stretched x2

And of course, it also takes objects to define the purpose of a room. Place some metal bunkbeds and Bob Hope girl posters and you have a Vietnam barrack. Paint it pink and replace the poster with Justin Bieber and you have a girls room. Put down some pee-stained mattresses, needles and pipes, and you have a crackhouse. There is a lot you can do with a floor, 6 walls and a ceiling. So, grab an IKEA catalog, argue with your girlfriend and start filling the rooms. Three Björn chairs here, the green Aslög sink there, a mahogany Helga toilet pot over there. Oh wait… we were doing a (“Soviet”) Radar Station…
The rooms had been defined, though not all of them had a purpose yet. So I took a (imaginary) snapshot of each and made a simple sketch of what & where could be placed. Then each room would result in a list of assets to-do for Sergi, who did most of the objects for the Radar Station. But what the hell would the Russians need in a Radar Station? Well, you can find a lot of answers on websites like www.englishrussia.com. The Russians made a good habit of photographing old forgotten hospitals, schools and rocket silo’s. Too bad we realized this a little bit too late, so most of the contents we’re wild guesses. A military Radar Station, let’s see. Computers, charts, documents. A place to sleep and brush teeth for the soldiers. Facilities to lay bricks. And lot’s of storage space for… No idea what a radar crew would store. Explosive barrels? Not really, but barrels are fun nevertheless. Boxes with documents, spare computer parts, canned dogfood.
Come to think of it, we forgot some entertainment for a bunch of bored soldiers, waiting forever on the nuclear threat. Maybe a billiard would have been nice. Then again, we’re talking about a Soviet army base here, not an American one. Not that I served the red army and have experience, but pictures like THESE
THESE tell me there wasn’t much luxery for those poor bastards. For that reason: place empty vodka bottles, cigarettes, and books. Too bad we didn’t have time to make all those. Sergi did 1 or 2 objects per week, and we had about 11 weeks so do the math. I ordered all the required assets on priority, so pencil drawn hairy women pocket sexbooks were low on the list. Big important stuff first. But the point is, do your homework to make things authentic. Again, Tower22 has nothing to do with Stalin, iron curtains or Russia. Yet we chose the decayed buildings from that era as a design guideline, so googling for Russian factories, North Korean apartments or old-tech technology from that time is part of the job. Just mixing everything without thinking is like an orange 70ies flower wallpaper with a modern Ivar dinertable. Disgusting. Although just mixing up everything is pretty Soviet style actually…

You can imagine its pretty hard to get everyone turned up when showing your ideas with horrible pics like these.
Anyway, to the 3D Batmobile then. Sergi had 1 or 2 objects to make each week, using 3DS Max btw. The program doesn’t matter much though, some use Maya or Blender as well, just as long it can export OBJ files. Usually we would search for a few photo’s to make sure our minds were on the same track. Then a game model was made. Wanna to know polycounts? Depends on the object, how big it is, how important it is, and how many times it will be used. The monster, nitrogen-tanks and big computer terminal take more than 6 to even 10 thousand triangles (when close to the camera), other stuff varies from a few hundred to a few thousand triangles. A modern GPU can easily shit out hundredthousands of triangles. Yet that still doesn’t mean you shouldn’t care. Spending thousands of triangles on small details such as ashtrays, wall sockets or a piece of cloth is overdone. A large, dominant object like the big computer terminal in the Radar Station on the other hand, will be in the spotlights and deserves some extra triangular love.
Quantities also matter of course. GPU’s generally don’t like to get interrupted, so always try to batch and do much stuff with as little calls as possible. Group/order on object, share the same textures if possible, and maybe use modern techniques like instancing in case the same objects appear in real big number. A dense Crysis jungle for example. Hundreds of trees and plants need to be rendered somehow, so it’s wise to use instancing, use the same textures to reduce texture toggling, and to keep the polycount relative low on those. In the case of Tower22, it’s not likely the same objects will appear in dense clusters though. It’s not that a dusty apartment contains twenty computer desks. The limited view distance allows to give some more triangles, though we still need to think about exceptional cases where we can actually see a lot.
LOD
A pretty simple trick to reduce the load is Level-of-Detail (LOD). Ever saw lantarnpoles suddenly (diss)appearing in GTA? Noticed the sinks being thrown at your head getting more detailed in a Halflife2 deathmatch game? It’s the LOD doing its magic. Hopefully you didn’t see it happen in the T22 demo movies, but it happens all the time. The big computerterminal for example has about 12k triangles in its “highest” detail. But after a couple of meters, all those little screws, buttons, and potmeters aren’t needed anymore, as you barely can see them anymore. So why waste thousands of triangles on invisible details?

Guess the 6.126 differences and win fantastic prizes.
Smaller objects like a trashcan or small pieces of debris won’t even have a Low(est) LOD, making them disappear. It’s also possible to switch over to a simple sprite / impostor for distant objects. Not sure about Crysis, but that’s how Farcry for example managed to render its jungle covered islands. Anyway, each object in Tower22 gets a couple of lower detailed meshes, usually by deleting some details by hand, and/or simplifying the mesh with a plugin in your favourite 3D modeling application.
Material sharing
A bigger performance problem is the variety of textures and different “materials”. In Tower22, a material is a collection of shaders (vertex, fragment and sometimes a geometry shader), shader parameters (colors, factors) and textures (diffuseMap, specularMap, normalMap, whateverMap). Before an object is rendered, first its material should be applied. Apply “stinkyLeatherCouch” material, then render the stinkyLeatherCouch 3D model. That way the GPU knows how to draw that thing. Switching to another material (= passing other parameters, toggling active shaders, binding other textures) takes time though. Not much, but yet the performance gets a serious kick if you do it hundreds of times. That’s why the engine sorts everything on material. In case there are 10 stinky leather couches, we only have to apply the corresponding material first and then render the 10 models. Saves a headache, but as mentioned before, Tower22 typically does not use a lot of the same objects at once. That doesn’t mean there are little objects neither, they just vary a lot.
Take a look in your own livingroom. Couch, chair, saloontable, carpet, vase, another vase, plant, cabinet, TV, DVD stash, wall socket, painting,… do I need to continue? Ok, clock, remote control, ugly decorations you didn’t buy yourself, candles, more stupid vases, junk from the kids, a book or two… enough. In 3D world, those are all different models basically. Unless you combine them to one. For example, the cabinet with the TV and DVD stash could be modeled as 1 bigger object, using just one material as well. But what if you want to shoot the TV of the cabinet? If you want to play with destructive physics, you still need to separate the objects… but that doesn’t mean they can’t share the same texture anymore! It’s not uncommon to share the same textures, shader and parameters amongst multiple objects that have (nearly) the same rendering characteristics and are likely to appear together in the same rooms. A bunch of books, kitchen pots and pans, debris blocks, cardboard boxes, plants, trees, or the IKEA Stömpekopf (ok this is the last time) furniture set that comes with a 1 seat, 2 seats, 3 seats couch and saloon table. The warehouse racks in the movie have up to 6 different cardboard boxes, but all using the same material. Thus only 1 material switch instead of 6. Winning.

Quite a lot decals we're used, but many of them using this single texture.
Physics and hitzones
What else can be said about objects in Tower22? Oh yes, maybe that an object is more than just a 3D model and a texture. Some objects require animations, but I'll save that for another time. Furthermore, models -if desired- can be kicked around with the laws of Newton. Physics and (bullet) collision detection requires some additional info though. First, we need a collision “hull”. To ease the computations, one or more simplified meshes are used to define the collision shape of an object. Each hull has its own info too, a physical material and hitzone ID. A car for example could be made of metal, rubber(tires), and glass parts. Each with different sounds and effects when they get hit. A special gastank hitzone could trigger an explosion when being hit by bullets. Very useful for making weak or armored spots on a tank or boss character. But also useful for making interfaces with objects. For example, point & click the cursor at the drawer of a desk to open it.

The yellow lines show the physical hull variants of the screen objects (and map geometry). Usually those are simple box or cylinder shaped primitives.
Object attachments
Asides defining physical properties, it’s also possible to attach other (sub) objects and sprites to a host object. For example, the computer screens on the big computer we’re animated sprites. And the rotating fan was made of two objects; a metal frame, and the rotating blades. The connection between the objects is either a static one, a simple motor that makes the child object shake, move or rotate, or a physical joint. A physical joint is well… based on “real” physics. Or at least simulated physics, such as a ball & socket or hinge joint. Useful for ropes, chains, cowboy saloon doors, tires, corkscrew motions, lamps swinging on the ceiling, ragdolls breaking their necks, et cetera. Making connections is useful for adding optional components to your model, such as a helmet on your ugly head, or putting various weapons in the players hands. And of course it's useful to rip apart sub-objects again once things get blasted.
Apart from regular objects, we can also attach more advanced entities such as (shadow casting) lights (car headlights, helmet lamps, gun lasers, ...), particle generators (smoke exhausts, smoking cigarettes, fire barrels) and invisible fields that can alter gravity, teleport other entities, heal or harm, act like a magnet or triggers boyancy which means the player starts swimming once nearby this object. Absolutely useless, but fun nevertheless.
Editor
In case you are thinking “how the heck are these awesome dudes stuffing all that data in a3DS Max or Lightwave file?!”: we don’t. We save LWO or OBJ files, containing raw mesh data. A bunch of vertices and texcoords is all we need. Like explained for the maps previous times, these files are imported in the T22 “Object Editor”. Then these files are interpreted either as LOD’s or physical hull meshes (in the case of a lightwave file we look at the material name so everything can be imported at once). All additional data and properties such as normals, tangents, names, mass kilograms or attachments with other entities are then defined inside this editor. And once the collection is complete, we can test the object inside… the Radar Station. Remember, we made that map as a playground for testing your new IKEA (oops did it again) Smêgma barstool in various circumstances. Dark rooms, bright rooms, skylight, water buyoancy, throw it down the stairs, let it slide on ice, and so on. Once we’re happy fonzies, the workspace gets exported to our own internal object format, which then we can place wherever we like in our maps. Finally.

Subscribe to:
Posts (Atom)


















