Posts Tagged ‘prettification’

Cityscape – update 7

Monday, May 25th, 2009

So, one of the things the project I’m ripping off did to add variety was to make some buildings slightly yellow, and some buildings slightly blue. Yesterday’s update was still looking a bit homogenous, so in the spirit of ripping off everything, I decided to implement the same thing. And it now look like this:

Now, this took a bit of doing. Because we batch up all our rendering, we try to change as little state during rendering as we possibly can – so, for example, we could have added an extra parameter to the shader to add a tint to everything rendered. However, this parameter would only have been changable between batches, which means we’d have to batch like-coloured buildings together – which would be entirely possible, at the moment, but later on I plan to exploit spatial proximity between buildings to produce batches for culling, and having to produce three batches per region would add complexity and potentially reduce performance.

So, the other place we can pass in static data? In the vertices. Each vertex could have a colour attached to it – this way, so far as our batching is concerned, all buildings are still equal. The downside is, there’s no space in our current vertex format (VertexPositionNormalTexture) for this information. One possibility is to turn off lighting (the city is at night-time, remember?) but I’ve got other plans for that, too, so the best option seemed to be to roll my own vertex format – VertexPositionNormalTextureMod – which simply adds another Vector3 to VertexPositionNormalTexture. Then it’s just a case of changing all my buffers over to use this format, add the relevant extra data and make the appropriate changes to the shaders to do the actual tinting.

Pleasingly, this didn’t seem to affect framerates at all (at least, not on the number of buildings I’m working with at the moment), and the effect is quite lovely – it adds some much needed variety to the scene.

The latest revision is 21 in the repository – there wasn’t a trunk revision attached to update 6, but you can check out revision 7.1.13 if you want to have a look at that.

Cityscape – update 6

Sunday, May 24th, 2009

Right, I’ve made definite progress towards getting things looking a bit better. It turns out that it doesn’t really matter than my buildings are ugly as hell, because buildings actually are ugly as hell – at least for the most part.

The first thing I needed to do was make the 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 selection of pixels in the lower half of the window, and then addded a small colour modulation.

The next thing to do was to make the buildings more interesting. Currently, a building consists of a central main tower, and then on one or more of the building’s faces, a smaller sub-tower. This took a ridiculous amount of work to achieve, and several iterations of the maths concerned – and I’m probably still going to throw it away once I think of a nicer way of doing it. But it’ll definitely do for now.

The last thing this update adds is a movable camera – the spinny-round camera was handy for testing performance and getting an overview, but it was seriously limiting in terms of making cool screenshots 🙂 It’s pretty simple – we have a position, a rotation around the y-axis and a rotation around the x-axis. The WASD keys move the position, and the arrow keys affect the rotation. We generate a look vector by transforming a view straight down the Z-axis by the two rotations.

Oh, and I made the background darker and added a black base, to make things a bit more city-like. If I’m honest, the dark blue sky is the thing that adds most realism out of the entire update 🙂 One last screenshot:

Next, we make things a little less homogenous, and discover that it’s not as simple as we might think.

Cityscape – part 4

Friday, May 15th, 2009

Things have come on a bit since yesterday. I’ve added a first-pass of the building textures, and a polygon count (for reasons which will become apparent soon enough. Now, it looks like this:

The 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 scattered across it. To get the solid-black of the tops of the buildings, I’ve simply set the texture map to a single pixel at the bottom left of the texture.

Also, you’ll notice that I’ve added more buildings – in that screenshot, it’s a 31×31 grid of buildings (with random heights, for a bit of interest), and added a polygon count. Now, the reason I added the polygon count is interesting, and we’re going to learn a bit about how graphics cards work in the process.

So, I increased the number of buildings to 961, and the framerate stayed nice and happily at about 60fps. Excellent. Then, I got greedy, and made the grid 41×41, giving me 1681 buildings – and the framerate plumetted to around 40fps. This seemed odd – I’m not yet hitting really big polygon budgets. Games these days happily push hundreds of thousands, if not millions, of polygons per frame, and whilst XNA is doubtless adding some overhead, this machine manages to pull off things like Demigod and Dawn of War 2 on respectable settings without too much pain. So something, clearly, is up. I added a polygon counter just to check my sanity, and yes, we’ve nearly doubled our polygon budget, but it’s still only about 20k polys:

Hm. So, what do we do in this kind of situation? Well, we investigate! We’ve basically doubled our poly budget by doubling the number of buildings, right? Well, more or less, anyway. How about instead, we drop our number of buildings back to the original number, and increase their complexity? What happens then? So, I added the base back on, which is essentially just another box at the base of every building, and…

Wait, what? We’ve now got more polygons than we had in our 41×41 scenario and we’re still at ~60fps. Something odd is happening here. So what happens if we add more (mini-tower on top) and more (two stage body for the building) complexity? We can do three times as many polys as our original 31×31 city without a framerate drop – it’s only once we get to four times as many – fourty-six thousand, over twice as many polygons as in our 41×41 city – that we start to see any impact at all, and it’s only a couple of fps. What the merry hell is going on here, then?

Well, remember how our buildings are constructed: for each box, we insert the vertices and indices into an array, then convert these to fixed-size vertex buffers for use when rendering. There’s one of these buffers per building. As we’re adding more complexity to our buildings, we’re increasing the amount of stuff in each buffer; however, when we add more buildings, we’re increasing the number of these buffers that need rendering – so it seems that it’s the number of buffers (or, more accurately, the number of draw calls we make) that’s our killer here.

And this is an important point: think of a graphics card as being like a car engine. You get most efficiency out of an engine when you drive smoothly, and a moderately high (but not excessive) speed, without changing speed too much; driving around a city where you’re constantly braking, changing gear, stopping, starting and so forth is absolute murder on your engine’s efficiency – and it’s the same thing for graphics cards. Hand them a big buffer of triangles to go off and render, and they’ll tear through it at high efficiency. Hand them a whole load of small buffers, or change texture or shader regularly, and they really start to struggle.

The reason for this, more-or-less, is that the time for a render call is split into two parts – a fixed setup cost, and a variable rendering cost. If you’re rendering a large number of small batches, your render time is going to be dominated by a very large number of fixed setup costs; however, if you render a single large batch, you only have to do this setup once, and then the rest of the time can be spent on actually drawing the triangles.

So, what can we do about this? Well, that’ll have to wait until next time – but remember, all of our buildings are using the same texture, shader, vertex format, etc – so an obvious solutino should hopefully present itself!

(We’re up to bzr revision 13 now, if you’re following along at home)