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.

Friday, June 24, 2011

Send report to Microsoft?


You might expected another "water tutorial". Excuses. Already wrote the text (a month ago actually), but I'd like to have some water pictures with it. I'd like to finish some maps first. You don't show photo's of your grandma when talking about your new girl either.

I got some other pics though. Sergi started producing various models. So while I was stinking in bed, he made an old computer, a lamp, comfortable bed, and a barrel. What kind of game doesn't use barrels?! Doom, Double Dragon, Halflife, Crysis, Final Fight, Donkey Kong. Except for Tetris, every game should have barrels. Especially the red explosive ones. A game without barrels (and crates) is like beef without beef.

To help the modeling guys, they finally got a working editor. This tool can import meshes, and render them in a test environment with the same graphics we use in the real game. As a little bonus, you can toss around objects to test their physics, and test the impact. Impact effects are collision, scrape, roll and spin sounds, particles, splat decals, bullet shots, et cetera.


Deployment my ass
Getting it to work on another computer wasn't so easy. I never had ATI videocards or a 64-bit machine, so the Editor went to unknown, possibly dangerous, territory. The very first issue was a mysterious "Runtime error 217". It seems to happen before the creation of any form, and the application just stops. Grumble!! Checked the DLL's dozen's of time with Dependancy Walker, but finally it turned out we had a "Millennium bug". Sort of. Sascha mentioned something about date function problems. The Delphi(7) function "strToDate('01-01-1900')", called at one of the unit initialisations, was making havoc indeed. What, not a valid date @#$%@#... my great grandmother was born in 1896 or something (married Julius Caesar, lived in a dolmen, and fought in the Eighty Years'War).

Now it works, and surprisingly it didn't produce tons of shader-compiler-errors... at least not on the computers with modern nVidia cards. One of the many programming horrors is to make your app "multi-platform". Yeah sure Java, OpenGL and the likes claim to be multi-platform, but in practice every PC is different. Even when using the same operating system. Conflicting security rights, hardware, Windows service pack version, screen resolution, component XYZ installed or not... It's a mess.

Any programmer should know that your program isn't finished as soon as you say "it's finished!". On your dev-station maybe, but you'll be amazed what kind of (stupid) errors will appear as soon as you deploy your hard-work on a customer computer for the first time. "Array index out of bounds... cannot open file... Hey... that's strange... Normally that doesn't happen.". Yes admit it, you said that more than once!


Congratulations, you have been selected to become a Beta tester!
That's why I try to delay my releases usually. Keep testing, add logbooks, and make use of those "try - catch" statements. If something goes wrong -and it will-, you can locate the cause somewhat better. At least try to give the client the impression you got it all under control hmm?

But yet, if you don't have extensive testing capabilities (thus 30 different computers including one with coffee spilled on it, and another one completely screwed up by porn websites), you got to move on at some point, and hand it over. For one thing, you are not a proper beta-tester, as you know how to use your own system unaware. You won't be hitting buttons 10 times in a row like a monkey, you don't click the cross while you should click "save". But don't underestimate the "stupidity" of your clients when it comes to using your software! They will produce fault-reports like Beethoven can write symphonies. Professional program-crashers as they are!

In other words, you'll need customer feedback to create stable software. Therefore it's wise to hand over your "Beta" version first to a few trusted persons (with a lot of patience!), before throwing it in the public. The problem is, the average user will stick to his/her first impression. If this first impression is "Access violation at address FF01234", they won't trust your software anymore. Even when build 4.0g12 is rock solid. First make sure it works as desired for a few test-persons (make them feel good about theirselves by telling they are specially selected to test your Beta!), then take the next step.

fuel barrels, empty barrels, rusty barrels, stinky barrels, bumped barrels, broken barrels, shiny barrels, important barrels, holy barrels, shitty barrels...

This card doesn't support multi-texturing
The advantage of a fixed hardware setup (like a PLC in a range of machines, or gaming console) is that the platform is equal everywhere. You know what to expect, now deal with it. Once it works perfectly on your development-machine, it should work on any other machine as well. But obviously, Tower22 is aimed for the PC. Maybe it will be ported to the XBox 720 Roundhouse kick, PS Forty-core, or Nintendo W00t some day :) But let's focus on my own dev-station first.

