Monday, September 12, 2011

Play on Player

Yea, my foot has been “restored”! Gypsum is gone, and now I can walk again (as if raped by a bull). Drink your milk boys & girls!


Movie-knowledge-check. A muscular robot? --> Arnold Schwarzenegger. That dude doing kicks and splits with a French accent; Jean Claude van Damme. The black man with that magical voice; Morgan Freeman of course. The simple guy telling his whole life story on a bus-stop bench; Tom Hanks. The psychopath shouting that Johny is here, Jack Nicholson. The teasing woman spreading her legs, Sharon Stone. "Can you fly bobby?", Kurtwood Smit. Roundhouse 360 kick; Chuck Norris.The little fatman with the big ###, uh, Ron Jeremy.

Just a grasp in the Hollywood Lucky Dip. And by now, the game scene also has an impressive repertoire of virtual actors. The jumping guy that looks like the earlier mentioned Ron; Super Mario. The medieval sadomachosism man with a whip; Simon Belmont. The fast blue hedgehog thing; Sonic. Hatatjapoerasturvat-something; Ruy from Streetfighter. "Your face, your ass, what's the difference?", Duke Nukem. The first polygonal breasted adventurer; Lara Croft. The chain-smoking sneaky grandpa; Solid Snake. That asswhipe stealing the princess every time; Bowser. The fairy-dude with the green hat; Link. Female bounty hunter; Samus Aran. The ninja with the skeleton head... Skorpion wins. The clumsy wannabe pirate; Guybrush Threepwood.

Now that my foot is ok, I can finally sport again. So here's a dressroom bench. It has been a while since I did a 3D object myself!

Not all games have strong characters with a complete biography, but creating a bond between game and player usually starts with putting down a loveable or interesting protagonist. A character being worth to pick up the joypad/keyboard. Cause, who wants to play a game with a stupid character anyway? Action hero's usually require a good look, a set of biceps and a doses of one-liners to make friends with the player. More serious games pass decorate the protagonist with a mysterious background. Lost your family, grew up in an underground sewer, shit like that. Who are you? Play the game and find out.

Yet other games manage to create a character that everybody instantly loves, such as Sackboy from Little Big Planet. Did you ever hear Mario talking by the way? We don’t even know where he lives exactly. Yet Mario is the most famous game-sprite in history. Some characters have that love-factor, others don’t. Now how about Tower22? What’s our plan to grab the player and drag him into the screen?

Here you go, a sketch of the player by Robert. There is still some cloth shopping and cheese-grater work to do here and there, but we’re getting somewhere. Not that Tower22 has much to do with “Communism” or “Russia”, but we chose the Soviet theme as a design-code. Therefore the character needs a typical Eastern Europe / Russian look as well. I’m not a fashion queen, but after a couple of visits in Eastern Europe, I can tell a few details. First, most men have a normal posture. No body building bullshit (who can afford the sport school), and neither fat. Most people work too hard to become fat. Second, a lot of men have short dark or blonde hair, often flat on the head (because they wore a cap or didn’t have time to smear 10 kg gel in it). A little bit the “army” look. Having a “tough-guy” attitude seems to be popular here by the way; lot’s of youth are wearing army trousers, trying to look dangerous and stuff.

Now our guy isn’t a kid or football hooligan anymore, he looks a bit exhausted. Yes, although things are slowly getting better in these regions, people still have sort of an depressed look if you ask me. Maybe it’s Slavic DNA, but I guess being bored, or just tired from all that work is playing part here as well. Read the lips: “Life isn’t easy”. Men like our player don’t have time (and money) to trim theirselves a cool George Cloney beard, buy the latest fashion shoes, and enjoy life. Fuck that, he wakes up to work. Nothing more, nothing less. Now that’s the kind of look we from T22 Next Top Model are looking for.

Robert made a whole set of (3D) "sketches" to pick from. We chose this one, because it has the tired "fuck-off", yet friendly, look. Now Robert is busy making a real 3D version. That version will be slightly different, and with little details such as beard, elder-marks, maybe a little scar, oil smear, sweat... In the meanwhile I have to make a realistic skin shader one day.

Not 100% sure, but most probably, the game will be using the first-person camera perspective. In other words, who knows how the player really looks like. Ok, you will see him in mirrors or in a few cut-scenes maybe, but most of the time you can just as well imagine playing the game with Robocop or Whoopy Goldberg... wait the player has white male arms. Never mind, you get the point. You won't see the player that much, the looks alone is not enough to make you care about the player.

So there goes the "lovely" factor. We need something else to get a love-match. A vast amount of cut-scenes with Reservoir Dogs dialogs maybe? Meeeh... not that I don't like those movies, but our player isn't exactly a joking piece of thug. And even if he was, T22 is a horror game remember. The game is supposed to make you poop your pants, not to piss yourself because it was so hilarious. Many horror-game/movie protagonists are normal, frightened, very human boys and girls. Would Resident Evil 1 still be scary if you run/jetpack through the corridors with Duke kicking ass? No, we want a fragile, sensitive, weak girl/guy. Like the Silent Hill or (older) Resident Evil characters... Though Chris took a steroid cure as well, his arms were 6 times bigger in the last RE game. But hey, RE5 wasn't scary either.

Heather from Silent Hill3, and Chris Redfield (without motor-oil injections) in the GC Remake version. Now Chris looks as if he can defend himself, but the difficult camera positions, stiff controls and scarce ammo still made him vulnerable for a bunch of stupid zombies. And for good reason, otherwise the game wouldn't be scary.

Although anti-hero, it's easier to identify with such characters in horrific settings. The player does the same what you would do: miss your gunshot and run like a girl. Well, probably you would also lock yourself on the toilet, rather than exploring a haunted zombie infested mansion. At least that's what I would do :) Either way, both you and the player are in the same nasty situation, so that makes a bond. And in case of a first-person-view, it's even easier to imagine that your own person is the player. Hence, likely T22 will be using the "Link" method. The what method? Yep, "Link", from Zelda. Or whatever his name is, because the player can always enter his own short name at the start of the game. This character keeps his mouth shut, has little to no emotions, and even a custom name.

In other words, your fantasy has to "complete" the character. Like with books. Some writers describe more details than others, but in the end your fantasy has to picture how the characters and scenery looks like. That's also why book-based-movies can disappoint. Shit, my hero didn't had a beard and brown hair! And that girl was a hot blonde, not a small Viking! Well, some people like to use their fantasy, others prefer to get everything served in ready-to-swallow chunks. But since the horror-genre is for a more select group anyway, I trust on your fantasy.

I'm not sure yet whether the (nameless) T22 player should talk or not. For one thing, there's not much company in that damn building anyway. But if the Boss gives a phone call, it would be silly to reply with silence. Other than that, our man is about 33 years old, normal functioning, and prefer to work with his hands. He's not a genius, neither dumb. An average, working-class (Russian) Joe, or should I say Dimitri or Jaroslaw? You didn't really plan to work in Tower22, but your hands were needed to take care of the building...

More barrels. Sergi is busy doing all kinds of IKEA object(sets). Boxes, barrels, beds, lamps, and so on. We need stuff to decorate that empty building with, right?

So let’s see… We have a non-hero, possibly without a name, that doesn't talk (much)... A prototype, normal human being. The type of guy who drops himself in the sofa with his stinky socks and a beer after work. Good to identify yourself with, but isn't that a bit... 'bland"? How about the mysterious background?!

Well, it would be stupid to spoil everything right here - right now, but let me say the player does have sort of a background. No, your parents weren't murdered. No, you didn't got raised in a spooky orphanage. No, you don't have CIA/KGB chips in your head. No, you didn't do ninja school. No, you don't suffer hallucinations after a mortar hit in Vietnam. No, you are not looking for your family. And no, you can't shit lightning-bolts from your arse either. So what the hell IS he? Play the game and find out :p

Saturday, September 3, 2011

Damn, still looking good!?


Wow! Doom is finally legalized in Germany! National Day! I guess most German gamers had their illegal copy on 5 floppy disks anyway, but those bans on violent games... sigh. You know what I think about games & violence:
Forbidding violent games?

