Procedural City, Part 2: Building Textures

 By Shamus Apr 14, 2009 49 comments

Technical Details

I should have given these details in the initial post:

  • The project is bound to Windows right now. Several people made great suggestions yesterday for wxWidgets, Qt or SDL. I don’t have time to examine those now (the interface is already done and I’m anxious to move forward) but I am making a note to make sure my next project is written on something portable.
  • I’m using OpenGL for rendering. The API seems more quaint every year, but it still gets the job done without getting in the way.
  • The look I’m going for is a helicopter-level view of a city, not a street-level view.
  • The city is going to be pretty basic. 30 hours is not much time, and I’m aiming for simple-yet-effective as opposed to profound and feature-rich. While a lot can be done with a procedural city, I’m not going to take this idea very far to begin with. I just want something that’s fun to view for a couple of minutes.

Textures

As I stated in my original post, my goal is to make a program that generates all of its own art assets. The first asset I’ll need is a texture map for on the buildings.

The surfaces of buildings are typically complex. Brick? Concrete? Classical engraved stone? Steel? Making all of those surfaces, their colors, their shapes, and making those details line up with the building itself would be a huge undertaking. We’re not making GTA IV here and I don’t have an army of developers and artists at my command. We’ve got one guy, store-brand coffee, and 30 hours. So the smart thing to do is to make this a stylized low-detail night scene and make the buildings themselves pitch black. I’ll hint at a detailed building using the light coming from the windows.

Since I’m dealing entirely with windows to define a building, I grab some reference images of nighttime cityscapes and study them to see what kind of details and effects I can devise.

I set up a texture map. It’s 512×512 pixels (a nice mid-size texture) and I divide it into a grid of 64 x 64 windows. This means each window gets just 32×32 pixels. That’s a very small space, and the goal here is to make the most of it. The old Douglas Adams quote comes to mind, “Little expense had been spared to create the impression that no expense had been spared.” That’s sort of the approach I want to take in regards to the details in these windows. Here is part of the full 512×512 texture:

This is the upper-left quarter of the texture. There's just no point in making you download the whole thing.
This is the upper-left quarter of the texture. There's just no point in making you download the whole thing.

Note that this texture will never appear in its entirety on a single building. Instead, many buildings will share this texture and each will take a randomly chosen section of it. Now, so far this doesn’t look very interesting. Obviously some lights are turned off at night. But even in windows where the lights are off, there’s often a little bit of light coming from other nearby interior rooms. So few windows are truly black. And in rooms where the lights are on, the amount of light visible outside varies a great deal based on the placement of the lights and the positioning of light-blocking furniture within the room. Taking this into account, I make a texture that looks a lot more plausible:

Again, this is just 25% of the texture.
Again, this is just 25% of the texture.

This texture is randomly generated when the program is run, so the pattern of windows changes each time.

Looking at the reference photographs of buildings at night, I note that a lot of them have dark clutter / shadows along the bottom of the windows, which is either furniture or shadows cast by furniture. This presents an interesting challenge, which is how to create this effect with just 32×32 pixels. (And since I need a 1-pixel border around the window I actually only have 30 pixels to work with.)

I try adding some random grayscale noise to the windows. It helps make the windows look less artificial, but it doesn’t really convey the impression of stuff being in the rooms. I try adding a few randomly generated vertical lines across the bottom of each window, but then the windows sort of look like tiny little bar graphs. Eventually I realize that since I’m trying to clutter up the window to give the impression of furniture, I should aim for making dark patches in the lower half of the texture. Also, the lights in a window tend to be brighter at the top, so I create a slight fade that darkens the lower half of a window. The result:

pixelcity_windows3.jpg

That’s closer, but the windows still seem a little flat. I try adding some random color noise and all of a sudden the windows pop to life. The changes in color make the brain think this is a far-off view of a cluttered, busy scene.

This might seem like a lot of silly fussing around over individual pixels, but these little squares of light will be all we have to go on and they will need to sell the rest of the building.

This scattered look for the lit windows doesn’t apply to all buildings. Some are lit by floors or sections of floors. Sometimes people are working late on one floor while the workers in another office have sensibly gone home for the night. So I add a random chance that sometimes a building texture will light its windows in groups instead of scattershot.

pixelcity_windows4.jpg

