Saturday, October 20, 2018

New Procedural City Features

I've been working on several different 3DWorld sub-tasks over the past few weeks. Some of them are directly related to my procedural city, and others aren't really related. However, I can still put a city in the background when presenting these changes. Here are some short descriptions and screenshots showing the improvements I've made.


I finally got around to adding benches to some of the empty spaces between roads and buildings. I copied the bench model I manually created for the office building scene rather than downloading a free online model this time. This is basically just a big table of numbers representing the coordinates of eleven cubes and one extruded polygon for the back of the bench. I haven't implemented support for reading my 3D text scene file format in the city framework yet, so I hard-coded the coordinates into the source code. It works well enough for this simple object.

The max number of benches per plot is specified in the config file. The placement algorithm selects this many random locations as candidates for bench positions. If the location is valid (nothing else is placed there), a bench is added in the orientation that faces the nearest road. This placement system has been generalized to allow the addition of any future type of 3D model. A simple bounding cube collision model is used.

Here is a night time screenshot showing a bench placed under the streetlight by the side of the road. Additional benches can be seen in the background. Benches, along with almost every other city object, both cast and receive shadows. I particularly like the warm lighting achieved by the postprocessing bloom effect in this image. The yellow car appears particularly bright.

A city bench placed by the side of the road under a streetlight. Other benches can be seen in the background.


I've had "add trucks and other larger car models" on my city TODO list for a while. The main reason I haven't added them until now is that it's difficult to find free truck models online. Car models are plentiful. I was able to find all ten car models I had up to this point in less time than it took for me to find a single truck model. I even signed up for an account on a 3D model website, just to find that I couldn't actually download any models with the free account! I found this one low-poly truck model and decided that it was good enough to use. Here is is:

A new box truck has been added to the set of randomly selected car 3D models. It's self driving (no human driver).

I had to add support for variable sized vehicles to make this work. Without that change, the truck was the same size as a car and looked very strange. I was expecting this to take a lot of effort and require a week to get right. It seems like everything related to cars is like that. Remember how long it took me to solve the traffic gridlock problem? I was surprised to find that all I had to do was multiply some numbers by a scaling value and it ... just worked?

Well, that's not too surprising. Car size was always a per-car variable in the code. I had started with cars of randomly +/- 10% size difference back when they were simple untextured boxes. Once I added 3D models, that randomness didn't look right, especially when two identical models of the same car were next to each other and different sizes. So I removed the random values and made all cars a constant size. There was a variable, but it had the same value for all cars. When I changed the size to add larger trucks, the size handling still worked. Now that variable has two values that differ by 1.6x.

I suspect there are still minor problems with trucks. For example, they may stop at the wrong place and block intersections, use the wrong acceleration/braking, or leave the wrong amount of space between them and the vehicle in front. I haven't actually seen any of these problems though. Maybe they only show up in rare conditions such as when two trucks are adjacent to each other while waiting at a traffic light in a heavy traffic area. I'll have to let the simulation run for an hour sometime to see if any problems turn up.


I added crosswalks to city intersections the day I came up with the idea. No, I still don't have pedestrians. Maybe some day I'll add them, though I'm sure they're much more difficult than cars. Considering how much trouble I had with car navigation, I'm afraid to think about adding people. Plus I don't want to have to find dozens of unique models of people online. (I don't have the tools, time, skills, or patience to create them myself.)

Anyway, crosswalks consist of those typical walk/don't walk signals at most of the intersections. In the case of 3DWorld, they appear at all intersections except for some of the 2- and 3-way ones along the edges of the city where they're not needed. Crosswalk signals are tied into the traffic lights so that they allow safe walking when cars are stopped at red lights. They have the expected three states: walk (white), don't start walking (flashing orange hand), and don't walk (orange hand).

These signals are attached to the sides of existing traffic light posts. They produce emissive light that's only visible from a narrow view angle facing the player, just like real crosswalk signals. Here's how they look in the city.

Intersections now have crosswalks that are tied into the traffic light system and change between white/walk, orange flashing hand, and orange hand (don't walk).

I believe the white car on the left has just made a right turn on red, which is why it's in the crosswalk. If I add pedestrians I'll need to handle this case. Either cars need to check for pedestrians before turning on red, or pedestrians need to check for turning cars before crossing. Maybe both.


I made all weapons destroy cars. This includes the baseball bat. Car explosions don't hurt the player, so you're free to walk up and bash them. Note that these are self-driving cars and there are no people. If you don't believe me, take a look in the car/truck windows in some of my city screenshots. There's no driver!

Cars explode when hit with a huge baseball bat. They explode when hit with pretty much any weapon/projectile.

I still haven't made buildings or other city objects destroyable, and I haven't made cars react to explosions. Those are future work items.


Okay, lava improvements aren't really related to procedural cities. They don't actually belong here, but I'm going to add them anyway to avoid having to create another short post just on lava. I can justify these screenshots in a city post by adding cities to the lava scene. Or adding lava to the city scene, if that's the way you prefer to think of it. Something like this:

Procedural city with orange lava flows in the background.

That last screenshot had lava in the background. Here's one with a closeup of lava and the city in the background instead. The surface of the lava is emissive and somewhat reflective, similar to water. In fact the lava and water use the same C++ code, they only differ in the fragment shader. I use a tessellation shader to generate waves on the lava, and the red-orange texture is animated over time. This produces a moving lava flow effect. Spherical bubbles form in the lava and release steam, which rises into the air. In addition, there's a heat haze postprocessing effect that distorts the scene when the player is near the hot lava surface. You can see how the city appears wavy in the distance.

View from above the lava surface, with a city in the background. There is a wavy heat haze screen-space shader effect.

Here's another shot of lava in a sandy area of the terrain from a bit higher up. The lower gray clouds are steam, and the larger, higher white clouds are ... normal clouds.

Another view of a lava pool with bubbles and steam clouds rising from the surface.

This is proof that cities don't have to be placed in the typical grassy + hilly terrain I've shown them in for every other blog post. Cities can be placed in any user-defined biome. They can be in the mountains, the plains, a dense forest, a desert, a rock pile, or on a hot lava planet. Temperature, vegetation, atmosphere, water level, ground composition, etc. are all independent config variables. It's all configurable in the scene text file.