Graphics Update: Making things go faster by doing less

Discussion in 'Planetary Annihilation General Discussion' started by varrak, September 17, 2014.

  1. varrak

    varrak Official PA

    Messages:
    169
    Likes Received:
    1,237
    So a little while ago @xanoxis asked me about how we do level-of-detail and other optimizations in PA to help with the performance. It's a really good question, and one I decided justified doing one of my technical rambles. So... for those of you who like this stuff, here goes.

    Alright then. So - one of the most important tools in any graphics programmer's toolset is the art of doing less. Not in the sense of being lazy (although I'm pretty good at that, I'd be the first to admit). Rather, in the sense of efficiency.

    When you're playing a game (well, a 3D game), what you see on-screen gives the illusion of you being in a rich 3D virtual world. There's a lot of stuff in front of you. You move forward. More stuff. You turn around. More stuff. It's (usually) persistent stuff - as in you can go back to a place and see the same things that were there before.

    But it's all a lie! (Us graphics programmers lie, as well as being lazy. OK, maybe not...). In most 3D games, if you don't see it on screen, it's not there. Off-camera is a soul-crushingly empty void. (Maybe I'm being a bit dramatic with that description...)

    To draw absolutely everything that's in a scene, in pretty much any game with compelling content, would tax even the most potent gaming system. In PA, you have thousands of units, multiple planets, thousands (or tens of thousands) of lights, particles... you know. Stuff. There's no way we could get interactive frame-rates if we tried to just throw all of that at the GPU every frame.

    Instead, we try and be smart about what we draw. We want to do as little as possible, after all. The less work you do, the less time it takes.

    So every frame, we start with an empty scene. Then we add as little as possible to it.

    For example, if something is behind the camera, we can't see it. So we don't draw it. It's fairly simple to test for that specific situation: since everything in our game has a 3D coordinate in space, you can test the position relative to the camera, and if the "z" component is negative then it's behind you and you can skip it.

    That only cuts down a fraction of stuff though. What about stuff that's outside of our field of view, but still in front of the camera? Or stuff that's too far away?

    To handle all of that, we use a technique called "frustum culling".

    vf.gif

    I stole this image from here: http://www.lighthouse3d.com/tutorials/view-frustum-culling/ - which by the way is a more in-depth tutorial on this technique.

    Anyway, that's a frustum. Effectively, it's the truncated pyramid shape made by taking the screen (your monitor), and stretching it out to some far distance (in our case, around 5,000km in game space... and that far out, that square is really, really big). So you have six sides to this shape, each a "plane" (for the non-math-geeks out there, a flat surface...).

    An object is visible if it's on the inside of all six of these flat surfaces. So, we do a really quick (optimized) check between an object's bounding volume (we use spheres, since it's super-trivial to test a sphere against a plane) and each of the six sides. If we're outside of one of them, the object is invisible and we skip it.

    In PA, we use this for everything you can see in-game. Trees, rocks and other surface features are grouped into clusters (based on a latitude/longitude grid) and the bounding sphere of each cluster is tested and added to the frame's rendering if it's visible. Each particle system calculates it's approximate bounding sphere (each frame), and is ignored if it falls off-camera. Each unit, building, and planet part, the same. Lights - same deal. We don't render a light if it's invisible.

    This technique speeds things up quite a bit. It helps on the GPU (less geometry to process), and on the CPU (fewer state changes, less draw calls). But it's not enough.

    Another trick we do is something called "level of detail". There's whole books on this subject, so I won't try and give a super in-depth description. But to summarize, the concept behind level of detail, or LOD, is this: when something is very far away, we can no longer see fine details. So a 1000 polygon mesh that's 1km away is going to show up as a few pixels, we don't need 1000 polygons.

    In PA, we LOD our features (trees, rocks, so forth) using a system called "impostors". I might have waffled about these a bit before - I forget. But anyway, we take each feature (tree, rock, etc), and render 3 orthogonal views of it into a texture. Then, if the feature is beyond a certain distance threshold, we render 3 flat billboards with that texture instead of the full model. This cuts down our polygon count on most planets by a factor of 2 or 3. It helps.

    We also LOD units, by turning of animation updates if they are too far away, and we stop rendering them completely if they are occluded by their strategic icon. We do some math that figures out how big on-screen the unit would be (in pixels) and if that's less than the icon size - we skip it. This saves us a fair bit of time, too.

    Right now we don't have a more complex LOD system on units, since it's not proven to be a big bottleneck. I might revisit this, though.

    Anyway, that's how we make stuff go faster by doing less. Now, go blow stuff up... :)
  2. Pawz

    Pawz Active Member

    Messages:
    951
    Likes Received:
    161
    Nice update! Pretty standard 3d rendering techniques, but I reckon hiding the mesh entirely if the icon covers it is pretty slick.
  3. zgrssd

    zgrssd Active Member

    Messages:
    658
    Likes Received:
    185
    My math teacher used to say:
    "Mathematicians are lazy." in the sense that the less you write, the less you can make mistakes.
    Programmers are basically just mathematicians, so I started saying "Programmers are lazy too". For the same reasons.

    The same applies to system adminsitrators, doctors, architects ... and just about any other profession on the planet.
  4. squishypon3

    squishypon3 Post Master General

    Messages:
    7,971
    Likes Received:
    4,357
    I remember back playing Halo CE, where LOD would make a wharthog look like a triangle mess when you're far away... Though of course you wouldn't notice, but there were about 10 separate models for each thing in the game, haha. :p
  5. tatsujb

    tatsujb Post Master General

    Messages:
    12,902
    Likes Received:
    5,385
    Yaaaaay! new dev works explanation!
  6. elkanfirst

    elkanfirst Active Member

    Messages:
    216
    Likes Received:
    117
    Haha, here's what I've found: threevirtues.com

    According to Larry Wall(1), the original author of the Perl programming language, there are three great virtues of a programmer; Laziness, Impatience and Hubris

    1. Laziness: The quality that makes you go to great effort to reduce overall energy expenditure. It makes you write labor-saving programs that other people will find useful and document what you wrote so you don't have to answer so many questions about it.
    2. Impatience: The anger you feel when the computer is being lazy. This makes you write programs that don't just react to your needs, but actually anticipate them. Or at least pretend to.
    3. Hubris: The quality that makes you write (and maintain) programs that other people won't want to say bad things about.
    Laziness definitely comes first ;)

    Thanks for the update!
    Gorbles, Terrasque, Nicb1 and 2 others like this.
  7. crizmess

    crizmess Well-Known Member

    Messages:
    434
    Likes Received:
    317
    Nice to hear something about the tech used behind the scenes ;)

    I wonder if you (besides of frustum-culling) use some advanced Open GL methods, like occlusion queries (opengl.org/registry/specs/ARB/occlusion_query.txt) to get even better information about visibility? Or is the overhead of having additional bandwidth usage on the GPU not worth the effort?

    Cheers,
    criz.
  8. Remy561

    Remy561 Post Master General

    Messages:
    1,016
    Likes Received:
    641
    Nice update Varak!! Great work, my framerate has raised a lot the last few builds!! :)
  9. stonewood1612

    stonewood1612 Well-Known Member

    Messages:
    726
    Likes Received:
    417
    I actually understand this one fully. But honestly I knew most of it already that's why. Anyway nice explanation as always varrak! I'm always interested in these.
  10. BulletMagnet

    BulletMagnet Post Master General

    Messages:
    3,263
    Likes Received:
    591
    I like the idea of Imposters. It's a super clever hack that really should get past the human eye without a lot of trouble (and it sounds badass too).
  11. felipec

    felipec Active Member

    Messages:
    465
    Likes Received:
    190
    Very nice! Thanx
  12. websterx01

    websterx01 Post Master General

    Messages:
    1,682
    Likes Received:
    1,063
    I didn't know that. Pretty neat way to decide if you need to render it or not.

    Also, do you guys render the stuff on the opposite side of the planet?
  13. Frederikam

    Frederikam New Member

    Messages:
    9
    Likes Received:
    3
    It's a good idea to discard all the polygons behind the near plane, rather than behind the camera.
    Last edited: September 17, 2014
  14. varrak

    varrak Official PA

    Messages:
    169
    Likes Received:
    1,237
    Yep. That's why we use frustum culling. I was giving that particular example as a simple case to ease those not familiar with graphics techniques into the concepts...

    But I like the way you're thinking... :)
  15. varrak

    varrak Official PA

    Messages:
    169
    Likes Received:
    1,237
    Right now, I am sad to say that we do. It's on my list of things to not do, though. Probably using occlusion culling (as @crizmess mentioned). Although that's an interesting trade-off, since to do occlusion culling you have to do more draw calls to draw the test geometry; since we're CPU bound, it could actually make things worse.

    We used to use a simple sphere occluder and do math to discard things behind the planet, but since you can carve chunks out of the planet with planet smashes, it ended up not winning us much.

    Some other ideas I had which may help are stuff like:
    • Not rendering shadows for the PIP. It's expensive, and really, do they make that much of a difference? Maybe we'd still do them for "Uber" settings, and not for others.
    • Not rendering shadows on the non-focus planet. I doubt many people would notice. Again, turn it on for Uber settings.
    • For lower settings, only render strategic icons in the pip and notification windows...
    ... as you can see. There's a theme. Do less stuff.
  16. drz1

    drz1 Post Master General

    Messages:
    1,257
    Likes Received:
    860
    I think a lot of this makes good sense. The visual perks that no one notices mid game. Good stuff!
    Do you render shadows no matter the zoom level? I wonder if that's something that could go if not important. I mean, you already get rid of trees at a certain zoom, right?
  17. varrak

    varrak Official PA

    Messages:
    169
    Likes Received:
    1,237
    We never completely get rid of trees and stuff. Although we probably should. That's another one to the list ;)
    Remy561 and drz1 like this.
  18. cptconundrum

    cptconundrum Post Master General

    Messages:
    4,186
    Likes Received:
    4,900
    What about a nice little setting for stone-age PCs that turns off all units and only ever renders strat icons? I can imagine some people might want to switch that on half way through a game that ends up getting bigger than they expected. Would it even save much in the way or resources?
  19. varrak

    varrak Official PA

    Messages:
    169
    Likes Received:
    1,237
    I'm not sure how practical that would be. You zoom in close, the icons are really small compared to the units or buildings. Interesting idea though - we'll have to see...
  20. aapl2

    aapl2 Active Member

    Messages:
    260
    Likes Received:
    175
    when will we get the settings to adjust this?

Share This Page