That should create some much needed variety. Now that I have a basic system for making little squares with “lighting” and “furniture”, the last step is to just make a whole bunch of different window shapes. Some will be long horizontal windows. Some will be slightly rounded. Some will be slightly narrow. Etc. I manage to come up with 8 different varieties of window that look acceptable, which is less than I was hoping for. (There are only so many window shapes you can make with 30 pixels!) If I don’t have enough different textures then the constant repetition will be obvious to the viewer. The human brain is infuriatingly good at detecting repeating patterns.

Here is a full view of one of the 512×512 textures. Note that it’s 64×64 windows, so if a building was 65 stories tall then the top floor would have the same window pattern as the bottom. Not that anyone would notice, but I don’t plan on making any that tall.

pixelcity_windows7.jpg

And just because I can’t stand to wait any longer to see if all of this work is worthwhile, I turn off the green development background and slap the textures onto a big row of cubes:

Two thousand frames per second.  I tell my graphics card not to get too cocky.  We'll see how badass it thinks it is once I hand it a few thousand of these suckers to draw at once.
Two thousand frames per second. I tell my graphics card not to get too cocky. We'll see how badass it thinks it is once I hand it a few thousand of these suckers to draw at once.

Pretty cheap, but it looks good enough so far. Next time: Buildings!

EDIT: As has been pointed out below, 64×32 does not equal 512. I changed the parameters of how textures would work several times, and I wasn’t careful to make sure I updated the post to reflect these changes. For the record, it’s 512×512 pixels, 64×64 windows, and 8×8 pixels per window in the screenshots you see in the post. I’m still tweaking them from time to time to see how it looks at different settings. It actually looks worse when using more pixels per window. With 32 pixels per window, the detail hinted at is revealed to be nothing more than a sprinkle of color and the illusion is broken. It could still be done, but the furniture simulation would need to be more sophisticated.)