At some older ATI card, the Editor already didn't work. At least not with all the shaders enabled (you can still render with textures only). Well, I could do two things. Make a profile with simplified graphics and shaders that make it run on older machines. Or B:, ignore them. When releasing a game, more audience means more money. So obviously engine-makers try to get CryEngine2 run on an Atari as well (although one has to draw a line somewhere of course). Yet, I chose option B. For now. Why?

Adding support for older platforms takes time, of course. You can't just disable a few tricks and get a result that is "good enough". At the same time, T22 is far from finished. The graphics I produce today, are likely to be (out)dated two years later. So instead of spending energy on the past, I'd better try to focus on the future. Waste too much time on making your engine "backward compatible", and you will stick in the past. The average gaming computer might not be able to run T22 smoothly right now, but don't forget the "average gaming computer" evolves too. I'm pretty sure these systems can run (the current) T22 nicely in two years.

Other than that, I'm just too lazy to work through all those shaders again :) Hey, programming a game all alone in your free time isn't easy!

Playing around with some concrete textures. We'll need a lot of those for the upcoming Radar Station map.

Saturday, June 11, 2011

Poland, Auschwitz

Visited Poland, once again. That means trying to spot some Soviet stuff here and there, having a stroll in the forest hills. And mainly eating and drinking. Feeling like a sugar donut getting stuffed with even more jelly. Sausages are not just sausages here, you can feed a damn Tyrannosaurus Rex with it. Maybe Poland is not the richest country around on this planet, but you won't starve here. And neither run out of alcohol. I'll spare you the alcoholic drama stories this time, but yet I just like to mention I saw an older friendly looking grandpa-man with a baby-buggy... So sweet... wait, that isn't a baby. That’s a pile of beer and wodka bottles.

Since Tower22 uses the communistic atmosphere and architecture as a background (though the story has nothing to do with Stalin or other comrades) I always keep my eyes open for the typical details here. We love old worn buildings, rusty bus-stops, cheap interiors and batteries of tall flats which make you wonder how a person could ever become happy there. Plenty of things are different from my (over)organized, clean, efficient, modern, somewhat obediently Holland. Certainly in combination with those alcohol stories. But honestly, it all isn't THAT dramatic. We didn't spot Pyongyang buildings, KGB agents or jumped 60 years back in time. Many youngsters do have a Samsung Galaxy telephone by now.


What would a Polish landscape without a red-white striped chimney somewhere in the background?

On a train
------------------------------------------------------------
The fantasy tries to see things that aren't there (anymore). And maybe I'm just getting a little bit used to the cracked pavement, concrete blackened by smoke, weird-color-painted walls, rusty metal commercial signs on buildings, cheap products, noisy old cars that bump over the hole-filled streets, funny narrow passages, the “air raid” that goes off almost every day after a thunderstorm to call the firemen out of their beds/bars, and the fact that you can never get what you really want. I needed some veal to cook a meal for my family. Nowhere. Tortillas: huh? One year ago, I searched two(!) CITIES for a photo-camera and GTA San Andreas for the PS2 (present for little brother in law). On 24 fucking December. Just before giving up we finally found a shop with decent camera's, but no GTA:SA in entire Poland. Sunglasses (not the cheap plastic ones): not in this town.

Maybe a ticket to Krakow, one of Poland’s major cities, not that far away from us then... According to the atlas, there is a railroad between Zywiec (the most nearby city from our town Milowka) and Krakow, so we should be there in a 90 minutes... Ok, ok 2.5 hours, as the trains don't go that fast here. Well… forget about it. That train doesn't exist or only drives at 20:00 ó clock or something. Any alternative (bus)routes then? Here in Holland every idiot can plan a journey after 4 clicks on one of the route-planning websites. But my parents in law never heard of internet of course, and the annoyed grumpy ladies at the station ticket-window apparently neither. She searches for an old book and starts telling it's basically impossible to get there unless we take a long detour. And we need some luck as she is not sure whether train X comes or not. Not sure?!

The bus-ladies weren't very helpful either. Krakow?! Of course there is no bus going there! Don't you know?! No, because if we knew, we wouldn't be asking bitch. Do your damn job. Exceptions there, nice customer service doesn’t seem to be a well known word in Eastern Europe. You would expect a shop-owner to be happy if you buy something, giving the fact that it's hard enough to sell enough wares to make a living here. But most of them don't seem to give a crap... Pfff, got to work again, another annoying (spoiled) customer. Bleh.

For Dutch readers, you will respect and love NS & Pro-Rail once you tried to travel here. We complain if the train is 5 minutes late. But at least it drives every (half) hour, and brings you everywhere pretty fast. Other than the Polish trains who creak and ramble as an 200 year old ladie in a rusty wheelchair getting raped. And don’t forget our railways are one of the most occupied ones in the world. In Poland the smaller train-stations still have houses and a lady to operate the switches (hopefully not in a drunk mood). All in all charming, but not very efficient of course.



Oswiecim
------------------------------------------------------------
Nevertheless, we finally managed to find a route to Oswiecim (nearby Krakow). Oswiecim... yes, that is what the Germans would call Auschwitz. With a car it would take less than two hours. With our logical combination of trains and buses, it only took four or five hours. From which most of the time was spend waiting because the train stood still, or waiting for a bus. But hey! We did it. For Auschwitz I was willing to make an exception, as the 1,3 million people who once were deported to this place, didn't have a comfortable ride either.

Oswiecim is a little city, just like any other Polish city here. But behind the station and trees, it hides one of the most gruesome historical happenings; the extermination of 1,1 million men, women and children. Mainly Jews, but also arrested Poles, Russians, and minorities such as disabled people or gypsies, who didn't fit in Hitler’s picture of a perfect world either. The grandfather of my girlfriend had to leave his house and help building the camp. Others ended up dead there.


What kind of architects does it require to design a place to kill...?

Not far from the train station, just behind the city, lies Birkenau with camp Auschwitz. Camp number II out of III actually. 3 kilometers away lies camp 1, with the well known “Arbeit macht frei” sign (“Work makes freedom”, sure). Auschwitz III, Monowitz, was more of a work camp where factories like Krupp Stahl and IG Farben were installed. But we didn’t visit those camps. No internet, no car, or map. We went by foot and just asked directions to “Auschwitz” and ended up at camp 2, the destruction camp. Following a pretty busy asphalt road with plenty of trees, bush and typical Polish houses on both sides. As said, we weren’t prepared (which is a shame hindsight), so I really had no idea what to expect... Except that it might "disappoint" a little. I'll explain.

We all know Auschwitz from the books, scary black-white pictures and maybe movies such as Schindlers List where trains loaded like cattle wagons drive through the gatehouse, with the horrific smoking chimneys of the incinerators in the background. It's dark, cold, noisy, full of angry SS soldiers, and even more terrified people that have no clue what will come... And that scenario is not spiced with Hollywood movie ingredients. The reality might have been even worse.

And here we are. After passing a little hill and curve in the road, we suddenly see the gatehouse, and the long, long fences with the wooden watchtowers. But what we also see are touring busses going on and off, and singing birds, grass and flowers as it's a beautiful sunny day in June. I can't help it, but the normal houses here that have a view on Auschwitz while barbequing in the backyard make an absurd contrast. The remains of Auschwitz are still there, but life obviously continued.

Could you tell world most famous deathcamp is only half a mile behind these houses?

Compare this picture to this, and you understand why it's difficult to get a good image of what really happened. About the railroad; although it seems unseparatable from the gatehouse, this rail wasn’t there until 1944. Prisoners had to walk in. As a “welcome”, an orchest was playing cheery music, while dead bodies were stapled on the other side as a warning sign.


