Friday, June 29, 2007
The REVOLUTION begins!
The game is set to be released next spring so everyone will have to wait a bit longer before they can play it but there's an announcement trailer floating around along with some concept shots (like here). In-game screenshots will probably be released within the next few weeks, which is very exciting since that will actually show off some of the work I've done related to rendering and general graphics work. The game is looking phenomenal and I think will definitely surprise some people who thought a studio like Firaxis couldn't pull off the next-gen look.
All in all it's very exciting to finally be able to talk about what I'm working on. It seems like so often everything I do is cloaked in secrecy. From one project to the next, I get maybe 6 or 7 months where my friends and family can know what I work on, then on to the next 2 year (on avg) secret development cycle. I suppose in modern times it's a necessity in order to avoid over-exposure (ehem, Duke Nukem Forever anyone?), especially on a game like Civilization that's constantly being tweaked and relies so much on iterative design to ensure the most balanced and enjoyable gameplay.
So even though the past few weeks have kept me very busy at work, I've still had a lot of time to get a lot done at home. I've taken up collecting Star Wars: CCG cards again, which is unfortunately quite an expensive habit (seeing as they haven't been made in years). It was probably my favorite card game growing up (more so than Magic: TG) and even after all these years impresses me with it's strategic complexity and depth.
I'm also really enjoying playing with the adorable little puppy we got about 2 weeks ago. It loves to keep me up at night which is just great... yeah. She's a miniature schnauzer, and incredibly cute, but, ugh, getting a new pup takes a lot of initial effort.
As far as Star Trader work, most of what I've been working on in the past few weeks as been conceptual design work. The combat system is almost completely planned out and just needs to be implemented. I have a document that's something like 20 pages long and goes incredibly in-depth into all the space combat specifics. The last remaining detail actually involves interface design and how a bigger ship's weapons will be fired by the player (for instance, the turret hardpoints on a capital ship as well as any energy beam emitters and torpedo launchers). I'm trying to keep things as simple as possible while still keeping the player involved (via tactile interaction). This means I'm shying away from automated firing but I think this may come back to haunt me.
I've actually gotten quite a bit of code work done as well. In the past few weeks I completely integrated the new very efficient font and gui element (quad) rendering I had prototyped a few months ago back into the main engine codebase. I can now basically render the entire GUI in a single draw pass if I setup my textures intelligently (by texture atlasing for instance).
I also completely revamped my entire GUI system to use xml. It supports a brand new animation system and uses a much better skinning solution which relies upon a few layers of abstraction to reduce complexity. A GUI file defines a layout and a skin. A layout once finished should never change and contains all the windows with the different gui controls that represent any given user interface. The skin file however contains control templates and properties, which define the look and feel of the GUI and can be changed at will. I have a feeling I'll probably be working on all of the layouts and templates and eventually when I get an artist to help out (hopefully sooner than later), he'll be swapping out new art and assets in the property files.
The other thing I finished was adding support for the 360 controller to the game. I recently purchased a wireless Xbox 360 controller and PC wireless adapter for this purpose. It's actually a great controller and works great for playing some Tie-Fighter or Freespace 2. So far I've only implemented controls for the new GUI stuff I had been working on but the plan is eventually allow for complete control of the game through the Xbox controller. Now I'm not of the mind that all game genres perfectly translate to a gamepad controller (first person shooters for instance will NEVER play as good as a mouse/keyboard combo), but I think that Star Trader really is perfectly suited to allow for all levels of control strictly from the gamepad. I actually think it may work even better than the mouse/kb and have a lot of great idea's about how to make the player interactions with the controller completely seamless requiring almost no thought. I'll have more details about this at some point but don't worry, I'm definitely planning on keeping things as simple and straight forward as possible. This situation is certainly something I plan to avoid.
Another thing I had been playing around with is screen-oriented billboard line drawing, which I plan to use these for lasers and exhaust trails (think Homeworld). Although the basic implementation is complete, there are a few issues I still need to work out. Basic laser projectile code is up and running though but I really need to get the ship combat system back up and running. It's been down for a few weeks as I've been revamping my entity management and zone systems. I basically NEED to finish my zone system by next week or progress with the game is going to be completely stalled. I have some idea's about how it should work but right now I'm trying to figure out the best way to implement it with the least room for programmer error (i.e. where's entities aren't accidentally placed in the wrong zone, or objects render incorrectly because of wrong zone ownership).
Alright, that's all I've got for now. Have a good one! Later!
Friday, May 18, 2007
Star Trader Communication System + Skeletal Animation
This screen represents the space station com screen.

And this screen is a mock-up for the player-to-player/player-to-npc com screen.

Because the player will be looking at an actual person (or uh, alien... thing), I needed to implement some kind of character rendering to accommodate this. Those characters would also need to animate so I would need support for skeletal animation, which my engine did not at the time support. Because of this, over the past few weeks I've been slowly building a prototype of the skeletal animation system which I am almost ready to incorporate into the engine. For this I ended up creating a my own custom Collada importer because I was quite unhappy with the DOM and FCollada libraries, and surprisingly it works quite well! The last major thing I need to do is convert form the Z-Up axis format to Y-Up and optimize the vertex lists.
Now the skeletal animation system is not quite done yet but here's a short video of it in action using the Mona Sax model from Max Payne 2 as a test model:
I had to manually rig and animate the model myself (since only the source model was available in the MP2 SDK) so although it may not be too impressive it's something at least (until someone makes me a better test model :-). Whats in place so far is standard skinning through software or GPU. I'm storing the transforms as quaternions and keyframe interpolation works perfectly but I still need to implement multiple animation channel blending (e.g. for running and waving at same time) and transition blends (e.g. smooth transition from run to jump). I'm not quite sure how I want to do that just yet so it may take me another week or so to completely finish it up.
The Mona Sax model was originally made for a fixed function pipeline with no per-pixel lighting so I had to create some normal and specular maps to go along with the phong lighting I'm using. One thing I did that I am very happy with the results of is storing not only the specular color mask in the rgb channels of the specular map but also the specular power in the alpha channel. What this means is that I can render an entire character in one pass with very diverse levels of shininess. Thus the skin be relatively matte but the eyes nice and shiny. Here's an example:

The eyes and lips have a specular power (shininess) of about 200 or so and the skin is varies around 50-150. I plan to eventually add some pseudo subsurface scattering at some point but right now I'm keeping it pretty simple.
Now one of the other pre-requisites for my character system was some sort of support for facial animation. The most straight forward way to do this would have been to use skeletal animation with a bunch of face joints to animate important muscle groups. There are definitely a number of advantages to this. For starters the animation pipe-line is unified and easily modifiable by an artist. Second, skeletal animation is relatively efficient and quick to do in hardware. Also it's relatively easy to blend multiple animations together to achieve a nearly infinite number of facial expressions.
Skeletal animation however is not necessarily the only and best way to do facial animation. Another option is using morph target animation, which is what I ended up going with. With morph target animation, instead of interpolating between different poses of a skeleton which deforms a mesh, we interpolate, or morph, between multiple geometry shapes. The really nice thing about using morph target animation over skeletal animation is that you can directly model the poses you want to deform to without having to worry about proper joint placement and weighting. For facial animation this is especially nice since you can do things like creases and subtle muscular skin deformations that would take a ton of joints to pull off.
An additional point to think about, and bear in mind I don't have any evidence to directly back this up, I suspect that on especially complex (high polygon) models it can be much more efficient to use GPU accelerated blend pose animation over skeletal animation. Now while I concede that software based blend pose animation will never beat out skeletal animation performance wise, doing the calculations on the GPU offers an incredible opportunity for taking advantage of the GPUs parallel nature. Some further points:
First, that vast amount of joints is potentially more than can be rendered in a single pass since only a certain number of constant registers are available on older vertex shader profiles (like vs 2.0). This might require additional passes as the model must be segmented to accommodate multiple HW accelerated renders.
Second, most GPU skinning implementations do not go beyond 4 joint influences per vertex. With a large number of joints in close proximity, the effect of the surrounding joints for a particular musculature would be incredibly weak, making it very difficult to achieve good results, requiring a lot of tweaking.
Third, if you're blending between 4 joint matrices per-vertex (the average influence count), you're talking 4 matrix adds (at 4 instructions each), plus 4 scalar/vector multiplies (for the weights), plus a matrix multiply for each vertex attribute that must be transformed, so for the position, normal, tangent, 3 matrix multiplies (at 4 instructions for each m4x4). Roughly lets say that's 32 instructions total (16 + 4 + 12).
For GPU accelerated morph target blending, you load up all the targets into vertex buffer, then set the active ones to the appropriate vertex streams with only a max number of simultaneous blend targets active at once (and mapped to the proper vertex attributes). So lets say there were a max of five blend targets possible at one time. Using delta morph targets (with a base target acting as the delta source), to accumulate the result of each morph target requires a single scalar add and multiply, which is 1 instruction (madd). So for 5 morph targets, we're using 5 instructions for position, plus 5 instructions for the normal. The tangent can be derived from the morphed normal and the base tangent via orthonormalization (this takes about 4 instructions) and the binormal is derived via a cross product (as would be in the skeletal animation case as well so we won't count that).
That gives us a total of 14 instructions for morphing over skeletal animation's 32 instructions per-vertex. Although using multiple vertex streams is not as efficient as interleaved vertex arrays, you're also not sending huge lists of joint matrices to the vertex shader (just a small list of morph target weights) which about evens it out. So in the end I think it's pretty obvious that for complex models that require a lot of animation detail, GPU accelerated morph target animation can be just as fast if not much faster than using skeletal animation with a high joint count. There's next to no CPU work involved for blend targets, whereas skeletal animation requires a skeletal hierarchy to be maintained (traversed/accumulated, animated, interpolated, keyframes blended etc...).
Now I'm not advocating switching your engine to using pure blend target animation here, I'm just saying that for certain situations (like facial rendering), blend target animation can be a big win. It should be noted however that older games like Quake 3 actually did use blend target animation ("vertex animation") to animate it's characters, but this required a LOT of blend shape keyframes as the linear interpolation results in horrible artifacts if the poses differ too much. For large animations this requires a lot of memory (and is proportional to the vertex count for that model, so it can be REALLY big for larger models). Also you can't reuse an animation between multiple models as you could with skeletal animation so it's a lot of wasted time for artists.
In the end here's the result of a keyframed blend target animation using 3 poses (base, open mouth, closed eyes):
Of course this is nothing compared to the new face demo nvidia just released. Here's the vid if you haven't checked it out yet:
I don't plan to go quite that extreme with my implementation but it's definitely exciting to see whats possible using current generation hardware. Their lighting implementation appears to be the same one used in the Matrix movies (blurred texture space lighting), but the brunt of what makes that look so nice probably has a lot to do with the high resolution textures they used. Such a shame you need Windows Vista and a DX 10 part to see this on your own computer.
Aright I'm out, later.
p.s. As I was writing this I suddenly noticed a little pop-up bubble next to the "save now" button which says "Now Blogger saves your drafts automatically!" - exactly what I was complaining about last time! Damn I love Google.
Saturday, January 27, 2007
Terrain Prototype
As an example, a (relatively) simple question to ask an American is "What battle represented the last major offensive by the Confederacy in the Civil War". The average person probably doesn't know this, but may have at least heard of Gettysburg, probably the most famous Civil War battle. A college graduate with perhaps a Masters in History will have a lot more perspective on the matter. In mere fractions of a second his mind will go through Antietam, Fort Sumter, Bullrun etc... A simple computer related analogy immediately comes to mind; a fragmented harddrive.
Unfortunately there's no Microsoft tool for defragmenting or re-indexing your brain (...yet) but it can definitely help to just step back, take a break and come back with a fresh perspective. I personally use fresh perspective to battle false assumptions and an over-abundance of information on a subject that clouds my ability to make a clear decision. Right now I'm taking a break from my Zone system for instance so I can come back when I'm ready with a clear head ready to tackle the problem again. Unfortunately it's been taking a while for this to happen...
So last weekend I did a hardcore coding binge and fleshed out a terrain prototype for Star Trader. I hadn't made a terrain engine in a long time so I got caught up in a lot of the simple details like grid creation, normals/tangents generation, indices ordering (for triangle stips), and grid resampling (I'm currently using bicubic filtering to overcome 8-bit heightmap artifacts). Texturing terrain was also something new I didn't have much experience in, specifically procedural texturing based on terrain properties. What I ended up doing was implementing a very simple real-time per-pixel "terrain splatting" algorithm, that takes a number of texture layers (like grass, rock, snow) and blends between them based upon a pixels altitude and slope. It looks pretty good but the algorithm I'm using right now is pretty rigid and doesn't allow for much alteration so I have plans to improve it. I also added detail normal mapping which looks great when you get real close to the terrain. Here's a teaser to show what I've accomplished thus far:

Like I said, needs lot of improvement, but I think it was a worthy first attempt. For comparison, here's some offline renders I made a number of years back for the Star Trader planet surfaces before I decided to convert to realtime terrain rendering.
The terrestrial/lush planet surface:

And the desert planet surface:

Comparatively the results aren't that different and I'm pretty sure I'll be able to achieve similar results once I get a sky and some aerial perspective in there.
One of my main goals for the terrain renderer was to allow for very high-polygon throughput. That shot for instance is pumping out over 1 million triangles brute force at about 60 frames per second on a Radeon x800 running at 1280x1024 with 6x MSAA. To achieve this kind of performance it really helped that I used triangle strips to keep the number of vertex indices down to a minimum. Another thing I made sure to do was keep the vertex size as small as possible. Right now it's at minuscule 24 bytes used just for the vertex position and normal. Everything else, like the tangent vectors and texture coordinates are synthesized on the GPU computationally.
I know this may sound counter to traditional thought but the main reasoning behind this is that while graphics cards have greatly improved their ability to compute complex data, bus speeds for transferring data to the GPU haven't really improved at the same rate. By maintaining a "skinny" vertex size I'm able to improve cache coherency as well as maintain instruction parallelism (since less vertex fetches are required). This is a much bigger deal on the next-gen consoles but is still very relevant in the PC world as well.
Now that I'm relatively happy with the performance I plan on moving on to sky rendering and aerial perspective, probably using the technique described by Preetham in "A Practical Analytic Model for Daylight", which is pretty easy to implement with incredible results. After this I want to finish up the per-pixel splatting, then I'll start integrating the prototype code into the main Star Trader codebase.
BTW, if you have any experience with Terragen or World Machine and would like to help with Star Trader, drop me a line. I'll be needing terrain for the variety of planet types which include Terrestrial (earth like), Ice, Water (underwater), Desolate/Barren, Desert, Mountainous, Volcanic, and Forest/Swamp.
Cya!
Tuesday, January 9, 2007
Star Trader Planetary Combat

"A new life awaits you in the off-world colonies, the chance to begin again in a golden land of opportunity and adventure..."
In Star Trader Online, planets are the most valuable resource you can possess. Owning a planet conveys numerous benefits, but an empty planet is next to useless. For a planet to be useful, it must be populated. In order to do this, the player must pick up colonists from the greatly over-populated Earth, where billions of souls await a fresh start amongst the stars. Once a planet the player has claimed is colonized, the player may assign responsibilities to the colonists. These tasks include ore mining, farming, and fuel manufacturing. This is where the real benefit is; it's production capabilities. Colonies may even be taxed. It's because of these benefits that planets are so sought after, and in time the planet can be upgraded for even greater production through buildings. Although travelers may trade with a planet that is claimed by another person (if landing is allowed by the owner), in some situations it's more beneficial for him to take that planet as his own.
After breaking through a planets initial defenses (like planetary shields), a planetary invasion may commence. There are two participants in a planetary invasion, fighters and marines. Before the ground combat may begin, the space marines must land on the surface. The marines start out high above the planetary city to the left of the screen in their drop ships, which slowly descend towards the surface. If there is no star fighter resistance, they drop rapidly, otherwise air combat commences. If the attacker has no fighter escort, the drop ships are sitting ducks and easily destroyed after only a few hits. If a fighter screen is present, however, the attacking and defending fighters battle until either side has no more fighters. If the attacker destroys all the defending fighters, the drop ships drop rapidly and ground combat begins. If the defender destroys all the attacking fighters, they can then begin their attack on the drop ships. If all the drop ships are destroyed, the invasion has been thwarted.
Once all the drop ship reach the ground, their hatches drop down and marines pour forth firing upon the awaiting defending marines. The conditions that dictate a marine units effectiveness include it's rank (regular, veteran, elite), it's tech level (primitive, average, or advanced) and any of the attackers special skills (like the planetary assault skill, which is earned after a number of successful planetary assaults, or a player having the planetary assault proficiency trait). Once either side has no more marines combat is finished and the winner gains, or maintains control of the planet.
A couple of extra details about planets and their design rationale.
Planet growth: Planets populations can slowly grow over time but require food to do so. Some planets can produce food, some can't. Planets that can't produce food will never grow in population until there is an excess of food, which tends to set food prices to a premium. This can create quite a lucrative situation for clever traders. In some cases it may be beneficial for a player that owns such a planet to offer subsidies to other players to encourage them to supply their planet with food, ensuring it's growth and increased production.
Planet sizes and populations: Planets come in small, medium, or large (ex: pluto, earth, jupiter/neptune). The size is used to determine the maximum population a planet may hold in the millions, which are represented as population units. One population unit equals one million people. As an example, a planet with max size of 4 population units may hold at most 4 million people. The lowest measurement of population on a planet is one thousand people, so 4 million people would actually be represented as 4,000 k (four thousand thousand). However, only whole population units can be used for production, as opposed to fractional population units. This means if the population was 3,900 k, only 3 pop units could be allocated.
For a standard ship, a single cargo hold can occupy 100 k colonists (special ships like the pod/seed-ship can hold more). So for a ship with 10 holds, a size 4 planet would take 4 trips to fill at 1 pop unit per trip (4,000,000 / (100,000 * 10)).
And that’s planetary combat (plus a few extra tidbits). Next time, the new star ship combat is explained.
Monday, January 8, 2007
Models and skeletons and formats....
I've started implementing matrix palette skinning on the CPU but I plan to eventually use the GPU for the task. Before then I need a good plan in place for the shaders that will require variable bone indices. I'll probably only support 1, 2, and 4 bone indices, but that would require up to 4 versions of each vertex shader (that's including the 0-bone version). Something else I need to consider soon is adding pre-calculated silhouette edges to the model format since I plan on doing stencil shadows at some point. Sure I could calculate them at load time but it would be just as easy to pre-calculate them and directly load them from file (and much quicker as well).
As most people know, Microsoft OS's start to crap out and get flaky after about 6 months of heavy use. Well I've had the same install of Windows XP on my current machine for nearly 2 1/2 years now and I was well overdue for a clean sweep. It's not usually a painful process but I decided to do a very thorough wipe of my hard-drive using DBAN. This took quite a while but honestly not as long as it took to back up all of my critical data onto disk media and my backup hard-drives. So since most of the process entails waiting I had a lot of time to think about some design aspects for Star Trader. I think I've basically worked out all the details for ship-to-ship combat as well as planetary ground combat. I've got to run but I'll describe it in my next update.
Later!

