Sunday, July 25, 2010

CSI Profiler

Trying to complete all the items on the list with "things to-do before I die". I meant the list for the movie. But as usual with programming, such lists only grow instead of shrink. Let’s see... "Spawn object X after trigger Y". O, that’s simple. Wait... a few script functions are still missing. Graphical glitch here, graphical glitch there. Found a few new bugs. Don't like the spawn effect, want to morph it from object A to B...

And before you know it you spend another few evenings on what seemed to be a simple point. Well better fix them thoroughly instead of rushing and hacking in features. Making an engine for your game is like collecting stamps, you’ll keep adding items in that book.

Strange enough, I always ignored a particular nasty issue: performance. I don't have to tell you that a game should run fast enough to be playable. I always try to stay above the critical 30-frames-per-second zone. I once learned that our eyes can see about 30 frames per second, so the game framerate should definitely not drop below. I maintained that promise for quite a long time on my laptop. Not the fastest system ever built, but not slow either:
-Toshiba Qosmio 32 bit (Yes, the ugly flaming space station model with hyperdrive)
-4gig RAM, dual core
-and more important, nVidia 9800 M GTS

Blabla. It can run Crysis Warhead just about fast enough most of the time, that's what matters. Crysis is not really the same as my mostly indoor engine (ha, I wish), but it's an indication that beautiful things can be done on this computer, so no excuses. However, I don't care that much about performance yet. For one reason, if I ever finish this game, we'll be playing on a GeForce-27, Octa-Core, organic RAM computer with a stunning 60 inch floppy drive.

Figured this bed needed some clean sheets.

Fine and all, but the average FPS of my game is currently ~21. That's going to be a crappy ride when FRAPS is also running to capture that movie. A few months ago I upgraded the Cg(shader) DLL's from version 1.5 to 2.2. I needed it to realize Cascaded Lights, but as a reward my framerate dropped from ~50 to ~28. I searched like mad, asked the Cg forums, but couldn't find a cause. Well, I kind of ignored it, and in the meanwhile more effects plus more complex scenery were made as well.

Ignoring problems in software is always a bad idea. The longer you wait, the more difficult it gets to fix it. And worse, tracing problems is about the most boring part of programming if you ask me. After all, this is still a hobby, supposed to be fun you know… I’m not coming home after work to torture myself with pointer errors made by bad multi-threading (did that once a few weeks, and it sucked). Anyway, this engine has thousands of routines that influence the performance. Now where to look?

nVidia has several tools to monitor your graphical flow. However, I'm starting to pay the price for using older techniques as well. Delphi 7, and an older version of OpenGL. Not that I try to avoid newer techniques, but I simply don't want to start all over again. A next game/engine may be DirectX & C++, but let's try to finish something. Just for once.

So I made a "profiler" that simply checks the elapsed microseconds to perform subtasks. For example, how long does it take to render the SSAO effect? How many microsecs did it take to play the fart sound? Is the CPU having problems with throwing a wheelchair down the stairs? This allows to find some of the chokepoints between all those many routines.

The Hourglass model is used to measure the framerate. Got to be patient.

It still doesn’t really finds all problems though. It seems that the GPU doesn’t run 100% synchronized with the CPU. That means your program will proceed, thinking that rendering object X is already done, while in reality the video card is still busy. Nevertheless, it brought me to a piece of the HDR pipeline.

Coded years ago, I almost forgot that I was using glReadPixels to fetch the current screen luminance. A required component to do Tone Mapping (= adjusting the eye to the current brightness). This operation isn’t that slow on itself, but it interrupts the rendering process. Imagine driving 120 on the highway and suddenly you’ll have to hit the brakes because a police officer wants to test your alcohol BAC (or the screen luminance for that matter).

It came down to changing a few things so that the luminance would be passed by a tiny texture instead of letting the CPU intervene. Thus fully driven GPU HDR. While dealing with HDR, I decided to face another old problem as well; the pixel colors that came out the Tone Mapper.

The main colors here are white, blue and green... But I used to get bluish all over the place.

After all that scaling, stretching, messing, tossing and mixing, the overall colors would look a little bit washed out. Blue wasn't blue, green wasn't green, etcetera. Nice to make a particular atmosphere (bluish for example), but if I ask for a red sink, then I want a red sink dammit. Colorizing the whole scene is already possible as an post effect anyway.

After tweaking the Tone Mapping formula a little bit, I think the colors are better now, although an overall change like this one always messes up all the fine tuning you did before on the scenery. Really, some tiny little changes in the fog, brightness or colors can make it Hot or Not. Like I said, my list of things-to-do just increased a little bit again.


  1. Very cool, Working on my own little Game + engine as well, though its NO WARE near the level of yours, and its 2d :o

    Look forward to seeing the final/release version :)

  2. Thank you!

    Nothing wrong with 2D engines. Sometimes I'm still in the temptation to make a good old fun fighting game such as Double Dragon / Final Fight. A lot more realistic than trying to make a big 3D game, and lot's of fun. But then again, since I'm this far already, I'd better stick to the project for once. Still a very long way to go though :)

  3. a lot of work to go maybe, but damn it looks good. Make yourself some good tools/exporters and I'm sure you can sell/license it out if you wanted!

    It's not that I don't want to get into 3d, just don't have nearly enough knowledge on it to make a real attempt, my blog has pictures of my first crack at it and it looks way more like Wolfenstien than Crisis! I'm sure I'll get there eventually but i really want to FINISH a decent 2d game before then.

    Good luck

  4. A license is 100 steps ahead. In that case the engine not only has to look good, it has to work 100%, being thoroughly documentated, tested dozens of times, and so on. Can't battle Crytek, iD or the Unreal boys&girls anyway... Although a cheap license more orientated for hobbyists one day isn't such a bad idea maybe...

    Well, let's first just stick to my hobby game :) I had a quick peak on your blog. Don't worry about Wolfenstein graphics, my earlier programs would look that way too. Just keep going, with enough effort the good stuff will come sooner or later. Learn some shaders (also handy for 2D games!), and you'll boost your visuals to a next level already.