Once through the gate, we tried to separate from the groups of tourists. Although the guides do a good job giving a background story with all of its (gruesome) details, I didn't want to stand between giggling girls, photographing dad's, annoyed kids and people acting being shocked, then yapping on two seconds later. Not here. Luckily it wasn't that crowded, and Auschwitz is a really large place. So finding some rest wasn't difficult. We started on the East side of the entrance, walking through the few wooden barracks that remained. This is where mainly Jewish men had to 'live'. With up to 500 men in wooden stables that were originally stables to house about 52 horses. Hunger and execution weren't the only concerns here. The barely isolated barracks are ovens in the summer, and freezing cold in the harsh Polish winters. And due the bad hygiene all over the camp, insects and diseases were ever present. And I don’t have to tell you where a visit at the doctor would bring you when feeling ill…

It's quite strange to see the first line of barracks are only 50 meters away from freedom. A patch of grass (mined?), a not too deep ditch, a 4 or 5 meter tall fence, and watchtowers every 100 or 200 meters. You may wonder why there weren't massive break-outs, at the "top" days when Auschwitz kept 90.000 prisoners. Well, some people did escape. Especially at the beginning when the fences weren't electrified yet. Prisoners also managed to blew up one of the gas chambers by the way. But probably most the prisoners were too unsure, too afraid, and too weakened for escaping. In total, about 700 prisoners escaped. Only 300 actually survived.


Some tried to escape here, others used the (eletrified) wires to commit suicide.
"Er ging zu den Drähten" (he went to the wires).


It has to be said that the Nazi's tried to hide evidence of the Holocaust at the end of the war. Yes, the bastards themselves must have realized they were doing something terribly wrong, something not to be proud of... The four gas-chambers are completely burned (camp 1 has an intact one, open for public), and most of the barracks are gone as well. Only the stone fundaments and small chimneys (used as central heating systems in each barrack) are still standing. This makes Auschwitz a large, but also an empty place. So we stand here, trying to depict all the misery, chaos and inhumanity. But honestly, the silence, the emptiness, the shiny weather, the green grass, groups of tourists and cars that drive by the fence now and then in the background make it very hard to get the slightest idea of how bad it really was.

Auschwitz is not an attraction, or horror-museum, trying to shock you. It's just what it is. And the people who work here try to preserve this with the donations they get (entrance is free, but you can make a deposit). Of course. It shouldn't be anything else, we're not in Disney World for a day of fun. But yet, this may feel as some sort of disappointment; I just couldn’t really imagine what happened here. Then again, this is a personal feeling, and I guess each person will experience this place differently.


Gas chambers
We went back to the central path with the rail-roads. When the trains stopped here, people would get divided in groups. Jews, non Jews, women and children, men. Imagine this was probably the last time you would see your family... Groups of new-arrived people would be transported to the so called "Sauna" on the East-North side of the camp. But some were less “lucky”. The weaker ones (elder, pregnant, disabled…) were transported for immediate destruction right away. Not being able to work would death here.



Days of traveling without food or water, packed like cattle, would take its toll on quite a lot prisoners already. But if the prisoners would knew their true end-destination, maybe dying here wasn’t so bad after all…

Krema III entrance... Unbelievable that hundred thousands did their last steps here.

The terror-core of the camp, the four gas chambers plus crematoria. Compared to other deathcamps from that time, the chambers in Auschwitz Birkenau were "superior" with a capacity of gassing up to 2.000 people in one time. Prisoners usually didn't know they would get gassed though, as they were told they get a delousing procedure instead. People would undress first, and then get moved into the chambers where Zyklon-B gas was pumped into the rooms. The dead-bodies would then be incinerated, including their documents. Erased from history.

A dirty detail; valuables like golden teeth were removed from the bodies in room H.
From Wikipedia:


