I’ve not abandoned the project, I’m just on holiday. In Japan, in fact, where there’s loads of skyscrapers to use as reference material. Be back soon.
Archive for July, 2009
So, we’ve got a road layout – now we just need to add some buildings to it. For a first pass, I just add simple blocky buildings; one per lot, with a height equal to the minimum of the width or height of that lot, and it looks like this:
…which isn’t bad, I guess, but there’s these enormous monolithic slab like buildings all over the place, and it looks really homogeneous again. So, let’s add the other building types back in and see what that looks like:
Well, that’s a bit better, but it still looks a bit Bladerunner-ish – the big buildings are still far too big, and I’m getting scene-dominating and unrealistic massive wedges still. It just doesn’t look realistic – I need to reduce the size of some of the buildings.
So, the next step is that once I’ve done my initial load of lot-splitting, as documented in the previous entry, I then loop over all the lots I’ve created, and if any of them are bigger than a certain maximum size, or have a length:width ratio of greater than 5, then the lot is split again, and this repeats until all the lots are a sensible size/ratio. And the final result of that is this:
…which I’m much happier with. I’ve also played around with the fogging a bit, which means the buildings don’t start to fade out until they’re much farther away; I’m not totally convinced it helps – especially on the NC10, which these screenshots were taken on – it just makes the scene busier and adds more visual noise. I’m also a bit unhappy that the buildings still all seem to blend into one – it looks better in motion, but perhaps I need to increase the amount of colour modulation that happens with the windows? The other this is that there’s no street lights or roads yet – I’m hoping that these might help to break the city up a bit more, and that’s the next step.
(note that the framerate in all these screenshots is ridiculously poor – this is because I took the screenshots on my little Atom-powered Intel-integrated-graphics netbook – on a machine with a sane graphics card, we’re still getting close to 60fps – although not close enough that I’m happy to leave it without future optimisations)
In the meantime, you can, as ever, check the code out of the bzr repo – we’re up to revision 45 now.
So, Shamus Young, the lovely man whose PixelCity project this entire developer diary is inspired by a tribute to a total rip-off of, has linked to it from his blog. Which means my pages views for the last couple of days have totally exploded.
I left a comment on his blog, but I should perhaps address a couple of the same points here:
- I’m doing this because I can, and because I wanted something to do in the evenings that my wife is out of the house. I’m on a hiatus from World of Warcraft at the moment, so figured a programming project might be fun, and as an ex-games developer with a lingering interest in 3D graphics, PixelCity provided a perfect inspiration.
- I’m focusing far more on the technical aspects of my project than Shamus did for his – this is because, as I said above, this is a total rip-off of his original project, so all the interesting stuff about what looks right and making things look realistic has all already been written about. This isn’t a “How to draw a realistic city” diary – it’s a “How I did it in C#/XNA using more modern techniques” diary. As things progress, I might head in a different direction on some aspects (like the city planning entry) – I’ll discuss what I’m doing there in a bit more detail.
- The C#/XNA “ZOMG MS ARE TEH EVILS” thing is not something I’m interested in discussing. I just can’t get worked up about it, I’m afraid.
- I make no promises about how often this will update. It was pretty rapid at the start but, as with many things, it’s sort of tailed off a bit lately. It’s got sunny, I’ve been busy at work, my chilli plants need tending – I fully intend to carry this through to… well, some poorly-defined and probably still distant end-point, but I have no idea when that might be yet.
- I apologise for inconsistently switching between first-person singular (“I did [x]“) and first-person plural (“We need [x]“). I’m a programmer, not a writer.
I think that’s about it. Thanks for dropping by; I hope you enjoyed what you read.
So, I’ve been busy trying to work out algorithms for generating interesting city layouts. I spent a good long time chasing down alleys that turned out to not work too well: I’d decided that I wanted something a bit more elaborate than the straightforward grid layout I’d been using (and that TwentySided also seemed to use), but making things look interesting and realistic, but not also horrifyingly complex to code turned out to be more difficult than I thought. I also caught myself in the classic case of refusing to throw away code I’d already written and piling more bad code on top of bad code.
One approach I initially tried was to start with an empty city, and then plant lots on it, starting with large lots clustered around the centre, and then gradually filling in the gaps with decreasing size lots. Each lot would be bordered by roads on each of the four sides, and then I’d add random roads afterwards to divide up any remaining space. However, this often ended up with a load of roads running right next to each other – and also, I wanted the ability to have variable width roads, and this approach didn’t really lend itself to that. So, after far too long, I gave up and threw it away, and came up with the approach that I’m working with now.
Instead of starting with an empty space and adding lots, I decided to do exactly the opposite – start with a space filled by a single large lot, and then carve it up: so, the initial lot gets carved into two, and then each of those gets carved into two, and so on. Each split creates a road – the initial road width is wide, but as the lots get smaller, so do the roads – thus areas with a large number of small lots will tend to have small roads, whereas areas with larger buildings will tend to have bigger roads.
I also added a number of heuristics to make it look more “city”-like: when splitting a lot, the split point is random, and may be horizontal or vertical – if the lot is taller than it is wide, the split is more likely to be horizontal than vertical, and vice-versa. This ensures that buildings are mainly roughly square – long, thing buildings are rare in real life. Also, not every lot is split: in order to create a more built-up CBD, for each lot, the probability of a split taking place is increased the further away from the center of the city the lot is, but in order to make sure the lots aren’t too big, the probability of a split is also increased as the size of a lot increases.
The result can be seen below as an animation – the road colours correspond to different “classes” of road, that may end up being rendered differently at some point.
The next job is to actually plant some buildings in the lots – there’s still some work to do here, because a lot of my code tends to work best with base sizes that are roughly square, and I’ve still got a fair few lots being generated that are of a size ratio 2:1 or more – but anyway. You can check out the latest revision – 44 – from the bzr repository.