BSP Map Optimization: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
mNo edit summary
(Further editing. Gonna be one or two more revisions before this is done properly.)
Line 1: Line 1:
[[BSP]] style game engines require a special set of knowledge, to know how to create levels that will run well in the engine. This article will attempt to explain some of the techniques and methods used to make a level run well in the Source engine. This will cover Visibility optimization, func_details, compile time optimization for VIS, and areaportals.
[[BSP]] style game engines require a special set of knowledge, to know how to create levels that will run well in the engine. This article will attempt to explain some of the techniques and methods used to make a level run well in the Source engine. This will cover Visibility optimization, func_details, compile time optimization for VIS, and areaportals.


===Requisite Knowledge===
Requisite Knowledge - How to make a map that is free of leaks, and be able to compile it and run it in the game engine.
How to make a map that is free of leaks, and be able to compile it and run it in the game engine.


== Theory ==
----
The whole goal of map optimization is to keep the amount rendered to the screen to a minimum. This is accomplished in a BSP engine like Source, through a number of techniques. I'll address the techniques in order of importance.
The first optimization technique is using the visibility tree to full advantage.
The trick here of course is to not draw anything we don't have to, so if you can remove unnecessary triangles from the map, it'll render faster.


==Theory==
The whole goal of map optimization is to not render anything that isn't necessary. This is accomplished in a BSP engine like Source, through a number of techniques. I'll address the techniques in order of importance.


==Examples==
The first optimization technique is using the visibility tree to full advantage. The visibility tree is precalculated in Source during the [[VIS]] step of compile. The tree uses the [[visleafs]] that were generated during the BSP step of compile to precalculate the [[PVS]] of every leaf in the map. The goal in level optimization is to minimize the PVS of each leaf that the player is most likely to be in, to maximize game performance. This is accomplished in practice by using hint brushes to divide leafs so that we can further optimize the PVS. The next step is to analyze the map, and any brushes that don't significantly block the player's visibility, should be removed from [[visibility determination]] by making the detail brushes. [[Func_detail]] brushes, or detail brushes, don't divide the BSP tree.


If you properly optimize your map, your compile times should be significantly shorter than an unoptimized map.


==Exercises==
==Practice==
Compile BSP with the -glview option, and VIS with the -fast option. Turn off Hammer's auto group for this compile. This should hide all the ents and func_details that don't carve up the BSP tree, since we are only interested in the BSP tree, and that is the only thing that affects visibility.
===[[func_detail|Detail Brushes]]===
Load it into glview, and have a look at how it carves things up.
Func_details don't divide the BSP tree, and can't block visibility. Use these for angled brushes, small brushes, and anything that doesn't significantly block the player's view.
Run the engine and have a look at the leafs in the engine, with mat_viewleaf on, and mat_wireframe on. You are specifically looking for the shapes of the leafs, and how everything triangulates.
*If it doesn't contribute to blocking the view somehow, make it an func_detail.
*Anything that's angled, make it a func_detail. BSP hates angled faces. If you can't func_detail it, put a hint brush around it, so it doesn't carve up the tree any more than necessary. That's why you'll see hint brushes in my maps over all angled faces.
* BSP engines love indoor areas.
* Generally visleafs will stretch to the ceiling of the map, which will let them "see" over your buildings, drawing what's on the other side, whether the player can see it or not. Counteract this by using hint brushes parallel to the ground plane, at the roofline of the building.


===[[func_areaportal|Areaportal]]===
*Areaportals have to seal an area to function. If they don't, they'll produce leak errors on compile, and generate a pointfile you can use to find where they aren't sealed.
*Areaportals are more accurate at visibility determination in engine, but they are more costly. Use them wisely.


- This is a neat trick; run this command in your console: <code>bind f1 "incrementvar mat_wireframe 0 3 1"</code> It will let you cycle through the wireframe modes by hitting F1.
===[[HINTs|Hint brushes]]===
Hints are used to divide [[visleafs]]. This is used to
*Don't use any more HINTs than you have to. The more leafs in the map, the slower it will compile. Although this may sound counter-intuitive to the last statement, proper use of hints can speed up your compile times, as visleafs will have smaller PVS.


==Examples==
Func_detail and groups. One func_detail can have multiple brushes.


Firstly. Anything that's rounded, make it a func_detail. BSP hates angled faces. If you can't func_detail it, put a hint brush around it, so it doesn't carve up the tree any more than necessary. That's why you'll see hint brushes in my maps over all angled faces.


BSP engines love indoor areas. That's why level 6 VISes so fast. Since level 5 is outdoor, we have some special tools and tricks for making it run faster, in particular, areaportals and occluders.
==Exercises==
 
Compile your map with the following options: BSP with the -glview option, and VIS with the -fast option. Turn off Hammer's Auto visgroup for this compile. This should hide all the ents and func_details that don't carve up the BSP tree, since we are only interested in the BSP tree, and that is the only thing that affects visibility.
Q re: func_details - Does each individual part have to be a func_detail or can a big assembly of say 4 brushes (the wall destroyed bits) be a func_Detail
Load it into glview, and look at how the compile tools carve up the level.
It can be assemblages
Run the engine and have a look at the leafs in the engine. You are specifically looking for the shapes of the leafs, and how everything triangulates.
If it doesn't contribute to blocking the view somehow, make it an func_detail.
Turn these on:
I'm going to go over areaportals now, cause they're absolutely perfect for level 5
<code>mat_viewleaf 1</code>
 
<code>mat_wireframe 1</code>
Basically, an areaportal is a way of telling the engine, instead of "don't draw what's behind this" it tells the engine "Only draw things you can see through this"
* Note: You can also set <code>mat_wirframe to 2 and 3 for different triangle display modes.
They work with the BSP tree. Basically, you have to 'seal' areas with areaportals, same as you seal the map from the void.
If it's say, a sideroom with only one exit/entrance to the room, you can seal the room off with one areaportal, on that doorway. If it's a more complex structure, like an entire building, you have to seal every opening with an areaportal.


func_areaportals? Are those automatic? I remember using those at some point and they didnt do anything
==Tricks==
Oh, they do something alright
This is useful for viewing how your map is turned into triangles by the compile tools. Remember, less triangles means faster rendering.
I had to manually toggle them with some console commands to make them block stuff
This will let you cycle through wireframe modes by pressing F1.
alright
<code>bind f1 "incrementvar mat_wireframe 0 3 1"</code>
Heh
Well, lemme explain
A func_areaportal is either "open" or "closed". When it's closed, it'll block off everything behind it, period. This is great for some situations, where you have a door you can open and close. When it's opened, it's still doing something. Basically, what it does is this. Everything that's visible through the areaportal's leaf, it'll cull it if you can't draw a ray from the player's viewpoint through it to the object being tested. This works really well for culling model geometry.


To understand why that's better than just straight BSP vising, we have to go into what the leafs are actually doing in regards to VIS
Leafs are generally rectangular prisms. they can be other shapes, but they have to be CSG, though, so they can't be convex
During the vis step of the compile, the engine goes and looks at a leaf. It then goes and says " which leaves can this leaf see?" and it draws rays from every leaf in the map to every other leaf in the map.
If you can draw a ray from the leaf to another leaf, it considers it visible. If you can't, it doesn't draw it when your in that leaf.


I just had to explain this to a kid on the chatbear messageboards. He's got a large building in the middle of the map, and he's wondering why it's drawing what's behind the building, even if the player can't see it
Well, it's visible not because the player can see it, but because the leaf that the player is in can see it
You see, generally the leafs will stretch to the ceiling of the map, so that let's them see over buildings more often than not
This will destroy level 5, if this were the case
Ahh. I take it this is where hints come in handy then?
You got it!
In the case of 5, we're going to lay a hint brush that's parrallel to the ground plane, at the height of the roofs of the buildings
This'll keep the leafs beneath the level of the buildings, so they won't be able to 'see' over them
You see?
Aye, so there aren't loads of leaves above the buildings, just a few.
Yup.
So for each roof level have a hint brush?
Nah, that'd be a mistake
That'd carve up the tree more than we want.
Hmm
What we want to do is try to put one level of hintbrushes, near the top, as high as we can without more leafs seeing over buildings.
This is where "designing with optimization" comes to mind
This is one of the things I intended to show you sooner, so we wouldn't have to go back and fix 5, but this is a learning experience, after all, so mistakes will be made.
Essentially now it's your job to come up with a way to make the roofs of the buildings all high and level enough that we can lay one hint brush over the top of them, and make the vis work for us.
Hmm, 'kay.
Ok. Now I'm going to step back to areaportals for a minute.
So a few things might be able to stick out over it but it should generally all be level with that hintbrush?
Yes.
Oh, sticking out over it is fine. We just don't want buildings *lower* than it
Otherwise, the leafs can see over those buildings
Areaportals help us whenever the player is inside a building. Now, like I said with the leafs, the leafs are calc'd on what they can see. Areaportals are calc'd on what the *player* can see.
So areaportals are more precise than leafs, but that comes at a cost
Ah, gotcha.
We don't want more areaportals than necessary, because that'll cost us in rendering performance also. But You can use quite a few and still be fine.
Here's a trick.
There's a couple of places, like, take the furniture storefront, for instance, where we can use one areaportal to cover several windows.
Ah
Basically, I'd func_detail the doorway and the brushes that're in the middle of the that storefront, and stick one areaportal over that entire opening.
Does that make sense?
Yah
Ok. I'm gonna go copy and edit this and put it up on the wiki, cause I just wrote a whole lot here, haha




==Related Links==
==Related Links==
[[Wikipedia:Binary_space_partitioning]]
*[[Wikipedia:Binary_space_partitioning]]
[[Visibility determination]]
*[[Visibility determination]]
[[Controlling Geometry Visibility and Compile Times]]
*[[Controlling Geometry Visibility and Compile Times]]
[[Visleafs]]
*[[Visleafs]]

Revision as of 17:37, 19 October 2005

BSP style game engines require a special set of knowledge, to know how to create levels that will run well in the engine. This article will attempt to explain some of the techniques and methods used to make a level run well in the Source engine. This will cover Visibility optimization, func_details, compile time optimization for VIS, and areaportals.

Requisite Knowledge - How to make a map that is free of leaks, and be able to compile it and run it in the game engine.


Theory

The whole goal of map optimization is to not render anything that isn't necessary. This is accomplished in a BSP engine like Source, through a number of techniques. I'll address the techniques in order of importance.

The first optimization technique is using the visibility tree to full advantage. The visibility tree is precalculated in Source during the VIS step of compile. The tree uses the visleafs that were generated during the BSP step of compile to precalculate the PVS of every leaf in the map. The goal in level optimization is to minimize the PVS of each leaf that the player is most likely to be in, to maximize game performance. This is accomplished in practice by using hint brushes to divide leafs so that we can further optimize the PVS. The next step is to analyze the map, and any brushes that don't significantly block the player's visibility, should be removed from visibility determination by making the detail brushes. Func_detail brushes, or detail brushes, don't divide the BSP tree.

If you properly optimize your map, your compile times should be significantly shorter than an unoptimized map.

Practice

Detail Brushes

Func_details don't divide the BSP tree, and can't block visibility. Use these for angled brushes, small brushes, and anything that doesn't significantly block the player's view.

  • If it doesn't contribute to blocking the view somehow, make it an func_detail.
  • Anything that's angled, make it a func_detail. BSP hates angled faces. If you can't func_detail it, put a hint brush around it, so it doesn't carve up the tree any more than necessary. That's why you'll see hint brushes in my maps over all angled faces.
  • BSP engines love indoor areas.
  • Generally visleafs will stretch to the ceiling of the map, which will let them "see" over your buildings, drawing what's on the other side, whether the player can see it or not. Counteract this by using hint brushes parallel to the ground plane, at the roofline of the building.

Areaportal

  • Areaportals have to seal an area to function. If they don't, they'll produce leak errors on compile, and generate a pointfile you can use to find where they aren't sealed.
  • Areaportals are more accurate at visibility determination in engine, but they are more costly. Use them wisely.

Hint brushes

Hints are used to divide visleafs. This is used to

  • Don't use any more HINTs than you have to. The more leafs in the map, the slower it will compile. Although this may sound counter-intuitive to the last statement, proper use of hints can speed up your compile times, as visleafs will have smaller PVS.

Examples

Func_detail and groups. One func_detail can have multiple brushes.


Exercises

Compile your map with the following options: BSP with the -glview option, and VIS with the -fast option. Turn off Hammer's Auto visgroup for this compile. This should hide all the ents and func_details that don't carve up the BSP tree, since we are only interested in the BSP tree, and that is the only thing that affects visibility. Load it into glview, and look at how the compile tools carve up the level. Run the engine and have a look at the leafs in the engine. You are specifically looking for the shapes of the leafs, and how everything triangulates. Turn these on:

mat_viewleaf 1
mat_wireframe 1
  • Note: You can also set mat_wirframe to 2 and 3 for different triangle display modes.

Tricks

This is useful for viewing how your map is turned into triangles by the compile tools. Remember, less triangles means faster rendering.

This will let you cycle through wireframe modes by pressing F1.
bind f1 "incrementvar mat_wireframe 0 3 1"



Related Links