Unterscharführer Hackenholt was making great efforts to get the engine running. But it doesn't go. Captain Wirth comes up. I can see he is afraid, because I am present at a disaster. Yes, I see it all and I wait. My stopwatch showed it all, 50 minutes, 70 minutes, and the diesel [engine] did not start. The people wait inside the gas chambers. In vain. They can be heard weeping, "like in the synagogue", says Professor Pfannenstiel, his eyes glued to a window in the wooden door. Furious, Captain Wirth lashes the Ukrainian [prisoner] assisting Hackenholt twelve, thirteen times, in the face. After 2 hours and 49 minutes — the stopwatch recorded it all — the diesel started. Up to that moment, the people shut up in those four crowded chambers were still alive, four times 750 persons, in four times 45 cubic meters. Another 25 minutes elapsed. Many were already dead, that could be seen through the small window, because an electric lamp inside lit up the chamber for a few moments. After 28 minutes, only a few were still alive. Finally, after 32 minutes, all were dead . . . Dentists [then] hammered out gold teeth, bridges, and crowns. In the midst of them stood Captain Wirth. He was in his element, and, showing me a large can full of teeth, he said: "See, for yourself, the weight of that gold! It's only from yesterday, and the day before. You can't imagine what we find every day — dollars, diamonds, gold. You'll see for yourself!"



Sauna

No matter how hard I tried, it's almost impossible to realise that you are looking at the ruins and soil that caught the ashes of hundred thousands of people. The only real witnesses are the tall green trees that still stand there. Maybe the large memorial monument between the two chambers distracts too much. Personally, I think this monument was a good idea, but shouldn't be placed inside the camp. But who am I to judge? A path behind the monument leads to some sewage systems, a forest path where even more dead bodies would be burned in the open air, and the Sauna. If one place managed to give me the shivers, it was here.

The Sauna was used to "receive" new arrived prisoners, turning them into numbers. Again, this building is mostly empty and sober. Auschwitz was made to be cheap, quick and efficient. So don't expect any detail in the buildings. But I could imagine the horrible procedures new prisoners would undergo here. First they had to give up all their personal belongings. Unusable stuff was burned in ovens (operated by other prisoners), other belongings were cleaned in some sort of steam kettles. In the meanwhile, the prisoners would get disinfected in shower rooms. And it wouldn’t be Auschwitz if the shower water was either freezing cold or boiling hot on purpose.

Prisoners would then get their infamous striped costumes, and their names were replaced by a number-tattoo. Both men and women were shaved with blunt tools at great speeds, so injuries and screaming were all part of the introduction. Now imagine you are a mother. Humiliated in every possible way. Being naked, shaved and hurt, in front of the eyes of your own children. Not being able to help them, and being worried sick of the fates or other relatives. It all happens between a bunch of Nazi soldiers (men, but also women), who would treat you as a ragdoll, or cattle. After doing it endless times before, you couldn't count on any compassion or any dignity from their sides anymore.




Why?
We completed our tour by walking through the west side of the camp, where mainly women and children were kept later on. These (stone) barracks were also close to the infamous infirmaries where "doctors" like Josef Mengele would do experiments. "Clean" baby blood for example was used to cure sick SS soldiers. Because the poor hygiene everywhere, insects and diseases didn't discriminate on Jews and prisoners only. Other experiments included removing limbs from twins (usually without anaesthesia), injecting bacteria to see how long it would take before a patient died, and electrocution.

The stone women barracks were slightly “better” than the wooden barracks for men. But could you sleep here, on these three story-bunks, together with hundreds of other faces that come and go?

I didn't really caught “the horror” in Auschwitz itself. But once I was lying in bed that night, this whole experience started rambling. You start figuring how people can do this. Killing is one thing, but why like this? A beast that murdered ten people who ends up in Death-row, still has a somewhat clean cell, and a shower. He can choose his last-meal, and eventually let a Priest visit before he gets executed in a, relative, painless way. His remains will be returned to his relatives, so the family can finish the story.

Not saying the death-penalty is good or wrong, but compared to the Auschwitz methods, at least it still has some respect to a human being. The train-ride to Auschwitz, the separation process, the induction, showering, shaving, tattooing, housing, beds, food and practically everything else here, was done in the most inhumane ways possible. A pig on his way to a slaughter house may suffer less. And we are not talking about criminals or cattle here... Auschwitz holds a room where they tried to reconstruct the background of some of the murdered families with the help of photo's, belongings and diaries. What you see here are smiling children, new born babies, men and women in love, people playing instruments and having fun, families trying to make a normal living.

How on earth can people do this to each other? I'm afraid the inconvenient truth is that any person can be turned into an emotionless machine, by the influence of group solidarity. Just look at Hooligans, or the "Prison Break" experiment. “Them versus us”. Would a single, random German (SS) soldier hurt women and children, without a good reason? Most probably not. Don't forget these men had families too. The "endlösung"(final solution) was the idea of a few very sick minds, not of the individual soldier. But the group dynamics, fear-for-punishment and discipline that rules especially in military structures make it possible that an average man will follow such instructions. Maybe with questioning himself, but without questioning the system. Let him murder once, and he may feel awful. Let him murder every day, and it becomes a routine, without regret and emotion. Let him make jokes and create bond with his fellow soldiers to find (false) reasons to justify his deeds, and he doesn't have to feel bad about himself anymore.

Like Stalin (not uncommon with deathcamps either) said:

The death of one man is a tragedy, the death of millions is a statistic.


If you are ever nearby Krakow, I can certainly recommend to take a visit. Don't expect to see a lot of spectacular things, but this visit is certainly a life lesson.
And if you go, prepare yourself better than we did, to get a better understanding of what the eye sees. There are only few places on this planet that show the contrast between good and evil in such a pure way. But also the thin line between it. Maybe I didn’t manage to get a good image of what really happened, just because it so inhumane. But it did happen. And it's up to us to prevent it from happening again. Asides from preserving these black pages in human history (which sadly starts to fade away already, as the last Auschwitz survivors will be dead within ten years, kids think Holocaust is a Thai herbal, and some people even start questioning if it really happened), Auschwitz should be considered as a warning to all of us. Respect life. Don't let hate form your decisions.

Tuesday, May 24, 2011

Ou est le swimming pool? #1


What a shame, the world didn't end yet. And of course that old fool from Family Radio didn't admit he was wrong either. "What can I say, I'm not a Genius." Yeah, God works in mysterious ways, so maybe you'd shut up next time? Making up stories to scare the hordes of sheep, tssk. For those who spend all of their money before 21 May: HAHAHA. Read Darwin next time.

Sorry, I got carried away. Still a little bit angry about this documentary from Louis Theroux I just on Belgian TV one week ago:
The most hated family in America
Very cute, but fundamental idiots like grandpa Harold or those intolerant assholes from the link above caused dozens of wars, crusades and other stupidity throughout history. Claiming to be God’s messengers, but doing nothing but threatening with Hell, Doom, Sinfloods… Let me say this:
- For the mouth speaks what the heart is full of (Matthew 12) -
And now go jerk off yourselves.



To the happy news then. First, we get some more help on the modeling part. Another bandito from Spain, Sergi.
http://nueveparadas.blogspot.com/
He’ll be making models, maps, and eventually some of the textures that are required for them. Let's hope he can boost the development speed! The other good news; I just started adding some water-effects.
=====================================================================
WATER
=====================================================================

Do you want to go to the plage with me?

H20, the magical substance that is believed to be the source of life. And the source of eye-candy when it comes to visual scenes. Where there is water, there is life. No wonder scientists are curious about what they might find on Europa, one of Jupiters moon's that is covered with a thick shell of ice.

And where there is water, there are decent graphics programmers (ahum). No doubt that water is one of the eye-catchers when it comes to showing your game(engine). Now I'm not a real expert on this matter, as the last time I implemented it was years ago. So I might missed a few new gadgets. But since one of the readers here asked for some water-rendering tips not too long ago, I thought why not writing a little tutorial? For young and old:

1.- Basic water techniques (non-shaders, beginners stuff)
2.- (Basic) shader tricks
3.- Adding reflections and refractions

Users who already did some water and shaders might skip part one (and two). Although some of the tricks are quite universal. I won't mangle too much with waves and fluid dynamics though, as I simply never did that before. Anyway, have fun!