But about Doom. If you tell the new generation of gamers about "id Software", then don't expect ringing alarm bells, twinkling enjoyed eyes, or hours of nostalgic talk. At its best, they might remember something about “Doom III”. In my opinion a very good game, but in the shadows(literally) of more innovative games of that time, such as Halflife2 and Farcry. Doom3 was well, 20 hours of shitting your pants & brainless shooting in darkness. Good enough for me, but not a shocking new formula.


New cars versus Grandpa’s unbreakable steam-tractor
Maybe they also noticed all the fuzz about that game "Duke Nukem Forever", which made the old boys nervous the last 15 years, but turned out to be a piece of . Conclusion of the new generation: we old bastards got stuck in history with Duke and Boom, or whatever that game was called. No doubt it was fun back then, but it’s time to move on. We old bastards on the other hand keep telling that games are shit these days. Like grandpa claiming his old steam-tractor is still superior to those modern machines equipped with electronics that nobody understands.

Nostalgia is a strong thing. Mark my words, you new generation wannabe-gamers (2000..anno now) will be complaining in 10 years as well. Telling everyone Call of Duty: Modern Warfare was way better than all those too-easy-4-hour-crap-virtual-3D-iMotion games we may meet in the future. As usual, everything was better in the good old days. Ask Alexander The Great, and he will confirm.

Nintendo & Wii tries to tickle the Nostalgia, using a different marketing strategy: Good old fun for the whole family (including labrador)... Too bad that they can't(don't want) get rid of their kiddy status. Asides from Nintendo's own series, most of the Wii games are weak excuses to wrap shitty stuff without immersion in a game-package, relying on the overrated Nunchuck. Simple, uncomplicated fun? Maybe, but not enough to hook this old gamer.

OT, Sergi made a sink... Don't know what to say more about sinks, but we need them.

Less serious, more fun
Now, who is right? Is nostalgia blinding us, or do we really have a point when complaining? All right, some nuance first. Doom was made in an era where good-looking quality games were scarce. Hence, it was one of the first "3D" games! Duke was the first game with boobs, humor and cities to explore instead of boring stone corridors. So titles like these would quickly rise above the average, had little to no competition, and got declared holy by the game-popes.

Yet, I dare to say games like Super Mario, Doom(1 / 2) or Duke Nukem still have a better thought-through design than many modern games. Whereas new games are taking themselves (too) serious with photo-realistic graphics and dramatic, cinematic gameplay, old games were more focusing on simple, yet challenging and very addictive mechanics. I finished "Double Dragon (SNES)" with my little brother about 5 million times, while I hardly finish new games these days anymore. At some point, I just lose interest. Even with quality titles such as GTA or Metal Gear Solid. Of course, that also has to do with my age, busy schedule, and being spoiled with too many good games last 18 years already. Chocolate cake doesn’t taste that special anymore after eating it six thousand times.

But when I'm in for a quick game, I usually start Doom or Red Alert, rather than newer titles. How come? Old rusty habits, or are these games really more fun? Both, I think. My major problems with nowadays games:

- It takes a while to get in the mood (complex story, slow build-up, learning all controls, ...). Not good if you don't have many hours of free time.
- But once used to it, these games are often (way) too easy.
- Not worth a second run. Once finished, they dissapear in the (virtual) cabinet.

Point 3 is typical for modern games. Their graphics, advanced scenery, teasers, and immersion usually keep you interested till the end. But the core-elements such as blasting foes or jumping platforms just isn't that much fun. Take GTA for example. Everyone loves the dialogs and exploring the city. But playing it all over again... Racing isn't that much of a challenge, neither are the simple shoot-outs where the computers does 95% of the aiming and cover for you. So what's left, are the dialogs and scenes you have already seen.

A game like Doom on the other hand brings you straight down to the action, 15 seconds after double-clicking \doom.exe. After 50 runs the AI and level-structure isn't really surprising either of course, but you can increase the difficulty to insane heights, and more important, firing the double barreled shotgun at an imp from nearby keeps satisfying, forever. These games are simple, yet brilliant and diverse at the same time.

A simple explanation for their good design might be the available time they got to tweak the levels and weapons. Now lot’s and lot’s of time is spend on making the maps and objects look good in the first place. High poly characters, huge libraries of textures, polishing the lighting, and so on. Making content for older games was simpler, so there was more time to test the maps. Where to put ammo, when to give a health bonus, where to place baddies. And if it sucked, maps or monsters were easy to scrap and replace.

More sinks! Btw, making this model + normalMap + specularMap takes more time than making a low-res sprite of a sink or toilet. Therefore it's harder to replace content, in case it doesn't really fit in the game.
----------------------------------------------------------------
Duke Legacy
I guess this is where it went wrong with the new Duke Nukem Forever… Too much struggle on making the content, too little testing, too much sweat/ego to scrap and redo things… As an old rusty gamer, I was a bit sad about the new Duke not being “Hail to the King baby”. DNF isn’t a bad game, and neither did I expect it to live up the hype. But it didn’t bring back old well-oiled shooter fun, and it certainly did not convince the new gamer generation. A mediocre product, nowhere near the old Duke achievement in 1996.

