4
\$\begingroup\$

I'm rendering a city of several million cuboids that are all axis-aligned, touching each other and same-sized. They only differ in height.

Rendering them as real geometry is vertex-bound and too slow, so I've went with another approach: render them as several flat layers of a single, big texture. The more layers, the better the buildings look. This is similar to how a 3D printer works. Also I've seen it used for rendering hair, grass and snow. In my case, I'm using nearest-neighbor filtering to make the buildings square-shaped, and alpha-testing to control the building heights.

Here's a very zoomed-in screenshot so the individual layers are visible:

enter image description here

This works great, but when I use a higher number of layers, it gets too slow due to the fillrate. The cuboids are opaque so I tried optimizing this by enabling z-testing, but it hardly helped, because my shader is cheap (fixed-function, actually), and it's the only thing z-testing helps to skip. Or maybe it's because on my dev machine I have an Intel GPU and it doesn't do early-z discard.

So now I'm out of tricks. What could be used to optimize this? Also, any common names for the technique?

Notes:
- I'm aiming for OpenGL 1.4-level hardware, which is pretty restrictive when it comes to optimizing.
- I'm additionally using multitexturing with alpha-modulation to make arbitrarily-shaped, antialiased buildings (not enabled in the screenshot)
- Usually the city is viewed from a RTS-style viewpoint, all of it is visible, and it fills the screen, so fog or LOD techniques wouldn't work

\$\endgroup\$
3
  • \$\begingroup\$ Can you clarify the scale a little bit? For example, you say "several million cuboids," but my monitor only has about two million pixels. So when "all of it is visible," each building is approximately a pixel in size? Is being able to zoom in with no quality loss important, or is only the outermost zoom level important? \$\endgroup\$ Commented Feb 8, 2012 at 8:40
  • \$\begingroup\$ Yes, when viewing the city from afar, each buildings is about a pixel big, and the city has to look good both from afar and when zoomed in. I may limit the zooming (and the viewing angle) to some range if the buildings end up looking good only at moderate/far zooms. Basically my only requirement when zoomed in is that buildings look passable/nice, even if not truly realistic. When zoomed out, what matters to the player is mostly the building height, which is invisible at that distance, so I've correlated it with the building brightness (as in the pic). \$\endgroup\$ Commented Feb 8, 2012 at 8:55
  • \$\begingroup\$ Btw, when viewed from a distance, I'm using mipmapping (NEAREST_MIPMAP_LINEAR), so there's no aliasing. \$\endgroup\$ Commented Feb 8, 2012 at 8:57

2 Answers 2

3
\$\begingroup\$

There are a handful of possibilities that don't require major changes that might help the fill rate. For example: draw your texture layers front-to-back, use low-bandwidth texture formats. Depending on your bottleneck, you might get some advantage from storing an 8-bit single-channel height map, and rendering that several times with different alpha test thresholds.

However, I would expect that you'd need to do some sort of adaptive rendering. Fully zoomed-out, you would have almost unnoticeable occlusion, so it would make sense to render a single layer (a mipmapped height map). As you zoom in, you'd need to switch to real geometry (using an index buffer to reduce vertex processing load).

Depending on your access to pixel shaders, relief mapping might also be a solution—you would render a single pixel only once, which might alleviate the fill rate.

And if you used an orthographic projection with a constant viewing angle when zoomed out too far for geometry, you could render to a texture and only need to process smaller areas of the screen as the player scrolls around.

\$\endgroup\$
0
0
\$\begingroup\$

First optimization - If your buildings are the same color (as on the picture), can't you use just colors instead of textures?

Second optimization - if you are looking from far away, you can render less layers.

Third optimization - render your buildings from up to bottom. Not one building from up to bottom and then other one, but take highest layer from all building and render this one, then second layer etc.

Fourth: If you are rendering big building (with a lot of layers, so many vertices), wouldn't it be better to render just one cube (8 vertices) instead?

//EDIT: Calsbeek was quicker.

\$\endgroup\$
1
  • \$\begingroup\$ Your first and fourth points are not applicable, because the textures are what is defining the shape of the buildings — there are no vertices except at the boundaries of the city. \$\endgroup\$
    – Kevin Reid
    Commented Feb 8, 2012 at 12:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .