The two major issues I've been working on these last few weeks are night time rendering, and the traffic AI.
So this is my 2nd or 3rd pass at creating a good looking & fast night rendering system with only VS1.1 & PS1.1. Major aspects of the night rendering system:
- Dynamic switching of a secondary texture (used as a reflection map during the day, and a modified texture for night, with some of the windows turned 'off') which represents the luminosity of the texture at the texel level.
- A global 2kx2k texture which all lights are rendered to, and is then projected onto the scene (sort of like a simplified shadow map system), it's much faster and is essentially free since the depth information (the transformed Y value of the vertex) is stored in the alpha channel of the 'Light texture', and therefore no Z buffer is needed. I'll describe this system in more detail later.
- Axial billboards for light shafts from the streetlights and vehicle headlights.
The luminance textures + projected lighting + axial billboards should be all I need to create a realistic real-time night scene.
Before I was not using a global projected texture, I was doing all the projected texturing locally on a per-object basis. This required me to re-render parts of the city many times potentially..and was sloooooowwww. This new technique is much more efficient, and only requires rendering of 2 triangles per light source, into a texture. I generate the texture by setting the camera high above the city facing the origin (0,0,0). I then just render the lighting information into the texture, storing the Y (height) value of the light source in the alpha channel. I use this value to adjust the attenuation of the light source later on, in the night pixel shader. It's quite trivial to generate the coordinates for this extra texture...in the vertex shader I use this code to map the texture across the entire city:
//In the night vertex shader
//v0 is transformed position of the vertex
//c39 is the size of the city
//oT2 is the dest coordinate register for the light texture.
//r2 is a temp register
//Calculate light texture tex coords.
add r2.xy, v0.xz, c39.xy
mul oT2.xy, r2.xy, c39.zw
In the pixel shader, I add the light texture to the luminance map (no max instruction is available for PS1.1) to get the final luminance value at that pixel, then I modulate the diffuse texture, and multiply by the fog of war. The night shader is quite simple compared the the calculations that happen per-pixel during the day. I've got to trim down the day shaders soon...the 4x4 PCF shadow mapping is slaughtering the framerates.
//The simple night pixel shader...
def c0, 0.1, 0.1, 0.1, 1.0
def c1, 0.5, 0.5, 0.5, 1.0
tex t0 //Base diffuse map
tex t1 //Fog of war texture
tex t2 //Dynamic light texture
tex t3 //Window luminance texture
//Determine basic ambient value
mul r1, t0, c0
//Determine final luminance value
add r0, t3, t2
//Multiply base map by luminance texture
mul r0, r0, t0
//Add previously calculated ambient value
add r0, r1, r0
//Factor in fog of war, from texture 1
mul r0, r0, t1
//Ensure alpha channel is correct, pull from diffuse texture
mov r0.a, t0.a
//In the game code, set the constant...
//Arbitrary values that describe the size of the city's uniform grid.
#define MAP_SIZE 90
#define TILE_SCALE 15
//Light texture constants
vLightTextureConstants, = D3DXVECTOR4(((float)(MAP_SIZE*TILE_SCALE))/2, ((float)(MAP_SIZE*TILE_SCALE))/2, 1/(((float)(MAP_SIZE*TILE_SCALE))), -(1/((float)(MAP_SIZE*TILE_SCALE))));
D3DDEVICE->SetVertexShaderConstantF(39, vLightTextureConstants, 1);
This system allows for an unlimited number of completely dynamic lights, with no performance hit. It also does not require an extra 2kx2k Z-buffer as depth testing can be disabled when generating the light texture, since the lights are rendered additively into the texture.
It should also be noted that I use an almost identical method for the Fog of War in the game, minus the adjustments based on the Y position of the vertex.
I've done a complete re-write of the traffic AI, and I simultaneously typed up a decent sized paper describing the techniques I used to get the traffic AI working in the game (one reason was to help formulate my ideas). Obviously since the game uses a tile based system there are some shortcuts/assumptions that can be made about the system. Though it all goes out the window when you consider the larger 4-lane roads in the city which break that system. I was planning on posting the document here and in the AI forum, but I'm having second thoughts...maybe once the game is totally finished, and I have time to polish it up.
The input to the system is a cloud of traffic nodes, I re-associate each node with it's appropriate tile in a uniform grid. This step would allow the system to work with any arbitrary group of nodes. Though the relation of the node with it's parent tile is essential in determining the directional information of each 'traffic lane'. I'm not going to start describing the system since it can easily snowball into my re-typing of the entire document...which I already have sitting on my computer.
In it's current state you can tell any traffic vehicle to drive to any point in the city. The vehicle will determine the most efficient path to that point via A* Pathfinding at the tile level. I then do a number of passes on the resulting path in which I determine the correct lanes, direction, etc the vehicle should be in. The vehicles obey all traffic rules, stay on the correct side of the road, avoid pedestrians/other vehicles, stop at streetlights, etc. It ended up being a pretty complicated series of algorithms. This all works over multiplayer, and is robust enough that you can order your gangsters into a vehicle and then tell them where to drive. Obviously for this to be possible the system has to be stable.
Another interesting side effect of the traffic system is the design of the cities. Since the vehicles follow all traffic rules, the design of the city is now the bottleneck. I think I've stumbled onto a Sim-Traffic-Manager game. Since you can create the cities in the editor, anything is possible. Traffic jams end up happening in highly visited areas, where the number of vehicles passing through the road exceeds it's capacity. Things start to get congested on bridges, and major intersections. Much like in real life. This quite an un-expected issue, and it looks like a certain amount of thought has to go into designing the road systems in the game :-) I'm tweaking a lot of things to ease these issues, it's very close to being perfectly robust.
For instance one area that differs from reality is the cycling of the traffic lights. At most intersections you'll find throughout the U.S. directions that are parallel to eachother typically share the same light color. EX: a lane going North will have a green light at the same time a south-bound lane has a green light. This allows the traffic to flow faster (though left hand turns must yield). Because of the somewhat dense traffic patterns in-game having a vehicle turn left typically delays the whole lane, while it waits for an opening to occur. My solution was to just cycle clockwise around the lights giving them each 5 seconds to go + a 3 second window where the light is yellow. So at a 4-way intersection there will be only 1 green light. In reality, there would be two green lights.
I can't think of any Action or RTS games out (multiplayer on top of that) that include a completely persistent traffic network. GTA just spawns the vehicles as the player is near. If you run 50m away from the vehicles and then come back to the same spot...the vehicle will be gone, and a new randomly generated set of traffic will be in the area.
I also couldn't find too many papers online that describe real-time traffic systems for games. Hopefully I'll have time to polish this Traffic AI document up, and it will be helpful/interesting to some people when/if I release it. Maybe a demo would be cool also. Hmmmm.
SHADER INSTANCING OF BUILDINGS IN CITY
I had a great idea about how to increase the performance of the game big time, by using shader instancing. If my calculations are correct:
- Number of DrawPrimitive calls = NumUniqueBuildings*NumShadowMapLevels
- No more slow VB Locks to generate the vertex buffers every time the camera view changes (probably one of the biggest bottlenecks now, other than the fillrate in the shadow pixel shaders).
- Up to ~150+ buildings can be rendered per DrawPrimitive call if I store only the 2D translations of the building, and then the 4 possible rotations as seperate matrices.
- No longer running out of room in static VBs if there are a lot of the same building on a city.
- Should cut vertex buffer memory use to 5% of current usage.
So yea...I think that warrants a day or two of research into the possibility...
MUSIC COMPOSER FOR THE GAME
I noticed a thread in the Music & Sound forum the other day where a composer was looking to score a new game. I sent him an e-mail and he's going to create some tracks for my game. I made the decision based on a ~40 second clip, but I was impressed by his style and I think he'll be able to create some great music for Gang War. We'll see, hopefully I'll get the first track later tonight.
He really has the same feel as the big composers you hear in the movies, I really like the transition in his sample piece...so I'm excited to see what he comes up with. Some dark/gloomy ambient 'thinking music' would be just what I'm looking for, we'll see.
Also I finally found a decent pair of wireless headphones. I returned the crappy Sony ones I had before (to Best Buy), and went across the street to Circuit City. I found these by a company called Sennheiser, they were the best ones I could find at the store. SRS surround enabled, auto tuning, noise canceling, etc. And the kicker is they actually WORK verses the Sony counterpart. To be fair, the Sony ones should have been in the < $70 price category (based on their quality), and these are in the $150+ price range...but I guess you really do get what you pay for.
I've got 2 (yes two) 5.1 surround sound systems in my room right now...these headphones are for night time, when I can't rock out (I had to move home to my parents house in Raleigh for a few months while I finish the game...ugh, I no longer am living the college life...). I have no problems sitting here working 24/7 as long as I can be entertained at the same time (3 computers, a 27" LCD TV, DVD player, 2 surround systems, should do the trick)...this room is wired to say the least. I should post some pics of my new setup...[grin] I really don't ever have to get up, except to go to the gym, and go have a beer from time to time :-)
Anyways, these cost me about $170 but it seems like they're juuust what I need...the only problem I've noticed is that the padded ear pieces are a little too small, and I've got an earring in my cartilage and it starts to hurt after a while...ehhh I guess I'll adapt.
Link to headphone specs
If these don't work out, I'm going to probably buy a bluetooth pair online. These seem really high quality (compared to the Sony ones) and hopefully I won't have to.
'Zee Germans for teh win'.