20209Feeling chatty? There are 49 comments.


  1. kjones says:

    God damn this looks good. I can’t believe that this is something you threw together in your spare time for fun.

    Keep up the good work.

  2. Jericho says:

    Very nice, and very clever, the window-clutter. I feel like zooming in and seeing what is in there.

  3. Kizer says:

    This looks like a scene from Koyaanisqqatsi! I’m looking forward to what it looks like when you actually create buildings in addition to textures. Well done!!!

  4. Ell Jay says:

    “We’re not making GTA IV here and I don’t have an army of developers and artists at my command. We’ve got one guy, store-brand coffee, and 30 hours.”

    Yes, but is it HOT coffee?

  5. Segev says:

    VERY nicely done. This, combined with your thoughts on procedural programming, could lead to very interesting potential for amateur game design again. But that’s probably putting the cart before the horse, so to speak. Good luck!

  6. Dennis Brennan says:

    Dude: curtains.
    They probably fall into categories, as follows:
    * totally opaque (black) or translucent (solid grey)
    * descending from the top of the window, or else narrowing it from both sides.

    Also, a given floor of a building will either have some curtains on a significant portion of the windows on the floor, or else there will be none at all on that floor.

  7. Joe says:

    It’s amazing to see what people can throw together with a little elbow grease and a lot of intuition. I’m willing to bet that deciding what you were looking for took you a lot longer than actually coding it up.

    Reminds me of stories I hear about a person at work: When the boss walks by and see the employee simply sitting at their desk, staring at the screen, they think the employee is slacking rather than thinking about the problem and its best solution.

  8. Rutskarn says:

    I resigned myself, when the series began, to not understanding half of the technical aspects of the series.

    Still interesting, though.

  9. Christopher says:

    I would take it one more step and see if you can mix the scattershot map with the grouped windows map. In the final image, it seems odd to me that the middle-left building is so scattered and the middle-right building only has whole floors lit up with no single lit windows scattered about.

    To me, the one on the far right looks the most realistic, but could still use a few lone windows here and there.

  10. DaveMc says:

    I’m so glad that you showed that final shot, since up to that point I was having little luck understanding what these textures were going to look like, in context. They make a nice city-scape, already! Low-res, but nice.

    Off topic, but where is that Douglas Adams quote from? I tried Googling the phrase, and I was pointed to some site called twentysidedtale. (It brought me right back to this very post, which I found amusing, but it didn’t answer my question.)

  11. Factoid says:

    How come the fully lit windows tend to come in rows on buildings 1, 3 and 4 but randomly scattered in building 2? Are those buildings offices while the other is residential? It would make sense that a business would have continguous rooms all lit like that.

    edit – nevermind, I guess I missed a paragraph while reading

  12. Wow! Looks great! Hell, it looks better than I expected it to look when I started reading this post!

    Can’t wait to see how it will look once you are done with it!

  13. mockware says:

    since whole floor lighting is simulating office floors, wouldn’t it make sense to have the noise in the windows on each floor look similar?

  14. MuonDecay says:

    Just because part of me has to (even though I hate that part and wish it’d just shut up):

    “Helicopter-level” view would be “top down”, in the real world. Helicopters are capricious and dangerous things to fly. Except for the guys flying camera-carrying copters for Hollywood films, you won’t see pilots taking the things below a city’s skyline in most situations.

    Now that the horrible nerd in me has spoken, please punch it in the gut, take its lunch money, and tell it to shut up.

    I like the clever work you do. I was never good enough at math or linguistics to pick up programming and computer science, so it’s fun to have someone else’s work to watch and get excited about.

  15. Teron says:

    Awesome. I’ve been trying to motivate myself to try procedural generation, and this has made me want to code something and play with it.

  16. Liz says:

    My brain really, REALLY wants to see an awful lot of those windows not as windows but as facial portraits. Not sure why — a focus-point close to the middle of the square rather than at the edge? Color shading that doesn’t quite translate to “light” for me?

    Not to say I could’ve done even half this, mind. :D

  17. Hotsauce says:

    Just a thought about colors
    Nighttime isn’t pure black, and indoor lighting isn’t pure white. Perhaps dark blue for night and either yellow or light blue for the lighting inside the building?
    But then you probably just haven’t gotten to that point yet.

  18. ngthagg says:

    I think the two outside buildings look the best, although I suspect they would look better if the floors that don’t currently have bright windows were had a few individual rooms lit up. But I’m astounded on how any one of those individual buildings looks pretty accurate on its own.

  19. Julian says:

    How about making some of the lights (particularly the scattershot ones) more yellow? The pristine white look only really works for hospitals and the like.
    Anyway, I must admit that this is amazing. Can’t wait to see what else you come up with.

  20. mc says:

    “We’ve got one guy, store-brand coffee, and 30 hours.”

    Would it be any more impressive if it were gourmet coffee?

  21. Jericho says:

    Yeah, maybe adding a touch of yellow randomly might add some more realism, as would mixing the grouped/randomized window areas. Also, I know that it is temporary, but I would get rid of the “mirroring” you see at the corners.

    But that does look fantastic.

  22. Muttley says:

    @Jericho:

    Why? Mirroring actually does make sense. Or rather: You need both windows at one edge of the building to be either on or off, as they both open on the same room. Probably mirroring is the easiest way to achieve that.

  23. bbot says:

    As apparently several people have beat me to nitpicking, the lighting in apartment buildings have, on average, a lower color temperature (2500k for incandescents, 2700k for compact fluorescents pretending to be incandescents.) than commercial buildings (3000k and 3500k, up to 4100k and 5000k for dentists and other medical offices.)

    In fact, (putting way too much thought into this) residential buildings would have a much greater range of color temperatures in general. Warm white for incandescents, flickering blue for people watching television or programming cityscape simulators in the dark, harsh clinical white for people eating dinner off of gleaming stainless steel plates in their hilariously expensive penthouse apartments.

    Commercial buildings would have either floors, or the entire building, of one color temperature, to make maintenance easier. Corner offices, meeting rooms, and reception areas tend to use incandescent lighting, but reception is always right off the service core, where the elevators run, and thus doesn’t factor in. Figure one meeting room per 15 or 20 offices, very least one per floor, always facing the best view, to impress clients.

  24. grasskit says:

    this fooling of the mind and suggestiion detail in the windows reminds me of Bellotto painting with a bridge with lots of people on it, although when you zoom in, the people are just vague pixels. your mind invents the details, all you need is slight suggestion, which is explaned in exciting talk by Daniel Dennet in TED conference about how our mind tricks us (for anyone who has 20min to spare for very interesting talk http://www.youtube.com/watch?v=fjbWr3ODbAo&)

  25. Hotsauce says:

    “We’ve got one guy, store-brand coffee, and 30 hours.”

    You forgot “it’s dark, and we’re wearing sunglasses”

  26. Ethan says:

    Fluorescents tend to look a bit greenish on video. Nice work, Shamus. Procedurals can be pretty fun. Are the building “models” themselves going to be procedurally generated as well?

  27. vdgmprgrmr says:

    Well, Shamus, that’s it.

    I’m following you.

    A few times, I’ve made a crappy random city generator (seriously, crappy, it generated the city the way you generated your textures) and put zombies in it for a quick zombie-shooting experience. So now, I’m urged to go for a third iteration of my never-released-or-finished-or-worthy-of-any-real-merit-at-all Zombie Shooter series. It was an FPS with zombies, and I didn’t know that there was actually a series called Zombie Shooter when I made the name up. It just felt… logical.

    So, anyway, I’m following you in Blitz3d. I’m going to copy your basic techniques in B3d, and make myself some zombies to shoot at.

    Unless you’re totally opposed to such a thing, of course.

    I need something to do after I finish my current project (or give up on it, like every other thing I start on), which will be very soon, anyway.

  28. Primogenitor says:

    Might be worth adapting it a bit so some blocks have slightly larger or smaller windows than others. Probably don’t need to make new textures, just tell openGL to scale it to 75%-125% when applying (if that sort of thing can be done).

    Also, my gut tells me that youve got too much color in those rooms, particularly red. Not quite sure why though.

    Does that have those 8 window types you mentioned? They look rather square to me.

    But on the whole, Id say you’ve already put more detail in them than most generated non-street view city! Good job!

  29. D4 says:

    DaveMC: From “The Restaurant At The End Of The Universe,” we get: “…in short, all the paraphernalia common to restaurants where little expense has been spared to give the impression that no expense has been spared.”

  30. Tacoma says:

    In a few hours you’ve made graphics that look good enough for me to be willing to play a game with them. We need indie game designers who are willing to make a decent-looking game with excellent depth because the big companies aren’t smart enough to figure it out.

    Kinda like how when he finishes the UI for dwarf fortress it will consume everything and everyone we all love.

  31. Muttley says:

    @bbot:

    and this is just a static image. When the buildings start moving, do you think Shamus will adjust the spectrum for Doppler shift?

    Also: can you see the double peaks of Mercury in fluorescent lamps? I used to calibrate diffraction gratings with those.

    NERD_MODE_OFF()

  32. Volatar says:

    @Tacoma

    Dwarf Fortress doesn’t already consume everything and everyone we love?

  33. Jericho says:

    @Muttley: Yeah, for the first row it makes sense, but beyond that, you get a obvious pattern. It’s not terribly bad, but it IS noticable, especially the random-scatter one.

    Just a thought, anyways.

  34. Zel says:

    I’m surprised noone has mentioned it before, but with a 512×512 texture and 64×64 windows, each one only gets 8×8 pixels and not 32×32 (actually 6×6 with the black border).

    It’s late, maybe I overlooked something but last time I checked (with a calculator a second ago), 512/64 = 8. Please correct me if I’m wrong.

    Anyway, it looks pretty nice for a few hours worth !

    You could wrap your generated texture around the building instead of mirroring on each face. What building will have a row of more than 16 windows anyway ..?

    For a next-gen look, you could consider adding a bit of bloom. It’s quite simple and doesn’t need shaders. It requires a blurring algorithm but you can find hundreds of them on the Internet.

    Also, what do the roofs look like ? Four blipping red lights and helipads on some of them would be nice to add a little life.

  35. Mark says:

    Since we’re nitpicking, I think maybe the grayed-out windows need to be darker overall, and perhaps a higher proportion of black windows overall. But that is pretty much amazing.

  36. Fosse says:

    Everyone is talking about color. These appear to be grayscale images to me. I assume I’m missing something, but my browser is displaying color everywhere else on this page and others. I just assumed color was going to be procedurally layered on top later on, until everyone started talking about it.

    I loved bbot’s post, also.

    EDIT: Ah, never mind. I blew the picture way up and can see it now. I’m very near sighted, and long ago hit the point where in order to make things look clearer my lenses must also shrink them a great deal. So the color was just too minute for me to see. Looks nice.

  37. dagnabit says:

    As an aside note, it’d be nice if you put up a zip of the day’s code with each blog entry so people could see precisely what you did, on top of the explanation in the post.

  38. Octal says:

    This is really interesting. Something does bug me, though… starting with the first not-all-white texture and continuing to the final, complete texture. The darker windows look sort of… puffed-out. Like a quilt, almost. They look like they’d have a rough or soft texture, not a smooth glassy one. When I look closely at that first one, I can see that the dark windows have sort of a tic-tac-toe shape with alternating squares filled in, which I guess is the cause. JPEG artifacts? Hmmm. The effect doesn’t seem so strong in the shot of the buildings.

  39. Fon says:

    It looks nice, but I agree with Liz(‘s brain) that instead of windows, it look more like facial portraits.

  40. Cuthalion says:

    I think building #3 (the third from the left, second from the right) looks most convincing.

    You may also want to skew the color noise a bit: I don’t believe I’ve ever seen a skyscraper window with purple furniture/light, but you’ve got a few that seem oddly red or purple.

    I also agree with somebody that you should have more of a range of brightnesses. What I mean is, the dark-but-not-black ones seem like they should mostly be a bit darker, and it overall looks like there’s only four brightness levels. I think there should be more variety between the mid and dark windows.

    All that said, I’m still majorly impressed! My eyes really do want to see all that as furniture.

  41. MuonDecay says:

    I would try to desaturate the colors a little bit, myself.

    Level design background I have none of but art background I have some of. If the colors were all commonly pushed a little closer to grey it would maintain a more congruous nighttime feel.

    What you have going on there so far does resemble what I remember of the Los Angeles skyline in the evening, barring that one nitpick. Not only is there not a full spectrum at night (natural or otherwise), but those windows are usually tinted or colored (in addition to that slightly metallic-looking coating that pretty much all windowed high rises now have to reflect the sun’s heat) and all of the images and lights you see from the building will share the common color of they glass they’re filtering out of.

  42. stringycustard says:

    I love how you are concentrating on the hint of detail. This is something I’ve been meaning to do for ages (procedural programming) and it makes me happy for somebody experienced to give us all a rundown of how it works, and the details of it. Your texture work is spot-on.

  43. Leonardo Herrera says:

    I’m loving this series already.

    - Rows of lit windows need to have similar “clutter”. Think open spaces there.
    - Same for unlit floors! In your office buildings, unlit floors should also share similar light levels.
    - I would guess clusters of windows instead of separate windows for residential buildings (spreading light to neighbor windows.) You may want to only do this in the x-axis (don’t make sense to spread light to the upper floor, unless you have duplexes… but that’s probably going too far.)

    I guess you are tackling color next. Good luck there!

    Anyways, this seems that a fun project to do. Screensaver, anyone?

  44. mneme says:

    Hmm. Looks to me like what you really want is to have randomly selected buildings have randomly selected “default white” floors — then apply the existing scattershot pattern (include black as well as white, and just replace windows you overwrite). Thus “all white” floors may have some dark rooms, (and will have a scattershot of lit rooms elsewhere in the building), etc.

  45. yd says:

    I’d also suggest that any given building not be so consistent. There are likely to be mixes of entire floor lighting and single room lighting in the same building. 

  46. Dev Null says:

    For early stages, it looks great! It seems a bit strange that every building has floor-to-ceiling windows in every room. (Though you do mention multiple textures with different window shapes, which I don’t think we’re seeing in any of your examples yet…?) Admittedly, office buildings tend to go for large percentages of glass, but residential blocks often have – real or fake – balconies covering half the space, or just windows that only go partway down.

  47. Here’s a link that may help/inspire: http://www.pxlshots.com/blog/2009/04/100-beautiful-night-scene-photos/

    Someone passed it to me for womething else, and I thought, “Hm, I’ll bet Shamus would appreciate that.”

    There ya go!

  48. [...] textures more interesting. And, again, I just went straight ahead and nicked the technique used in TwentySided’s blog, althought it took some tweaking. In each window, I’ve darkened a random [...]

  49. [...] texture generation is simple enough (and mainly ripped off, like the rest of this project, from TwentySided’s PixelCity) – a 512×512 near-black texture, with 8×8 blocks of either light or dark grey [...]

2 Trackbacks

  1. By Cityscape – update 6 « Not a blog on November 24, 2009 at 4:01 pm

    [...] textures more interesting. And, again, I just went straight ahead and nicked the technique used in TwentySided’s blog, althought it took some tweaking. In each window, I’ve darkened a random [...]

  2. By Cityscape – part 4 « Not a blog on November 24, 2009 at 4:11 pm

    [...] texture generation is simple enough (and mainly ripped off, like the rest of this project, from TwentySided’s PixelCity) – a 512×512 near-black texture, with 8×8 blocks of either light or dark grey [...]

Leave a Reply

Comments are moderated and may not be posted immediately. Required fields are marked *

*
*

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun.

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!