Procedural City, Part 2: Building Textures

By Shamus Posted Tuesday Apr 14, 2009

Filed under: Programming, Projects 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.)

 


 

Stolen Pixels #81: Left 4 Dumb: Part 3

By Shamus Posted Tuesday Apr 14, 2009

Filed under: Column 19 comments

I can’t decide what I like most about Left 4 Dead. Playing it, or making comics about it.

Who am I kidding? Playing it is two or three flavors of awesome. Thanks to everyone who joins in and acts nothing like I depict in the comic. That’s appreciated.

 


 

Procedural City, Part 1: Introduction

By Shamus Posted Monday Apr 13, 2009

Filed under: Programming, Projects 155 comments

Change of pace. In the last week I’ve had an idea clawing at the back of my head, and it’s clear the thing isn’t going to leave me alone until I do something with it. I don’t usually blog about my little programming projects (with the exception of the Terrain Project) because I like to imagine this site has some sort of focus, but the choice here is for me to blog about this or leave the site fallow for a week. So I’m blogging it. Perhaps you’ll find it entertaining anyway.

Motivation

There are several reasons for wanting to do this.

It’s comical now, but this was a real eye-grabber in 1996.
It’s comical now, but this was a real eye-grabber in 1996.

Way back in my early days of 3D development a lot of my work was focused on creating effects or finding tricks to make it look like there is more to the scene than what is really being rendered. A lot of work was being done by game companies to simply push the technology as far as it would go, but I enjoyed getting halfway there with technology and then going the rest of the way with a good facade and some lighting tricks. The techniques I used in the mid 90’s would seem laughably simplistic and trivial today, but at the time I remember getting a lot of “How did you do this?!?” type reactions to my work.

For example: I wanted to make a city, but the scene just couldn’t render things at a great enough distance to give you a “big city” feel. It just felt like a handful of big boxes next to each other in the middle of a featureless plain. So I set the city at night, scaled the buildings down so that they weren’t really much bigger than houses, and slightly pinched the tops of them so that the top of the (apparent) cube was smaller than the base. The reduced scale let me get a lot of buildings close together, the night lighting let me suggest more detail than was really present, and the skewed shape created a false impression of height. (The eye wanted to believe that these building-ish objects were cubes, and so when you looked up it made them seem taller than they were.) The scene was pretty astounding in 1996, although I doubt it would impress anyone today.

This sort of thing was an unusual blend of technical and artistic work, and I enjoyed it immensely.

l4d_buildings.jpg
In a section of the Left 4 Dead commentary (near the very end of the initial No Mercy level) one of the developers draws attention to an apartment building in the distance. He explains that it’s a very simple building with little detail, but because it’s mostly a silhouette against a detailed sky, the eye accepts it and your mind fills in details that aren’t really there. This reminded me a great deal of my old work, and got me itching to do some of that sort of thing again.

My new graphics card is ridiculously powerful. While I’m working less and less with graphics these days, on the rare occasions where that sort of work crops up it’s still focused on getting more out of widely adopted low-end technology. So I haven’t worked with much new technology. (“New” being very relative. For me, anything younger than a kindergartner is new.) This makes me some sort of cutting-edge Luddite, pushing the limits of stale technology.

CPU’s have stagnated a bit over the last few years while GPU’s have continued to accelerate. (No pun intended.) This has moved a lot of the old bottlenecks around. I think it would be good for me to get to know one of these recent GPU’s and see what it’s like to work with them.

And finally, I love procedural content, but I never get a chance to work with it.

Goals

1. The goal is to make a nighttime cityscape that is mostly made of lights and suggestions rather than real detail.

2. The city will be entirely procedurally generated. That is, the program will contain no art assets. No textures. No models. Everything must be built from scratch at startup.

3. I’m budgeting a week of nights and weekends for the project. So, probably about 30 hours of time total.

4. I’m going to use only conventional rendering. While I’d love to muck about with pixel shaders and see what the new ones can do, I haven’t messed with that sort of thing since 2006. Just getting up to speed on the subject would blow my entire time budget. (Pixel shaders are special programs that run on your graphics card instead of on your “computer” with all of your other software. They are strange, amazingly powerful, and difficult to master.)

5. I’m aiming for something that will run on a broad range of machines. This will be a little tricky, since my current machine is pretty beefy compared to the average. (I’m talking about the average windows-based PC, not the average gaming computer.) It’s much easier to develop on an old machine than to develop on a new one and try to guess where the bottlenecks will appear when run on old hardware. All of our older machines around the house have been converted to Ubuntu, and running under WINE wouldn’t make for a very useful benchmark. So this goal will be difficult to judge. The best I can do is aim for the program running at at least 100 frames per second on my PC and hope that it can still manage 25 or so on an older machine. Even this is pretty dicey, but it’s the best I can do for now.

I don’t know what I’ll do with the program beyond the goals above. Give away the source? Turn it into a screensaver? Add more features? We’ll see where the project takes me and how interesting this is to people.

Getting Started

The first step in a project like this is to make a simple program to open a window, start up OpenGL, and provide some basic camera interface so that I’ll be able to examine my work. This involves gathering up a lot of boring boilerplate code, creating the project files, and adding a bunch of not-very-interesting low-level systems. The result is not very compelling:

pixelcity_base.png

Sorry for dragging you all this way only to show you an empty window, but this is how it often goes. I’ll make sure to have something more compelling to show you next time around. This series will run all week, assuming everything goes to plan.

 


 

