[Tutorial] Optimisation - Stairs

Discussion in 'Tutorials & Resources' started by x6herbius, Dec 6, 2009.

  1. x6herbius

    aa x6herbius

    Messages:
    377
    Positive Ratings:
    271
    After recently delving into Valve's mapping world in order to make a L4D campaign out of Half-Life: 2, I've gained some valuable experience. What better time then, I thought, than to write some of the optimisation tutorials I've been thinking about? Some of this is what I've picked up from Valve's maps; some, including this tutorial, are what I've come up with myself. I hope they come in useful. :)

    Stairs
    When making your arbitrary bits-and-pieces for a map, your goal should always be to make the best structure you can while creating the least polys (triangles) you can for the engine to have to render. Before I go any further, I want to make a point which should NEVER be disobeyed, regarding the tools/nodraw texture: whenever you make a new brush, ALWAYS create it with the nodraw texture and then texture the faces you're able to see. This minimises the faces the engine will have to draw, since the ones you'll never see in-game aren't even compiled into the map.

    That aside, we move on to stairs. They can be pesky little things if you don't get them right, and in my experience this is the best way I've found to do it.

    Enclosed Stairs
    These types of stairs are ones that reach completely from one wall of a corridor to the other. You cannot see the sides of them or go underneath them, so the number of faces drawn should be minimal.

    First, choose your size of step. My recommended size is either 8 units high, 12 units deep (the general standard) or 8 units high, 16 deep (which I'm inadvertently used to), and wide enough to go the width of your hallway. Create one step in nodraw, place it at the top of your staircase and then shift-clone it in a stair-like fashion until you reach the floor. Note that you can texture the step before you clone it, but make sure not to have Texture Lock enabled (unless you're using a specially aligned step texture) otherwise your stairs' textures will look strangely identical from in-front, which can ruin the realism a tiny bit. :)

    [​IMG]

    To quicken compile times, we want to get the simplest brush structure possible. A rectangle shape must be split into two triangles, whereas a triangle shape is obviously only one, so select all your steps and cut them at once to leave them just as triangular prisms. This isn't so important for enclosed stairs but is more important for others, as you'll soon see.

    [​IMG]

    Now, tie all your stairs to a func_detail with Ctrl-T. Stairs make masochistical visleaf cuts unless they're func_detail, so don't forget this step.

    [​IMG]

    You may also notice that there's a lot of empty space underneath the stairs. This won't matter as, since the stairs meet each other's edges, the player won't be able to see underneath. Do not fill the space with a brush, even a func_detail one, as it's completely unnecessary. Remember the Tesco motto: “Every little helps”. :)

    Finally, the clip. Ever tried to jump on stairs? Isn't it annoying when you ricochet off them at an angle? Creating a clip brush like so solves this problem while also allowing Engineers to build properly on the stairs. If you have large, tall stairs and want Engies to be able to build on each individual step, make the clip brush a player clip and it won't affect the buildables. Also, don't func_detail the clip as it prevents it from being put into the correct visgroup and clips don't cut visleaves anyway.

    [​IMG]

    Textured, things should look like this:

    [​IMG]

    Open Stairs
    Open stairs are still very simple and are where the stairs don't take up the entire width of a room but cannot be crawled under. They look like this:

    [​IMG]

    Firstly, make the basic slope your stairs will be on. Once again, I'd recommend a 2:3 or 1:2 (rise:run) ratio.

    [​IMG]

    Now, make your top step and cut the oblong into a triangular prism. This will reduce the amount of triangles the engine will have to draw for the end product, as shown below:

    [​IMG]

    This is the main thing people get wrong with stairs: while the right may seem the simplest way to make them, it's by far more taxing on the game engine than the left.

    Now, texture the stairs. You shouldn't end up texturing the base slope's face as it's covered by the rest of the stairs and so is unseen.

    [​IMG]

    Finally, func_detail and add the clip:

    [​IMG]

    If you want, you can add a bit of detail. Firstly, select the entire stairs and press "Apply Current Texture" with nodraw as the texture to get rid of all the previous textures. We will re-texture the stairs at the end.

    Now, shrink the width of the stairs by one unit either side and create another ramp that runs along the full slope of the stairs, like so:

    [​IMG]

    [​IMG]

    Split the ramp and shrink both new ones to become one unit wide. Then, sit them on either side of your stairs.

    [​IMG]

    Delete the triangular ramp underneath, since it can no longer be seen and so is not needed.

    [​IMG]

    Finally, re-texture, func_detail and clip.

    Framework stairs
    These are stairs that can be crawled under, like so.

    [​IMG]

    There are two main types, either with or without gaps.

    Without Gaps
    Follow the Open Stairs method so that you have a base ramp with stairs on top, then delete the base ramp to leave the stairs. If you left them like this, imagine how many unnecessary polys you'd get on the underside:

    [​IMG]

    To combat this, and make the stairs look generally nicer, create a nice brush that follows the slope of the underside of the stairs, like so:

    [​IMG]

    Now, we have two polys underneath with our one rectangular face, instead of loads with our many stairs.

    Shrink the stairs by a unit each side, then add the detail like in the Open Stairs method:

    [​IMG]

    Finally, texture, func_detail and clip.

    [​IMG]

    With Gaps
    Stairs with gaps in-between require a little different setup. Firstly, create the outside guides for your stairs (which you could just clone from having done the Without Gaps method):

    [​IMG]

    Next, put in your stairs. For this example they're one unit high.

    [​IMG]

    Now, texture the rest of your stairs and func_detail them. Make the clip a player clip this time, as a normal clip may stop small objects from being able to drop through the gaps in the stairs.

    With a little practice, Framework Stairs With Gaps can look pretty stylish. Check out the details on these:

    [​IMG]

    [​IMG]

    [​IMG]

    If you'd like to use any of these stairs, the VMF is here: http://www.mediafire.com/?5gwuzmltztt. Note that the frames of some stairs, like grazr said below, should be made func_lod and are not currently in the VMF. I'll reupload once I've fixed them.
     
    • Thanks Thanks x 25
    Last edited: Dec 6, 2009
  2. Chaopsychochick

    Chaopsychochick L4: Comfortable Member

    Messages:
    189
    Positive Ratings:
    91
    Definitely learned some things I hadn't known before. Thank you! ^^
     
  3. A Boojum Snark

    aa A Boojum Snark Toraipoddodezain Mazahabado

    Messages:
    4,769
    Positive Ratings:
    5,531
    Standard ratio is actually 2:3 (8x12 units).
     
  4. grazr

    aa grazr Old Man Mutant Ninja Turtle

    Messages:
    5,436
    Positive Ratings:
    3,564
    func_lod your frame otherwise you may overload your t-junction limit if you have a lot of func_detail work that touches the edges of world geometry or other func_detail geometry.

    [​IMG]

    In this image for example.

    func_detail steps with func_detail frame = 56 func_detail based t-junctions and 4 world geometry t-junctions.

    func_detail steps with func_lod frame = 0 func_detail based t-junctions and 2 world geometry t-junctions.
     
    • Thanks Thanks x 6
    Last edited: Dec 6, 2009
  5. Psy

    aa Psy The Imp Queen

    Messages:
    1,705
    Positive Ratings:
    1,467
    Damn you, Grazr. Beat me to it. :D
     
  6. x6herbius

    aa x6herbius

    Messages:
    377
    Positive Ratings:
    271
    Ah, OK. I only came to 1:2 a long time ago because I was sticking to a grid size of 8 and found that that worked well. I'll update the post.

    OK, I had no idea about T-junctions. I'll update that stuff when I'm back on my own computer.
     
  7. grazr

    aa grazr Old Man Mutant Ninja Turtle

    Messages:
    5,436
    Positive Ratings:
    3,564
    T-junctions

    It's something that becomes an issue in the later development of a map, regarding detail, and it's prime suspects are protruding wall trims and stair cases.

    Luckily for Valve's development team most of their stuff can be converted to models and thus removes this problem altogether. But in other cases, such as badwater, which has excessive use of stairs, Dario Casali simply func_lod's the stair frame's. Quite clever really.
     
  8. x6herbius

    aa x6herbius

    Messages:
    377
    Positive Ratings:
    271
    I see. Ironically, I seem to have learned something I didn't know from one of my own tutorials. :D
     
  9. gamemaster1996

    gamemaster1996 L13: Stunning Member

    Messages:
    1,065
    Positive Ratings:
    131
    I dont think you HAVE to nodraw everything and then texture brushes on faces i just nodraw faces that are not needed it is alot easier.
    But thanks for the info about stairs very useful.
     
  10. x6herbius

    aa x6herbius

    Messages:
    377
    Positive Ratings:
    271
    I've had this debate before. :D

    I'd rather start out with nodraw and then texture/align the faces I need to than start out with a texture, align it and then go back and nodraw all the ones I can't even see. If we're looking at it from an optimisation viewpoint, you'll eliminate 99% of unneeded faces if you start out with nodraw, the only exceptions being if you clip a brush and a random texture gets applied to the new faces, or if you change/add geometry so that a face that was textured gets covered and is unseen. While flush world brush faces (faces that are pressed together) get ignored by BSP, flush func_detail ones, as far as I know, do not, and this is especially important for stairs which are both func_detail and have a lot of faces.

    Sorry about that, lecture over. :D
     
  11. ParanoidDrone

    ParanoidDrone L3: Member

    Messages:
    147
    Positive Ratings:
    10
    I am absolutely in love with that glass staircase. :O

    Good advice all around. Thanks.
     
    • Thanks Thanks x 1
  12. Stormcaller3801

    Stormcaller3801 L5: Dapper Member

    Messages:
    249
    Positive Ratings:
    28
    1) Wouldn't making all of the parts of the stair one func_detail reduce or eliminate the t-junction issue? I've been trying to grab logical groups and then func_detailing them all at once for this reason.

    2) Nodraw vs textures: my feelings on the matter are guided by laziness. How many faces will I have to change later on for each method? The one that requires the least amount of work is the one I'll use for a given situation. Thus my water and displacements start out as nodraw brushes, whereas my open staircases and fence posts get textures.
     
  13. x6herbius

    aa x6herbius

    Messages:
    377
    Positive Ratings:
    271
    Same here, and it's how I did the staircases. I like to keep things all under one func_detail to act as a "group" if I want to clone the thing. I don't tend to use actual groups as much, since I usually tell whether or not something's tied to an entity by whether it selects other brushes when I click it.

    However, I don't think making the whole thing a func_detail would work since it all seems to depend on what vertices touch what surfaces. If they're flush, they get turned into T-Juncts whatever the weather.
     
  14. Tapp

    Tapp L10: Glamorous Member

    Messages:
    776
    Positive Ratings:
    211
    All func_details are un-grouped during compile. This taught me a LOT about optimising stairs, I will make a note to use your tips whenever I can.