I already had sort of a bad feeling about it when seeing the few demo movies that were released throughout the years. Duke was struck by an identity crisis. Should he try to be an innovative, fresh game with modern elements such as sniping, driving vehicles and easy-gameplay (plenty of auto-saves, linear levels, lot's of hints, not too much enemies). Or should he stay with his core-business: shooting everything that moves & saving babes up tempo?

I wasn't there at the development, but it seems the creators got stuck somewhere between. Resulting in a game that is neither an oldskool-hardcore shooter, and neither a refreshing new game with superb graphics. It's frustrating difficult at some points, and too easy at the same time. It’s not long, nor short. It's a lot of firepower, but only carrying 2 guns and no mighty-boot at the same time. It's Duke humor but being-a-pussy-getting-killed-by-just-a-few-bullets at the same time. The enemies don't overwhelm you by intelligence, neither with big swarms as they did in the past. The pace was not slow & stealth, neither on steriods. The levels try to look good, but forgot the secrets, humor, freedom and fun that make you want to get the max out of them.

Vehicles or moving stuff doesn't surprise anyone anymore. But back then, this "metro" was a (also technological) highlight!

As said, it's not a bad game. But the new generation that compares it to Crysis or Deus-Ex will be disappointed by the many shortcomings; the game excels in nothing, and Duke’s silly poop-jokes won’t fix that either. Then, we older games get disappointed by the lack of challenge, not killing 100 pigs per minute, and boring level design. Yes, it surprised me that most of the scenes you have seen in 10-year old demo-movies, such as the casino, hoover dam, and cowboy stuff are still in the game. You can't tell me that it took fourteen years to finish those (few) levels... The problem was likely something else: it missed the simple yet addictive and aggressive gameplay that made the 1996 release so brilliant.

I think 3D Realms realized this very well in a pretty early stage. The fun isn't just there when firing a rocket at a bunch of aliens flying with a jetpack. But instead of having Duke-balls of steel and starting over from scratch, they grasped with the ideas & content they made so far, and tried to improve what they got. But probably this was a mission-impossible. Having spend so much blood, sweat and tears in their product, 3D Realms probably didn't want to scrap and disappoint their fans. But at the same time, they might have been too ashamed/unsure to release the game in its current shape. That's where 2K-Games interfered, by putting Gearbox on the Duke. Not to make it a better game, but just to make it sellable, finally. I understand their choice, yet it's a pity to witness the downfall of our old hero.

Roots, bloody roots
I’m just speculating of course, but it seems they took a few fundamental wrong decisions. Once they got behind schedule, being surpassed by better engines and other innovative games, they probably had to adjust their selling points as well. Making a copy of ’96 Duke 3D with improved graphics wouldn’t be enough. At least, not according to publishers that want to sell the game to a wide audience. Times of nonstop brainless shooting, 30 + 2 secret levels, and hard difficulty settings were over. Who to please? The old loyal fans, or the new generation of gamers? Probably they tried to please both, and that’s exactly what made the game fail I think.

In my humble opinion, Duke should have been more like its predecessor. That sounds lazy, but trying to be new and better is near to impossible these days, especially in the shooter genre. Duke wasn't going to steal the hearts of new gamers anyway, there are simply too much players out there now. (Virtual) heroes are just as easily forgotten as they rise these days. So why not going back to the roots, making a decent shooter game. Fast, aggressive humorous action, heavy weapons, whole armies of foes to shoot. A big bunch of fun-levels, not bound to realistic rules or a complex story. And a difficulty setting to separate the men from the boys.

For 2011 standards, that would actually make quite an original game. Hell, I dare to say it would even be fun with 2.5D (but High Quality) sprite graphics. Damn, that would look good. Or least original. Maybe the newer gamers wouldn't be interested... then again, Retro 2D Mario sells again, and I'm pretty sure there are plenty of old grumpy guys that haven't played a good old shooter since Halflife1, in their experience.

Little teaser for Demo2...

----------------------------------------------------------------
Ok professor, how about Tower22?
What design rules would Tower22 follow? Well, neither of them. Horror games are a complete different genre. The target is to give you just a single-ride, with complex & difficult gameplay. But a ride you will never forget because it was so goddamn strange/weird/unique/scary. Like Silent Hill or the older Resident Evil games did. However... I would love to make a 2.5D Duke Nukem, Command & Conquer, or beat 'm up like Double Dragon!

Talking about games, do you have a top10 (old or new, doesn't matter)? In random order:

0- Super Metroid (SNES)
1- Crusader: No Remorse (PC)
2- Doom2 (PC)
3- Halflife (PC)
4- Goldeneye (N64)
5- Zelda (SNES, N64, Majora's mask in particular)
6- Resident Evil Remake (GC)
7- C&C: Red Alert (PC)
8- GTA: San Andreas (PS2)
9- Red Dead Redemption (PS3, hey, that's a new game!)
10- Super Mario (Bros 3, World, 64... and I likes the Wii ones as well)

My top 10... counting from 0 ;)

Sunday, August 28, 2011

Golden particle shower

Let’s discuss some graphical tricks again. You may have seen ice patches in the screenshots from previous posts, but it still looks kinda odd, don’t you think. Is there something wrong with the ice shader, or is it just… What would you think if you if your steaming hot bathtub was half-frozen at the same time? We graphic programmers sometimes forget that effects can’t be tested on realism individually. It’s the whole picture that convinces or not.

In this case, the environment has to look freezing cold. Otherwise the water wouldn’t freeze right? A few tricks you can use for that:

- Use a grayscaled / blueish screen filter. Blue looks cold.
- Use blueish or gray-white fog
- Put snow / ice on all surfaces, not just a few pieces of ice on the water
- Make windy snowdust particles (nearby air-vents and such)
- Let is snow, let it snow, let it snow


Still got to learn those little fuckers not to fall through the ceiling. Maybe the depth-texture (from the player point of view) may help...

Since the summer here was one big fiasco (Global Freezing), I’m already in a Christmas mood. So I decided to start with some snow. But as usual, it required a whole lot more to implement a solid basis to make such effects. What we needed was a particle generator (and an editor to define them).

Now Engine22 already had a few techniques, but not flexible enough for Micheal Jackson moves, and certainly not fast enough to spray massive amounts of particles. And when it comes to particles, density does matter. Usually 5.000 smaller dots make a better volumetric shape than 5.00 somewhat bigger dots. Time for a revision on the old, CPU-based, particle code.


For starters, particles is nothing more than a “cloud” of (small) sprites that move around in a certain way. Simple examples are bloodsprays or flying debris after bullet impacts. But it’s also useful for complex volumetric shapes such as fire, smoke, gas, clouds or a water fountain. The power of particles is the simplicity to draw them, which allows to render large numbers that form a shape together. A single particle looks like shit, but as with ants, killer bees or football hooligans, the group dynamics make it a strong whole.

A particle can be a simple dot, or a textured billboard sprite. The simpler, the faster of course. But you can also apply lighting & shadowMapping on your particles to create cool effects such as lightshafts. Or let it bend / blur the background to create a heat haze for example. Same stuff as usual. More difficult is to render it in insane quantities, and to update particle positions in a realistic way. How smoke moves through the air? Well, I can’t tell you really. But at least I can share some methods to render large numbers of particles.

Smoke test - You'd better not try to model that in real 3D... And a single animated 2D sprite won't do the trick neither anno 2011...

Transform-Feedback (Vertex Streaming)
The simple way of doing particles is creating a big array of particle-structs. Let the CPU loop through the array, update the position with gravity or whatever forces, then render it as a sprite. Not bad, but your CPU will cripple when doing really large numbers (ten thousands). The GPU on the other hand… Wouldn’t it be nice to benefit from the GPU math skills and having all vertex data loaded on the GPU already, rather than passing thousands of coordinates? Think in magnitudes of hundred-thousands of particles, rather than thousands. Well, in theory that is. Having a lot of layers of transparent quads filling the screen can still cause fill-rate issues.

Maybe you know how to pass a VBO with vertex data to the GPU, but how to update the particle positions and store them back in a VBO without needing the CPU? Transform-Feedback is the magic OpenGL word. You don’t need that freaking CPU, neither clumsy textures to store data in pixels.

0. Create a VBO with vertex-data (positions, maybe texcoords/colors, or force vectors in case of particles).

1. Make a Vertex-Shader that updates the vertex data (positions, forces)
2. Store the Vertex-Shader output directly back into a second VBO (= Transform Feedback)
3. Render your particles (or cloth, or skinned character, or anything else) with the second VBO as input. Eventually use a geometry-shader to make billboards out of single vertices.
4. Next cycle, use the second VBO as input in step 1 and store results in the first VBO. Toggle for each cycle.


Dance dammit
So, as for particles, you can create a VBO that contains the maximum amount of particles. In case you can spawn up to 10.000 particles, then create a VBO with 10.000 points. Since geometry shaders can produce sprites out of a single vertex-position, you don’t need to store all 4 corner coordinates in that VBO. Asides positions, you probably need some more info to store per point. For example:

TVBO_Particle = packed record
......Position : TVector4f; // XYZ, W=scale
......Force : TVector4f; // Current velocity / force vector, W=lifetime
......Color : TVector3f; // Color modulator
......LookupCoords : TVector4f; // Pick a sub-texture from a bigger atlas texture
......Randoms : TVector4f; // Some more random numbers to vary data
End;

When creating the VBO, you only have to fill the static data; properties that won’t change such as the color, size lookup coordinates and random numbers. The dynamic properties such as position, lifetime and force will be updated in the Vertex-Shader that updates the VBO each cycle. A very simple approach could be:


OUT.Force.xyz = IN.Force.xyz + Gravity.xyz * cycleDeltaTime;
OUT.Force.a = IN.Force.a - cycleDeltaTime; // Decrease lifetime
OUT.Position.xyz = IN.Position.xyz + Force.xyz; // Update position


Go Recycle
Right, this will make your vertex fall down. At some point, it hits the ground or it should simply vanish after X seconds. Then what? You can’t create new vertices in a VBO… But you can recycle them of course. Notice I used “force.a” as a lifetime value:

If ( ( OUT.Force.a < 0.f ) || (OUT.Position.y < floor.y))
{
......// Particle ran out of time, or hit the ground
......// Respawn it (eventually with a delay)
......OUT.Force.a = maxParticleLifeTime * randomFactor;
......OUT.Force.xyz = initialParticleForce;
......OUT.Position.xyz = initialParticlePosition.xyz;
}

It will start over again next cycle. Probably you want to vary the initial properties a bit to prevent all particles starting at exactly the same point, with the same forces. Use some shader-math, input parameters, or like me, use a lookup texture. Depending on the overall time, you can pick from a texture that tells where to place it, what force to use, what color to use, and so on.

tx.x = elapsedTime / totalGeneratorLifeTime;
OUT.Position.xyz = generatorCenter.xyz + tex2D( dataTexture, tx );

You can also use such textures to morph the color over the time, or to fade them out after a while. Whatever you like Mac. In case of complex movement such as dancing Plutonium molecules, or a tornado, you can eventually encode an entire movement pattern in a 2D or 3D lookup texture. Use your creativity!

I still lack textures and finished shaders to show some cooler effects, but you can also use particles for tornados, rain, lava, flies circling around a turd, slime dripping from leaking pipes, electicity sparks, water splashes, fire, weather effects, plasma generators, exhaust pipes, and so on.


Make it quads please
For simplicity sake and to reduce the VBO size with 75%, we only store 1 vertex struct per particle. That means you can’t just render the damn thing. That’s where geometry shaders (finally) become useful. Given the camera matrix, particle position, and particle size, you can let it make billboards that always face the camera. Here some code:

POINT TRIANGLE_OUT
void main( AttribArray iPos : POSITION,
uniform float3 camPos , // camera position
) {
// Make quad-sprites from points
float4 p1,p2,p3,p4;
float3 particleCenterPos = iPos[0].xyz;
float size = iPos[0].w; // Stored size here

float3 vAt = particleCenterPos.xyz - cameraPos.xyz;
vAt = normalize( vAt );
float3 vRight = cross( float3( 0.0, 1.0, 0.0 ), vAt );
float3 vUp = cross( vAt, vRight );
vRight = normalize( vRight );
vUp = normalize( vUp );

float3 dir1 = (-size * vRight.xyz) + ( +size * vUp.xyz );
float3 dir2 = (+size * vRight.xyz) + ( +size * vUp.xyz );
float3 dir3 = (-size * vRight.xyz) + ( -size * vUp.xyz );
float3 dir4 = (+size * vRight.xyz) + ( -size * vUp.xyz );
p1 = mul( glstate.matrix.mvp, float4(particleCenterPos.xyz + dir1,1 ) );
p2 = mul( glstate.matrix.mvp, float4(particleCenterPos.xyz + dir2,1 ) );
p3 = mul( glstate.matrix.mvp, float4(particleCenterPos.xyz + dir3,1 ) );
p4 = mul( glstate.matrix.mvp, float4(particleCenterPos.xyz + dir4,1 ) );
// Don't forget the texcoords
const float2 tx1 = { 1,0 };
const float2 tx2 = { 0,0 };
const float2 tx3 = { 1,1 };
const float2 tx4 = { 0,1 };

emitVertex( p1 : POSITION, tx1 : TEXCOORD0 );
emitVertex( p2 : POSITION, tx2 : TEXCOORD0 );
emitVertex( p3 : POSITION, tx3 : TEXCOORD0 );
emitVertex( p4 : POSITION, tx4 : TEXCOORD0 );
restartStrip();
}


Transformers!
Nice and all, but how to use transform-feedback? Here some directions. Not sure if this also works on ATI/AMD cards though…

// Specify target for transform feedback
// Toggle between 2 vbo’s
glBindBufferOffsetNV(GL_TRANSFORM_FEEDBACK_BUFFER_NV, 0, particleVBO [0 or 1], 0);
glBeginTransformFeedbackNV( GL_POINTS );
glEnable(GL_RASTERIZER_DISCARD_NV); // disable rasterization ( = no pixel output to textures/screen)
// Apply shaders & draw the VBO
render_ParticleVBO;

glDisable(GL_RASTERIZER_DISCARD_NV); // Return normal modus
glEndTransformFeedbackNV();

As for the VBO creation, here is one way:

glGenBuffersARB( 2, @particleVBO[0] ); // Make 2 buffers
for j:=0 to 1 do begin
glBindBufferARB( GL_ARRAY_BUFFER_ARB, particleVBO [j] ); // Set target
// Pump array of structs into the VBO
glBufferDataARB( GL_ARRAY_BUFFER_ARB, self.props.maxParticles * sizeof(TVBO_Particle), @part[0], GL_STATIC_DRAW_ARB );
// Don’t forget, specify which attributes to store
glTransformFeedbackAttribsNV(5, @attribs[0], GL_INTERLEAVED_ATTRIBS_NV);
end; // for j
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); // unbind


Final notes
VBO’s & Transform feedback allows to render lot’s more particles. That still doesn’t fix all problems though. First of all, the performance will still decrease rapidly when looking into a dense cloud of particles where the quads overlap lot’s of times (meaning each pixel gets overdrawn many times).

Then there is depth-sorting. No matter how many particles you use, if your front particles mask the ones behind, it still doesn’t pay off. When using additive or multiply blending methods, this is not a problem. Though you may risk to get extreme bright/dark results as soon as particles overlap on the screen. When using normal transparency, you still need to sort things out. I believe there are methods to sort on the GPU as well, but I never really looked at them yet. Another way might be using multiple particle generators, sort them on the CPU, then render them all to get a combined result.

Finally, I’m not so sure if this technique is also advisable for small amounts of particles. For example, when shooting at a wall, you may only need a handful of debris particles flying around. Setting up a VBO takes some extra time, so either use the good old CPU approach, or use a fixed set of premade particle generators.

Sunday, August 21, 2011

Funf Bier bitte schnell, danke.


Just in time to shoot this pic!

Excuses for the delay. See, I'm a temporarily crippled programmer now. Allow me to explain.


Two weeks ago we came back from our little vacation in Germany's Capital city: Curry Gewürz, I mean Berlin. No, leave the Bratwurst and Heidi Jokes in the trunk. The image of big bellied, mustached beer drinking champs with lederhosen and a hat+feather is a bit false. At least here in Berlin. Which is a shame by the way, but more about that later. Berlin is a modern, big city with modern citizens. Did we really expect something else then? No of course not. Yet Berlin is quite different when comparing it, for example, to our Dutch cities such as Amsterdam or our beloved Breda.

Right after leaving the Haupt Bahnhoff (Central Station), the first things you'll notice are the colossal structures. Berlin doesn't have a lot of highrise like American cities do, yet it's filled with massive blocks and monuments, placed asides the wide roads(no gigantic traffic jams here!). Many of them looking threatening, imposing. Maybe once fulfilling a dark task, in the DDR or WOII era.


Needless to say, Berlin has quite a history. Varying from the Iron Curtain that separated the liberated Western from the communistic world, to the last days of Hitler during the WOII. Speaking of which, it just happened to be that our hotel was placed right on top of Hitler's Bunker. Yep, the site you'll see in the (great) movie "Der Untergang". Don't expect much of it though. The Russian took quite some effort to remove the bunker. Hitler's "grave" is nothing more than a parking lot between a couple of calm buildings nowadays. Only a sign will remind you what happened here. We found this out while playing Red Alert (with the Stalin cutscenes yes), and wondered why there were so many people outside, standing near that sign. Wait a minute… yep, we were playing war games on the grave of one of world’s most infamous leaders.

Soviet war Monument.


Nothing to see here, move along. Our apartment was just outside the picture in the left upper corner. The other picture is not Hitler's bunker btw, it's our Radar Station testing map. We're starting to get some objects to decorate the place with.

Berlin makes you think about war, and the more recent DDR era that forced its people into the socialist ideology with instruments like the Stasi. The remains of this history are spread throughout the city, giving a grim look over some parts. But of course, there is more than oppression and bloodshed; Berlin didn't stood still last decades. An excellent subway system, Modern office buildings are placed between the old Stasi offices, hip restaurants pretty much everywhere. Unlike some ex-communistic cities I saw in Poland, Berlin looks fresh, clean and structured. Certainly not as if the KGB is still watching there. Although I didn't like Checkpoint Charlie. A few sandbags, American flags, two actors, and... a fucking macDonalds 4 meters further. The ultimate price of a Western society.

You can still see and visit many remains, including the Wall and the evil looking Reichstag building. Yet, just like with Auswitz Birkenau, it's hard to get a good feeling of what really happened. Time erases the past. Then again, did you really think 5 guys would visit Berlin for history lessons? I can dream operation Blitzkrieg and Barbarossa after seeing 6.000 documentaries already. No, what healthy Dutch boys really want is beer. Lots of it.


Meet modern Berlin. As a friend would say, this looks like an IPad3 or something.

And that's where we got stuck a bit. Instead of 130 KG feather-hat, mustached lederhosen guys sitting at a table with roasted pork and beer, we only saw modern, cozy(not) purple LED-light bars. Music volume -4, only a few people, closed pretty early... Aye, that's not what are used to. In Amsterdam, you can get drunk in 60 seconds as soon as you arrive in the center. In Berlin, you need a sniffing-dog specialed in tracing beer, because this large city doesn't really have all stuff concentrated at one central point. The bars are sure out there, but spread or well hidden. And in most cases, not really alive. Although I liked the fact that Berlin people are calm and friendly, the noise of 600 drunken people and the feeling you can get involved in a barfight any time, "engages" here in Holland. In Berlin, I often had the idea that we noisy, farting, burping, belging, laughing idiots were annoying for other people who try to have a calm conversation. But I also had that feeling in France. And in Belgium. And a bit in Prague...

Well, making noise, trying to get drunk, and waking up 06:30 on the floor with a flower bouquete in my underpants (yes, that happened) is maybe just a Dutch thing... And British probably. I'm sure there is a lot more to find in Berlin, just have to dig a little bit deeper. Other than that, we had a good time. And a nice bonus feature is the price. Whether you need beer or a Rumpsteak at a restaurant, Berlin is cheap compared to other Western Europe cities. Same goes for the hotel.



And... Friday actually delivered what we want when it comes to lederhosen, beer and schlager (and Rammstein): Berlin's international Beer-festival! Dozens of beer stalls, tables, music, and würst. Hurray! With as a grand finale a broken foot. Drunk and satisfied, we went home and waited in the Metro station. I felt down somehow, and hurted my foot badly. My friends had to transport 95 kg of drunken flesh through the wide streets of Berlin. Luckily it happened on the very last night, but a few days later it turned out that my metatarsals were broken at 3 or 4 spots. End result: I’m driving in a wheelchair with a laptop between the harvesting and tabletting machines like Stephen Hawking now. Except that Stephen is not so stupid to drink and break his foot probably.

Yeah keep laughin, but not for long anymore. Not everyone likes to wear Lederhosen by the way.

Next time, back on games

Saturday, July 30, 2011

X-Ray

Time for a little vacation in Berlin with my fellow beer-buddies. Wurst, Bier, Heidi und Schlager. What does a men need more? But before we can become “Berliners”, first a little-big story about portal-culling.
*1. What is portal-culling?
*2. Recursive function to get visible sectors
*3. Checking if portals are in your view with a 2D overlap check
*4. View-frustum narrowing
*5. Optimizing with Scissoring
*6. Portals that are partially in front, partially behind the camera
*7. Preventing infinite loops

1. I see what you don't see
The best part about programming is doing the stuff you like, with quick results. Adding the last straws on the other hand... Don't know about you, but in my case it often leads to 90% finished parts. The other 10% is... well, for another day.

Of course, with limited time you can't fine-tune everything till perfection. At the time it's perfect, it's probably also outdated, in this insane fast evolving software world. But sometimes you forget about important missing parts. Now that all Radar Station maps are imported, I noticed a relative low framerate on my laptop (~20 to 24 FPS). Now my laptop isn't the fastest anymore, but suddenly I remembered I didn't finish the portal-culling engine... This particular map has quite a lot of rooms and walls between them, resulting in a lot of overdraw.

For those unfamiliar with (portal)culling, or rendering performance in general, this technique helps preventing stuff from getting rendered for nothing. Unless you are spying or wearing X-Ray goggles, "rendering" the interior of your neighbor’s house is useless, cause you can't see it anyway. Walls and stuff. If we don't cull, invisible parts of the map will be called for nothing, and pixels will be drawn on the screen, and then get overdrawn by something else in front = a waste of time. In an ideal 3D world, each pixel will be drawn only once (asides overlapping pixels with alpha blending enabled).

A deferred-rendering engine already helps reducing the lighting complexity, but when rendering the contents for your deferred pipeline (data textures), shadow/depth Maps or other passes, you still want to exclude rooms you can't see. Or how about rooms you can only see partially? Behind a door or window, there could be st.Paul’s Cathedral. Yet you only see the bits behind the opened doors/windows ("portals").

With portal-culling, you divide your world into rooms, hallways, terrain chunks, or as I would like to call them: “Sectors”. The openings between them (open space, doors, windows, holes, ...) are called "Portals". In a perfect definition of a sector, for each corner(vertex) of a “room”, you can see all other corners of the same room without obstacles between them. But you can cheat a bit of course. Since rendering works best with bigger batches of data, try to prevent ending up with hundreds of tiny sectors. Because you will render sector by sector.


2. Portal Culling recursive function
Before you render your scene, you first have to determine what sectors are visible for the camera. Making such a list isn't that difficult, but it has some tricky (math) catches. Don't worry, my math doesn't go much further than counting potatoes, yet it succeeded. Here a pic, and some pseudo code:


// Make a list of visible sectors
1- Start in the sector your camera(player) is standing. Add to the list
2- FOR EACH portal IN currentSector.portalList
......3- Check if the portal(quad?) is inside/intersecting the camera view-frustum
............4- Add the sector behind the portal to the list, IF not done before.
............ Be aware that the same sector can be visible through multiple portals.
............5- For each sector, manage a list of portals that made it visible. Add ............ this portal to the sectors list.
............6- repeat step 2 for the sector behind the portal

Now when you go rendering your world, just loop through that sector-list. Eventually do it backwards to help with the depth-sorting for alpha-blended/transparent surfaces. The furthest sectors will be rendered first, your current sector last. Oh, and did I mention this "visible sector list" is also handy for other stuff like updating lamps, A.I., and vegetarian cooking? Having a list of visible sectors helps you to exclude unnecessary checks.

Now that's easy, just a recursive function, some looping, little list... done. But wait, as said, there are some catches. Circular references may occur, and how the hell do you know whether a portal is (partially) visible or not? If you are like me, you Googled "triangle sphere collision" and the likes quite some times. But "portal(or quad) versus frustum test" didn't gave me a lot useful results. Mostly you'll need combinations of functions, as collision-test routines are often incomplete. In case your portals are quads, they can be fully inside your camera frustum, intersect it, or completely overlap it (when standing nearby a big portal).

And that's where I didn't finish the code. Just made a cheap check to make sure portals would be visible. But due the margins, invisible sectors still became visible according to the checks. Time for a revision.



3. 3D to 2D
Checking if 3D stuff collides, intersects or overlaps isn't so easy. Narrowing the view-frustum when it travels through a portal neither. Checking if 2D rectangles overlap on the other hand... So why not do the math in 2D? It still has a few flaws, but at least it's an easy way. And a solution that actually works is also worth something right?

So, instead of doing 3D math, we convert the view-frustum and portals to simple 2D rectangles first. Initially, your view covers the entire screen, which means it’s rectangle would have the following coordinates: {-1,-1,+1,+1}. Where -1 is the left or top of the screen, 0,0 the center, and +1 the right or bottom. This conversion still requires a little bit matrix-math though. There are multiple ways to convert a 3D point to 2D, but what I did is using the camera ModelViewProjection (MVP) matrix. Wha? The same matrix you use in vertex shaders to convert 3D points to projection space(ehm... am I saying that right)? You can get this matrix in OpenGL as follow:

// 1. First, make sure your camera is set. For example:
glutLookat( ... ); // Point the camera at a target somewhere
gluPerspective( ratio, fov, near, far );

// 2. Now buy your matrices for only 99 cents
glGetFloatv( GL_MODELVIEW_MATRIX , @modelViewMatrix );
glGetFloatv(GL_PROJECTION_MATRIX , @projectionMatrix );
// Construct the MVP (matrix x matrix)
MVP := matrixMultiply( modelViewMatrix, projectionMatrix );

// 3. Convert a 3D point to 2D with the MVP (matrix * vector)
p2D.xyzw = vectorTransform( MVP, worldPos3D );
p2D.x := p2D.x / p2D.z;
p2D.y := p2D.y / p2D.z;

With this MVP matrix, you can convert 3D points to 2D space, in the range[-1..+1]. If you like, you can multiply further with the screen-resolution to get real screen pixel coordinates, but we don't need that here. Oh, AND your 2D point should also carry a Z. You can use the Z to check whether a point is in front or behind the camera-view frustum.



Testing, testing

PointInsideViewFrustum := (p2D.x >= -1) and (p2D.x <= +1) and
(p2D.y >= -1) and (p2D.y <= +1) and
(p2D.z >= 0);

The -1, +1 are the screen bounds, the Z tells if a point is in front or not. That's how you can check a single point. But, Portals aren't just points right? Portals can be seen as quad (since doors and windows are rectangular). But if you really like, you could also make complex shapes such as... circles, or... kangaroos.

What I do is simplifying the calculation by making simple rectangles out of whatever shape you want to check. First of all, your own view-frustum happens to be a rect; the entire screen. But hold on, your frustum may get narrowed as it passes through portals! (See Scissor chapter below). Next is the portal. Simply loop through all its (vertex) points, convert each one to 2D, and determine the most left/right/top/bottom ones. That makes a rectangle, or 2D “bounding box”.

Sure, rectangles fill more space than, say, a circle. So your portal might become visible even when you can't really look through it yet. But who needs complex portals anyway. Quads, or sets of quads, will do in almost any situation, and keeps the amount of point conversions limited. Asides, it’s wise to have some margin anyway. On top, the usage of rectangles gives an extremely nice bonus-track... but more about that later. Let's show how to do the overlap-check first:

rect1 := viewFrustumRect; // "screen"
rect2 := portalRect;
overlap := (rect1.left < rect2.right) and (rect.right > rect2.left) and
(rect1.bottom < rect2.top) and (rect1.top > rect2.bottom);

Still alive? Bon, because you're almost through the math-part. There is still one nasty bug at this point though, don't raise the flags yet.

* Always expand your portal 2D bounds a little bit to prevent leaky edges.




4. Portal Narrow
We know how to determine whether a portal is visible or not now. But usually a portal is a lot smaller than the sector behind it. Imagine you have a wall with a little Alice-in-Wonderland hole. Although you can fade-out and block the portal after a few meters (use this trick to keep distant sectors hidden), you will still have to render the entire sector behind that hole at some point. And how about the portals in that background sector? Maybe you can't even see them, yet they are in the view-
frustum:


This was one of the reasons why the Radar Station maps went slower and slower. Pretty much all rooms had an opening to another sector somewhere, so at some camera angles, the entire map would be rendered. While you only saw ~35% of it. A waste of precious horsepower.

What we should do, is "narrowing" the view frustum after each portal. That sounds like awful 3D vector math, and, it is. But wait, we worked with 2D rects right? Narrowing the view-frustum is just as easy as using an AND-operator on 2 rects. Well, that still sounds difficult. Look:

narrowFrustum.left := max( previousFrustum.left, portalBounds2D.left );
narrowFrustum.right := min( previousFrustum.right, portalBounds2D.right );
narrowFrustum.bottom := max( previousFrustum.bottom, portalBounds2D.bottom );
narrowFrustum.top := min( previousFrustum.top, portalBounds2D.top );

Just adapt to the portal rect. That's it. In the recursive "PortalCulling" function, narrow the frustum each time it passes through a portal. And don't forget your view might enter the same sector via multiple portals, resulting in different results.



5. Scissor sisters
Narrowing the view prevents portals that are in the view, but occluded by foreground geometry to be evaluated. But it still doesn't fix the huge overdraw when rendering a gigantic sector behind a tiny portal. Call in the Scissor Sisters.

Yet another great feature of 2D rectangles, is... 2D rectangles. In OpenGL, you can tell where to draw by giving up a rectangle, and enabling "scissor testing". Pixels inside the rect will be drawn, others outside will go to the pixel hell.

glScissor( portalBounds2D.left, portalBounds2D.bottom, portalBounds2D.width, portalBounds2D.height );
glEnable( GL_SCISSOR_TEST );

glDisable( GL_SCISSOR_TEST );

This is why I added the portals to a list(per sector) as well in the Portal Culling function. So later on, when looping through that list, just BEFORE rendering the sector, you can setup a scissor. In case you found multiple portals you might activate multiple scissor rects (not sure if this is possible), or just combine the portals to make 1 bigger rect. Don't always hurt yourself with math, enjoy life. With a scissor enabled on the portal, only the visible part of a sector will be drawn, no matter how !#@$ big it was.

However, it does not prevent the render-calls. All triangles / objects inside that sector will be pushed, the scissor just discards pixels that didn't fall inside the rectangle. If you have massive amounts of objects / vertex-data, you may want to split up the sector in smaller chunks. And don't forget about LOD systems. Portal Culling can help a lot, but still doesn't make your game fly of course. Games like Crysis or GTA use lower-poly meshes or even sprite billboards for distant objects.



6. The exceptionals; portals partial behind / in front of the camera
So far, so good. I would almost throw the portal-culling code asides again, leaving it "95% done". If it wasn't there is a not-to-ignore bug still present. How to handle with portals that are (partially) behind the camera? Take this scenario:

Two or only one point of the (quad) portal are in front of the camera, and will produce normal 2D coordinates. The other points are somewhere behind the camera. Math wouldn't be math if there wasn't always an annoying exception on the rule. If all points still had a positive Z value, there is nothing to worry about. The portal rectangle will be partially outside the screen-bounds, but that doesn't give any problems. But in this case, the rear-portal points have a negative Z value. So, when doing the division with Z, the X and Y coordinates will get mirrored too.

This makes a wrong rectangle. Luckily, there is an easy fix. I’m not 100% sure if this is the best way, but I did it anyway. And so far it works:

p2D.x /= p2D.z;
p2D.y /= p2D.z;
if (p2D.z < 0) then begin
if (p2D.x > 0) then p2D.x := -1.0 - p2D.x else // Put it left from the left side of the screen
p2D.x := +1.0 - p2D.x;
if (p2D.y > 0) then p2D.y := -1.0 - p2D.y else // Put it below the bottom of the screen
p2D.y := +1.0 - p2D.y;
end;

Now just make a rect out of all portal points and test it with the view frustum rect as usual, but be prepared for one exception:
if ALL points were negative, the test failed. At least 1 point has to be in the foreground. If you forget this, portals behind you can get visible as well.


7. Loop-back / Circular referencing
A problem with checking visible portals/sectors, especially with the 2D overlap check, is that we may get stuck in infinite loops, or lack info about which portals made a sector visible. Take this scenario:

In this particular case, first the room behind the 3 windows will be checked. This room has a door that leads to a toilet on the right. This toilet has another door that leads back into the big-room we started from. Although the toilet exit door is in front of the background room door, all their 2D rects will overlap (one shortcomings of doing 2D checks). In other words, after our toilet visit in the recursive functions, we get back to the main-room.

This isn't so bad, but we have to be careful not to add the room twice. But neither should we stop as soon as we detect an already-inserted room. Since we entered the room via a different route, it may show other portals that weren't visible before. This gives yet another problems: infinite loops.

To prevent walking circles, you can block portals. Once checked, they can't be checked again. But… this leads to wrong scissor-rects though, or even missing sectors. In complex situations, the same portal might be visible through multiple foreground portals. Each "route" can lead to different results, and will also produce a different scissor-rectangle. Crikey, how to deal with that? Not blocking means infinite loops. Blocking means incomplete data.

So instead of just blocking a sector or portal right away, I look if the sector was already made visible by a(nother) portal with equal or a bigger overlapping rectangle than the current one. Ifso, no need to check. Because it can't produce new results anyway.



Well, enough Portal Culling. The 2D approach has some flaws and still can evaluate portals that aren't really visible for the camera. Yet it's a relative simple (and fast) way to do culling. Just make sure your loop really checks all scenario's, in case parts of the scene are missing.

Sunday, July 17, 2011

Could the real Da Vinci please stand up?

Begging modus engaged. Concept artist required.

Question. Are you (or do you know) an artist, specialized in drawing realistic, but horrific environments? Do you love horror, and do you have at least 5 hours MC-Hammer drawing time a week? Then maybe you like to help us. We need an extra artists that can draw environment. Both realistic looking posters to illustrate the atmosphere, as schematic sketches to support the 3D modelers with making maps. If you are interested, see the contact info below.

Requirements:
- Ability to draw realistic, eerie looking environments. Reference pic:
Control Room
- Available 5 hours or more (quite a lot needs to be drawn, so I need someone with time)
- Eye for detail & architecture
- Affinity with the horror & fantasy theme. Able to make unreal, bizare, dreamish or nightmarish rooms.

What needs to be done:
- Working out the main themes of the game (athmosphere sketches, example environments)
- Building exterior (it's not just an ordinary flat of course)
- Schematic sketches / material sets to support the 3D modellers with making specific locations

What we can offer:
- Hopefully a fun & learnful time!


Before contacting me, please add a link or attachment to the mail with one(or more) drawings in this style. I can't judge the "match" if your art-work has a complete different style! Address:
nieuwlaat dot r AT gmail dot com

cheers

The Office

If one would ask how Demo2 is going, then I would say , “Steadily”… uhm, “slowly”. Pity, but not a complete surprise though. Quite a lot things have been upgraded thoroughly in the code, several more things yet have to be made. Or usually the required features are already in the Engine, but limited. So it has to be revised anyway. Another slowdown is the lack of materials, textures, sounds and 3D props. This time I don’t want to “borrow” media from other games anymore, so we have to make everything ourselves. From a simple carpet texture to a noisy wind ambient loop.

I’m planning to release a movie in the meanwhile though. Not in-game or cinematic sequence of (horror)stuff. Merely a tech-movie. Just showing some fancy shader stuff, that’s all folks.


Nevertheless, a little bit more tempo would be nice. The problem with making a game is that it’s not just big…. It’s f$cking big! And I’m not just talking about all the programming work. Even a simple room can already hold 5 or more different textures(from each requires additional images such as a normal- or specularMap), 10 different props (bench, TV, painting, lamp, …), and several decal/overlay textures (dust, dirt, moss, holes, power sockets, …). Well, just look around in the room, toilet, or stinky office you’re sitting at the moment. And that’s just one room… A game like this needs hundreds, if not thousands.

Of course, after making a couple of environments, your so called library of textures, models, sounds and other shit to put in the game will start growing so that future locations can be filled faster with already-existing assets. But making a start feels like pushing forward a big Diesel Locomotive. Derailed. And because progress is so slow at the start, it’s harder to motivate people. We all prefer quick results, like mcDonalds hamburgers. Painting, modeling, programming or sound engineering is difficult without seeing direct results. Certainly when spending your precious free-time on it.

Off topic. Added some more specular intensity, and it turned out pretty nice for this screenshot that uses only 2 different textures by the way.

Nevertheless, if you want to realize a big project, you shouldn’t be afraid to bleed. Rome wasn’t built in one day either. In my case it requires a lot of effort from the modelers, drawers and anyone else involved. No assets = no game. But it also requires my support, feedback, motivating and vision. Just like in any other company, whether it’s the local tobacco store, a cheese-pudding factory, FC Barcelona, or the Navy Seals, employees need clear goals, a planning, and need to get helped or pushed time to time. This interaction between employees, managers and direction is crucial for any company. If the sales are bad, you can’t just blame the employees because they were too lazy to bake cookies. And neither can you expect to solve all problems simply by replacing a manager. It takes two to dance the Tango.


Now this “managing” task is harder than I thought. Just giving a good idea (“gonna make a cool game, yeah!”), then waiting until the 3D models of double barreled shotguns, awesome monsters and picturesque locations stream in via the mailbox is not going to work. But as a typical worker (don’t talk, just work), I’m not used to socialize a lot with others, demand things, push them, or stipple out rock-solid strategies. I’m used to get some assignments, then just execute them. Managers… ttsk. Talking all day, but never touched a hammer or made their hands dirty. Who needs managers?

In theory, managers are nothing but overhead indeed. If all workers do what they have to do, one Boss-guy should be enough. In practice, worker aren’t always motivated, don’t always know what to do, have internal problems, or are just waiting for feedback / approval before they continue. And certainly; the bigger the company, the harder to get them all facing the same direction.

Now I don’t have to command a whole army of Borgs. The complexity here is the distance and limited, fragmented time. I don’t know my helpers personally. Don’t know their faces, or voices. They spend some hours in their free time, but on varying intervals. This makes it easier to forget things, and a whole lot harder to make robust appointments. The lack of appointments makes it near to impossible to plan anything. As a result, no clear mission. Nobody really knows what to do when, and finally that degrades the motivation. Why work hard if there are no concrete results to expect anywhere soon? It works like a chain; if one link gets stuck, the whole chain starts stuttering.

Ice, ice baby. Asides being David Brent, I spend time doing (cheap) Sub-Surface-Scattering & Fresnel for this ice effect. Not done yet though. Pretty darn difficult, certainly to get it right in relative dark indoor situations.

Enough metaphors. Let’s fix this sink boy. To get more done, I could ask for more people to help (like I just did for the Concept Art). But in the end, I believe smaller, flexible, motivated teams can do more than big chunky ones. So before buying extra horsepower, it’s worth trying to get the maximum out of your current team. You can do this by threatening (you’ll lose your job!), but since this is a charity project, I’d better try it the positive way. Not by kindly asking, but by providing. The A-Team won’t be able to get in action if no one provides ammunition and cigars.

So, it was time to look in the mirror to acknowledge my faults or shortcomings. One of the problems was the amount of info. Not that they don’t know anything about the project. No, there are so much documents, mails and posts scattered around that it’s simply too much. Admit it. Asides from nice books, do you really read tons of paperwork? No. It’s a waste of time making them, because 95% of the people will skip it anyway. I should learn to keep my descriptions short, and less suggestive. Don’t ask “should we do this or that?”. Just tell them what to do. Show them who’s the Boss! And if you need opinions or feedback, put it in simple, compact polls. You don’t have to rule the joint like Stalin, but as a chief, you are expected to chose directions.



Asset manager
As said earlier, another difficulty with games is the tremendous amount of assets to make. Assets? Yes, sounds, textures, models, maps, shaders, concept-art, story dialogs, an animated mouse-cursor… pretty much anything that is relevant for the game. If you want your helpers to do something, they’ll need to know what to make of course. And since there is usually more than just one asset to make, someone needs to prioritize things as well.

To make it more complex, game-assets are often interleaved. A map asset may require other texture assets, going to be made by another person. So to prevent endless waiting, the priorities of all helpers need to align. Person A can’t finish his map if person B has low priority on certain important sub-assets of the same map. This is what would be called “miscommunication” in a normal company. Obviously, the complexity grows when more and more assets & personel arrive on the scene.

Yet another problem with assets is the “unknown”. Do you really know already what EXACT assets to create for, let’s say, a corridor map? Often it’s up to the artist to decide what materials, music or decorations suit best. But to find that out, you’ll have to put the bastard at work first. To do so, he needs to know about this corridor in the first place. In other words, assets can be seen as a tree-structure. From top-level, abstract, global assets such as “making game Tower22”. Going down deeper and deeper till the actual game-content assets such as “ConcreteWall #34 normalMap texture”. First you’ll write out the top-level assets, then you start zooming in, further and further.

The red/green/blue bands is caused by an effect called "Dispersion". Now this code isn't exactly based on realistic wavelength calculations. But it looks cool nevertheless. Maybe overdone for ice, but glass objects can certainly make good use of this. How it's done? Just by calculating 3 different refraction vectors, and sampling 3 times from the background texture. One coordinate for Red, one for Green and another for Blue.

I think most of us hobby game developers made listings in Notepad or Excel. This and that map, blue chair, orange bench, dustbin and a Ming vase model. Go. But then you probably also recognize the quality of these listings: not up-to-date, incomplete, lacking detail, and asides you, no one really looks into them. It works for small assignments, but not for something in the magnitude of a game. So, I did two things:
A:- Ask a person (Brian) to help me managing
B:- Made a database tool to manage the assets

Since Brian is a writer, he probably knows better than me how to “RAR” my huge documents into short but powerful (proper English) texts. He can help me building the assets listing. He does not know about the deep gritty details such as which shaders need to be made to render a 3D turd. But he does now about story telling… and since we have to fine-tune the story and all of its assets (locations, themes, characters) first, before we can go deeper… The splitting process automatically will dig up the story details and paths that yet need a decision.

To manage all of this, I made a simple MS Access database. And a graphical program around it. In a folder-structure (the top-down approach), you can insert assets. An asset here is made of:

- Short name
- Type (texture, character, game info, 3D object, …)
- Description
- Design info (text, additional files, papers and weblinks that explain HOW-TO make it)
- Status (not started, work in progress, almost done, done, suspended, aborted)
- Priority (lowest to highest)
- Assigned person(s)
- Planned / released data (to make appointments)
- Estimated & spend hours (for administrative purposes)

And yet a more powerful feature is the ability to drag & drop assets into another. This allows to make abstract assets, split out in deeper, detailed assets. Example:

Player
----Models
---------High poly body
---------High poly head
---------Low poly body
---------Low poly head
----Textures
---------AlbedoMap body
---------NormalMap body
---------SpecularMap body
---------AlbedoMap head
---------NormalMap head
---------SpecularMap head
----Animations
----Info
---------Background docs
----Sounds
---------Footsteps
---------Voice
---------Dialogs
----Programming
---------Animating
---------Controlling
------------------Navigating
------------------Weapon handling
------------------Ladder climbing

We can already insert the “Player” asset, without knowing which sub-assets we’ll exactly need. Hell, I don’t know what kind of animations or sounds we’ll need. The same asset can also be referred by multiple parent nodes. For example, Demo2 requires the “Ladder climbing code” asset.

Well, this program allows Brian and me to manage the assets of course. But it also allows others to have a look or eventually to update their own progress. Be careful not to let a whole bunch of persons mess around in your database, or it will get mess as every person as a different grouping / naming strategy. Each person can see his (priority) pending tasks (+ explanations), or the progress from others. Hopefully, this helps streamlining everything, and ultimately, helps motivating people. If two persons work slow, the third will be less motivated as well. If two persons work hard, the third has a better chance to get sucked into this “fanatic workflow”.

Rick
CEO of… uh, crap, still no name yet

Sunday, July 3, 2011

Forever young

Easy, the second part of the water tutorial will come. Got to finish some more rooms first... Last week I spend most programming-time on adding motion blur on rotating objects (see bottom), improving Cascaded ShadowMaps for long-range lights such as the sun, and a fancy loading-screen system! We programmers all know debugging means changing 2 letters, recompile, and run the program again for the 1235th time. When having long loading times (10 seconds or more), this can get quite annoying. So here a little tip to make all the waiting a little bit more bearable; show your concept art!

Concept artists do their best making teasing images or good reference work. By now, we got a whole truckload of old-flat photographs and the likes. So why not showing a few random pictures while waiting? Just to bring you in the mood, and to make sure all that hard work won't be forgotten.

See? There are still parts missing. And the brown chunks on the water should be ice...

Boy, all that talk about games. How old are you? I’m 27, and could become a grandpa within 13 years in theory already (didn’t count the 6 year old moms). Well she’d better not, but what I’m trying to say is: aren’t we a little bit too old for playing games? Or like me, spending thousands of hours trying to make one? Uhm… although I’m not playing that often anymore, and although the impact and charm isn’t the same as ten years ago, I still enjoy them. Mom cooking, little daughter drawing “things”, daddy shooting cowboys in Rockstar’s Red Dead Redemption. Which is an absolute masterpiece by the way, way deeper than the GTA series.

Yet, when someone asks about my hobbies, game-programming is often replaced with “doing creative stuff” (or sporting, yeah right). When colleagues at work ask “how did you learn all that stuff huh?”, I answer with “School and a little bit fooling around at home”. While the fact is that most of the experience comes from the endless attempt to make games. It’s just not cool to admit you’re doing kiddy things against a bunch of non-digital workers smeared in oil, even not when having a cigarette in the corner of your mouth.

Needless to say, openly telling your exciting Super Mario adventures and your boy dreams of being a muscular Doom Space Marine is not exactly what you tell the girls either. Grown men drink beer, demolish things, drive motorcycles and shit without toilet paper. Ok, the modern metro-man shaves legs, knows everything about expensive perfume and hits the club every Tuesday. But neither of them plays games. Not done. Just like you shouldn’t play with Lego, read superhero comics, draw bad monsters, or enjoy Commando with Arnold Schwarzenegger at my age.

Talking about action movies. This is the Radar-Station (work in progress), our test playground map for the object Editor I mentioned a couple of times last posts.

Of course, many people do have a secret Marklin modeltrain platform on their attic (where the wife doesn’t come). Oil platform workers play Pokémon on the pink NDS of their girlfriend. And just look how excited all the boys are when the word “Lego” falls. Tssssk, bet what happens if you throw a box of Lego between a bunch of full-grown drunk men on a party. Happy like never before. Being full-grown sucks, but we have suppress our feelings anyway. Otherwise the guys at the office will laugh, and your wife is too ashamed to walk in public with you.

Basically, “growing-up” means throwing your fantasy overboard. Because that’s what really happens. And whether you like it or not, sooner or later you start noticing Rambo III isn’t as funny as it used to be. Superheroes are kind of lame, Duke Nukem isn’t real, and instead of imagining your own action-packed stories, you lazily let the TV do all the work. Or maybe you read a book. Just as long as you don’t have to surrender yourself to your own fantasies, because that’s childish.

Some give a brave struggle, others fall quickly. But we all get old sooner or later. And for what? Give yourself a pat on the back. Because you didn’t only grow up(7 years after your girl, as she claims), you also got officially boring due the lack of fantasy an impulsive thinking. Perhaps resulting in the so called midlife-crisis, ten years later, as you finally realize you did nothing but working, watching TV and adapting yourself to age, wife, kids, environment, and the “norms”. Shit, you could have played Counterstrike for at least five more years, or maybe still even drink beer and laugh about farts every Saturday with fellow 40 year old childish friends! Now you suddenly got to compensate with parachute jumps and climbing a mountain.



Now seriously. Isn’t it a pity we hide or even discard our hobbies, loves and fantasies just to prove our maturity? When looking at my little daughter, it reminds me how special little things once were. Every year I hope to catch that nostalgic feeling when setting up the Christmas tree, but after two days I’m not even looking anymore. But as a kid, I was fascinated just by the red and green colors of those tree lamps. The whole atmosphere could become exciting, just by adding some colors, sounds, a specific smell or event. Kids are still unbiased, open for everything. Life is a big adventure, and when they play they live their fantasies, unashamed, pure. Doesn’t that make you jealous sometimes? At least they are still happy with everything they see and do.

I’m Goddamn happy with my game-programming hobby. Childish or not. As you may guess, my grownup girlfriend doesn’t really understand either why I’m wasting so much time behind the computer. Programming a game… ok… But for me, it feels like the last station between childhood and maturity. Already lost a lot of luggage when it comes to absurd humor, farts, partying and building fantasy cities on the attic. So please! Let me be young and dream away in my fantasy for a little longer! And if you think that’s childish, maybe. But at least I’m happy with it! Touché.

If fantasies about old barracks in spooky environments are already childish, then how the hell could a man think of Mushroom Kingdom, Harry Potter, Star Wars, or Family Guy? Exactly. Screw them, just use your fantasy and be proud of it, no matter what they say!


Motion blur on rotating objects?
---------------------------------------------------------------
Not a very high quality blur, but at least it’s cheap and easy. For a good description, check this link:
GPU Gems 3: Motion blur as a post effect
In turbo-short, perform this post-effect on the whole screen as follow;
- Calculate the previous (screen)position of each pixel by using the preview modelview matrix
- Calculate the 2D motion vector by subtracting the previous position from the current pixel position
- Create a blur-streak, using the motion vector to offset the texcoords.

This creates a blur while (quickly) rotating the camera. However, it does not make fast moving/rotating objects blur by itself. Got to give a helping hand. In the earlier passes, I also store the motion vector in one of those buffers. Just like you can store depth in a texture, you can also store a 2D or 3D velocity. Calculating this velocity is easy. For each object, store the previous matrix. You know, the position / rotation matrix you would set with glLoadMatrix before rendering your object. In the (vertex)shader, use the current and previous matrix to calculate 2 world positions. Subtract them to get the velocity.

Although somewhat more work, you can do the same trick for animated characters if you pass all previous bone matrices as well. This allows to blur fast moving limbs, such as E.Honda's Hundred-Hand-Slap. Now back to the final step. Just sample the motion vector and add it to the camera motion. Done. Burp.


We still have to produce more textures, and then fill the rooms with objects. But it is a start.