Unskippable: X-Blades

By Shamus Posted Saturday Apr 11, 2009

Filed under: Movies 38 comments

I had trouble enjoying this Unskippable because of the way the cutscene made me hate the game with an unquenchable passion. This antipathy is particularly deep in regards to the main character, who has the personality of Paris Hilton, but less intellectual. From her preposterous outfit that makes Lara Croft look like a nun to her heroic display of vapidity, stupidity, and skankidity, there was just nothing notable or likable about this character. Her personality is abrasive, her voice is grating, and her dialog is narcissistic expositional pablum.

Perhaps you could just ignore the cutscenes, plot, characters, and dialog. You could sweep the narrative aside and enjoy some mindless button-mashing violence, but apparently the gameplay is also insufferable. A male player might be able to overlook both the narrative and the gameplay to enjoy some cheap T&A, but they ruined that by making her look underage and giving her a voice actress that makes Yoko Ono sound like Judy Garland.

So… I guess I won’t be adding this to my “buy” list.

“But, you’d think she’d know to wear practical footwear. Or for that matter, pants.”

 


 

Gamethread Apr 10 09

By Shamus Posted Friday Apr 10, 2009

Filed under: Notices 34 comments

Today I have the day off from the ravages of a job that wasn’t all that bad to begin with. Left 4 Dead tonight is inevitable. Team Fortress 2 is possible. And by “tonight” I mean, “anytime after noon”. Noon was two hours ago for me. I plan to vigorously slack off very soon. Perhaps I’ll see you in-game. Remember that if I shoot you it’s probably not because of anything you did. Do try to be patient about it.

Note that you’ll need to join the Twenty Sided Group on Steam to join the official group server.

I know it isn’t possible, but I can’t help but think of how excellent it would be if the PC players could meet up with the Xbox players in some sort of utopian platform-agnostic server and play together.

Open thread for any pre-game or post-game comments. Also: when presented with a choice, do you take the pipe bomb or molotov?

 


 

Vatsy and Bruno

By Shamus Posted Friday Apr 10, 2009

Filed under: Nerd Culture, Pictures 20 comments

l4d_ff1.jpg
Online Left 4 Dead is now a nightly tradition. This regular evening exodus from the infection zone to a joyous yet undefined safety are ruinously fun, to the point where I’ve spent too much time shooting zombies and not enough time writing content for this website. Perhaps you’ve noticed and you’ve just been too polite to say anything.

If you’ve been in a game with me, you may have run into lnwlf, Thufir, or thegrimone, all members of my perpetually fallow tabletop gaming group. But more likely is that you’ve run into Rutskarn (who you may recognize from the comments here) who is the most patient of teammates, long suffering in the face of my errant bullets (which are sometimes to the face) and my habit of hoovering up all the pipe bombs. I’ve probably played more games with Rutskarn than anyone else that wasn’t software written by Valve.

l4d_ff2.jpg
In these games we sometimes chat about websites and the running thereof. Rutskarn has his own site, Chocolate Hammer, which has tabletop-type stuff, some fiction, and good supply of cleverness. He’s stuck in the stage where he probably suspects he’s putting up good work but doesn’t know how to get people to come and see it. Having toiled* in obscurity** for months*** on this site, I can sympathize.

* “Toil” in the sense of doing something fun that might vaguely resemble work to someone who didn’t know any better.
** Aside from the readers I was able to beg from SDB.
*** It was actually a year and seven days between the launch of the site and the start of DM of the Rings, but who’s counting?

His big project is Vatsy and Bruno, a work of fiction that I will excerpt rather than attempt to summarize:

To whom it may concern:

We do not regret to inform you that this submission is unusable, unintelligent and frequently illegible. We do not regret that your mental seepage, poured in such an ungainly fashion on your half-cent-per-thousand-sheet paper, will not be gracing this or any future publication of the Writer's Guild World Newsletter. We do not regret that you willâ€"most probablyâ€"die alone, penniless, unloved and foul-smelling.

We do, however, regret that we were exposedâ€"even through this protective screen of incomprehensibilityâ€"to this most unspeakable body of work. We regret that our sanity and our lives can never be whole again after even a brief perusal of your first page. We regret that the stink of hideous purple prose and suspiciously fecal ink will forever saturate our desk space. Most of all, we regret that you had slithered, like a diseased rat infiltrating an unsuspecting granary, into this world on whatever dark day you were born (from the art inherent in your prose, we would estimate about a year ago.)

If we ever see the name “Vatsy”â€"or that name spelled differently, or any name with a superficial resemblance, or anything that even reminds us of youâ€"on any volume, essay, poem, or bill that ever crosses our threshold, we will ensure that you will not survive the night that follows.

Wishing you well,

The Writers Guild

I didn’t think to get permission to talk about his age, but I hope Rutskarn will forgive me for revealing that he is not old. I was shamed last night when I discovered his age and I realized I was not nearly as promising or as focused at roughly that same stage in life. The site is full of amusing self-quotes, witty phraseography, and a solid dose of non-LOLCATS brand humor, a resource which is all to scarce on the internet.

You could do worse than visiting the site. For example, you could not visit the site.

 


 

Stolen Pixels #80: Left 4 Dumb Part 2

By Shamus Posted Friday Apr 10, 2009

Filed under: Column 10 comments

The latest Stolen Pixels, wherein Louis makes astute political observations in the face of tyranny, is now available for your enjoyment.

sp_l4d1.jpg