BASICS
-----------------------------------------------------------------------
You could try to implement an aqua volume that reflects and refracts light exactly physically correct. Or you just fake it with some tricks, with a wink to mister Fresnel. As usual, games tend to pick the second approach. And although water in games like Crysis or Halflife2 looks pretty real by now, we can nicely see how the fake tricks evolved from a blue texture to sparkling clear water.

Doom and Duke Nukem simply painted an animated(2 or 3 frames!) texture on the floors. So much for water. But pretty soon things evolved to a transparent water surface quad, with a moving wave texture rolling on it. You can laugh about it, but we have to start somewhere. Plus some hardware can't do much better anyway (The Wii? Just joking). Well, how do we do this?

- Make a quad(or a grid of quads) -> the water surface
- Apply a seamless (mipmapped) texture that "rolls" over the surface.
You can do this by accumulating the UV coordinates (glTexcoord2f( x+time, y+time )
- Disable specular and diffuse lighting before rendering. Don’t apply light, or
an ambient color only.
- Make it half transparent (glColor4f( rgb, transparency)
- Let it blend. Don’t forget to disable these settings after rendering the water btw!
glEnable( GL_BLEND );
glEnable( GL_ALPHA_TEST );
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Done. You can't get it much simpler than that. But at least most players will understand they are dealing with water here. How about some more effects dude? Sure.


Multi Texturing & Caustics
-----------------------------------------------------------------------
Apply the wave texture twice, using multi-texturing. Let the second texture scale and move in a different direction. Eventually use a different (wave) texture.
http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node60.html

Hey… if you can draw a second(or third, or fourth) texture on that water-plane… Then it’s also possible to draw a “caustics” texture onto the walls/floors/ceilings nearby the water-surface right? Sure, you can use the very same wave texture, grayscale it, and render it on top with additive blending modus. Man, you can even render it on the objects / characters that wade through the water.

Underwater fog
-----------------------------------------------------------------------
You can cut your world in 2 halfs: everything below and above the water surface. Everything rendered below the surface can use a much thicker fog value. This effect will make deeper or distant underwater polygons fade out in a basic color.
Use dark blue for an ocean, or brown for a muddy canal. If you want to do it really good, you'll need to use "height-fog". This is not a standard OpenGL feature, and requires a shader though, but a very simple one :)

Or instead of using traditional fog, you can simply decide the fog value based on the height of a vertex(or pixel, if you can use shaders).

fog = min( 1.0f, (watersurface.y - pixel.y) * thicknessFactor );

This would be a crude pixel-shader formula. If you can't use pixel-shaders, you can still do it per vertex. For each vertex you render, use glColor3f( fogRGB );, where fogRGB is computed based on the vertex height. However, this won't work very well if you have relative large polygons though. If you wonder in which order you should render things now:
1.- Stuff underwater with fat fog.
2.- Stuff above water with normal fog
3.- (Transparent) waterplane


Here the Swimming Pool map anno 2011. I only had a few textures to decorate it, and no other contents. But here some first water effects nevertheless. The brownish look is simply (height) fog. The deeper the pixel, the darker. I didn't make caustics yet by the way...


Waves (& LOD)
-----------------------------------------------------------------------
A single flat quad can’t make 3D wave shapes of course. Split your quad up in multiple smaller quads ("subdivide"). When rendering the water surface, you'll calculate the height(Y) coordinate for each vertex based on a wave formula. Now this can be damn tricky! I have zero experience with wave formula's, but I suspect it's a mixture of lot's of sines & factors. So let's keep the code simple, you can go figure out that formula yourself :)

function wave(x,y:single) : single;
begin
// Very simple wave function...
// _elapsedTime just increases with the deltatime every cycle
result := cos(x + _elapsedTime) + sin(y + _elapsedTime*4) * 0.2;
end;
...
For y:=0 to 100 do begin
glBegin( GL_QUAD_STRIP ); // Render horizontal rows of 1x1 meter quads
// Render the first 2 vertices on the left side
vertex1 := vec3(0, wave(0,y+0) , y+0);
vertex2 := vec3(0, wave(0,y+1) , y+1);
glTexcoord2f( 0 * uvScale, (y+0)*uvScale ); glVertex3fv( @vertex1 );
glTexcoord2f( 0 * uvScale, (y+1)*uvScale ); glVertex3fv( @vertex2 );
for x:=0 to 5 do begin
vertex1 := AffineVectorMake(x, wave(x,y+0) ,y+0);
vertex2 := AffineVectorMake(x, wave(x,y+1) ,y+1);
glTexcoord2f( x*uvScale, (y+0)*uvScale ); glVertex3fv(@vertex1 );
glTexcoord2f( x*uvScale, (y+1)*uvScale ); glVertex3fv(@vertex2 );
// Eventually calculate the normals here as well,
end; // for x
glEnd;
end; // for y


LOD (Level of Detail)
Wait a minute. I end up with a few billion vertices if I want to make waves on a 10x10 km water surface! So, decrease the detail for distant quads. If you look over an ocean, do you see any waves at the horizon? Unless you have a monster tsunami, you won't. Simple, because it's way too far to see such details. So neither do we have to render them.

The trick is to make the grid less dense at distances. But how? Again, I never did LOD on heightfields or water-surfaces so I have to apologize. But I might have some ideas though. From the top of my head:

1- Make a 3x3 initial grid. Around the camera(player)
2- Evaluate all (9) quads you just made
3- If 1 or more points from a quad are inside X meters from the camera (just check the distance, simple enough), subdivide the quad:
* don't do any (wave/heightMap) height calculations yet!
* don't think about triangles or OpenGL yet, just manage cells and points

4- Repeat step 2 & 3, but with a smaller radius around the camera.
Do this until the radius comes nearby the camera. The more steps you take, the
more divisions (but also the more work of course).

You don't have a 3D mesh yet, just a bunch of quads/points. Now you have to do 3 or 4 things to make soup out of this:

- Triangulate the shape (=make triangles)
- Calculate uv coordinates (interpolate)
u = ((point.x - fieldOffset.x) / totalFieldWidth) * repeatUcount
or
u = (parentQuad.leftVertex.u + parentQuad.rightVertex.y) / 2
- Calculate height ( y = getHeight(xz) or getWave(xz) )
- Optional, calculate normals (based on your surrounding point coordinates)

Sounds not too difficult, except for the triangulating part. You can keep track in each cell(quad) while dividing. Normally, a cell has 4 points on the corners. When subdividing, a new point will occur in the center, and 4 new cells will be generated. More tricky are cells that have extra points from a divided neighbor cell. See the picture for possible triangulating options.

LOD is a useful technique for large surfaces such as water with waves or heightMaps (terrains). The implementation above is just my quick thought. You might find better ways on the web.



Specular light
-----------------------------------------------------------------------
So far we didn't use any lights except an overall ambient color. Which might be a little bit odd of course. If you shine a flashlight on the bathtub, you won't see a nice circle spot caused by diffuse light. But what you do see is reflected light (=specular light). Well, sort off. Don't shoot me if that is not exactly correct, I slept during physics lessons.

Anyway, as water often comes with a sun or moon in outdoor scenes, you can activate specular light from that specific source. Be careful, you'll need sufficient triangles to do this (or use per-pixel lighting(and thus shaders)). That means you have to sub-divide your water quad. See LOD above. If your triangles are too big, the specular light effect will be chunky as well.

If you are doing real 3D waves, you will need to calculate correct vertex-normals as well, or your specular light suck.

Here you can clearly see the effect of specular light. Per-pixel specular with simplified Fresnel that is though.


Miscellaneous
-----------------------------------------------------------------------
I’ll keep it short. Don’t forget water splashes, underwater bubble sprites or drawing (additive transparent) ripple sprites on top of the surface whenever something falls in the water. There are advanced tricks for this as well, but with some simple sprites and particles you can come quite far already. Don’t underestimate the impact of these effects! You can have a horny Lagune-shader, but the illusion of water will still break in thousand shards when a fat man bombs himself into the water without making a splash.



So, enough for this long post. To be continued. Take two or three weeks to read it, cause I’m going to Poland this Sunday for a little vacation… If that fucking Volcano in Iceland let us go, that is…