This chapter is all about visleafs, so sit back, relax and enjoy yourself :P
As written earlier, the hl2 map compile-programs divide the map into area's called visleafs to determine what area's of the map can be seen from where, and thus what brushes and entities need to be drawn when a player is at a certain place. The maths is simple: if a line can be drawn from the players view to a certain brush, the brush needs to be drawn. Using real-time calculations would be very heavy, as their would be 1000's of these brushes to test for visibility, and thus does the opposite of what we want (a fast map). Instead, Valve uses a system to pre-calculate visibility. The vvis-process, the second program that compiles the hl2 maps, does nothing more than trying to draw lines to see what parts of the map can be seen from where. You can imagine that because a player's view can be litterally everywhere, this would seem like a near-endless process. To get around that, we will divide the level into parts, and then check what part can see what other parts. If we then know in what part of our map the player currently is, we will be able to find out what parts of the map he certainly cannot see.
If this still sounds strange to you, here's a step-by-step explanation:
Our test level:
Step 1. Divide the level into area's
To divide the level into chunks, we simply ignore all entities and displacements, and start carving the playing space into convex area's:
This step is done by vbsp, the first of the compile programs. The process is called "portalling", as the planes where two visleafs touch is called a 'portal'. The result is outputted to a portalfile ( [mapname].prt ), which is picked up by vvis, the second program of the compile process. In red marked are the visleafs, blue lines denote portals. As you may notice during compiling, portalling is very fast, usually no more than a few seconds for a huge level.
The reason why entities and displacements are skipped is that entities are considered to be dynamic ( able to move ) and we simply can't make dynamic visleafs if we want to be able to precalculate their visibility. Displacements would create thousands of visleafs on their own, which is why they are ignored aswell ( They were originally also meant to be able to move ).
Step 2. Making the visibility table
Vvis will now draw straight lines from each corner of each portal to all other portals in the map. If all lines between two portals cross brush-geometry, the portals are considered to be invisible to each other. If one of the lines can be drawn without crossing brushes, the portals can see each other. If that is the case, both visleafs ( one on each side of the portal ) are able to see the other pair of visleafs (one on each side of the other portal).
We take the portals:
To see if visleaf 1 can see visleaf 2 we don't have to do anything, as both share a portal (they touch each other directly).
To see if visleaf 1 can see visleaf 3 we will try to connect one of visleaf 1's portals to one of visleaf 3's portals:
As you can see, this is possible, thus visleaf 1 can see visleaf 3.
To see if visleaf 1 can see visleaf 4 we do the same again:
As you can see this isn't possible, all four lines we can make between these portals goes through brush-geometry. Visleaf 1 cannot see visleaf 4.
In short, visleaf 1 can see visleaf 2 and 3, but not 4.
Visleaf 2 can see visleafs 1 and 3 (because they directly touch each other), but what about visleaf 4? We know the portal between 1 and 2 cannot see the portal between 3 and 4, but can the portal between 2 and 3 see the portal between 3 and 4? The answer?
Yes! Visleaf 2 can see all other visleafs in this level!
Our visibility table now looks like this:
- 1 -> 2 visible
- 1 -> 3 visible
- 1 -> 4 not visible
- 2 -> 3 visible
- 2 -> 4 visible
- 3 -> 4 visible
Because visibility is reciprocal, we also know that 4 cannot see 1 etc.
The amount of calculations needed depends not on the amount of visleafs, but on the amount of portals. as you can see, three portals take 3 calculations. With each portal the amount of calculations is increased by the total amount of already existing portals. 1001 portals thus take 1000 calculations more than 1000 portals!
Step 3: using the visibility table
Now that we know what visleafs can see which ones, we can make out what to draw when a player is at a certain visleaf. This is done ingame, realtime. For instance, if the player is in visleaf 1, we don't have to draw visleaf 4:
(green is drawn, red is hidden, hollow boxes are entities).
Note: Brushes only exist in the editor. Ingame, only the brush-sides that make up the brushes exist, but they don't belong to each other anymore. This is why in the above example brush-sides can be hidden while other brush-sides of the same brush are visible.
I hope you can imagine why reducing visleafs can increase compile times (as we need to connect less portals), but can also decrease the framerate of our level. Can you imagine what would happen if the brush north of visleaf 2 was an entity (pretending this wont cause a leak)? In that case the entire level would be drawn, even the parts that are red now, even though the player wouldn't be able to see through the wall... This is a serious waste of power you can use for extra frames per second, or more details in your level! Less visleafs mean a slower map because there is less to hide. Big visleafs are harder to hide than small ones, just as an elephant is easier to spot in the woods than an ant. You some how have to make a compromise: long compile times and a faster map, or shorter compile times and a more lagging map? This isnt very easy, especially since extra visleafs dont HAVE to increase map speed, so you may be compiling useless data, which will in turn make your map slower.
You have to determine when visleafs are uselessly small, and when they are uselessly big. This is not easy. In the next chapter i will tell you how to change the shapes of visleafs, and then a few hints on when and where to do so.
Some things you don't really need to know, but can be really usefull:
- What is rendered also depends on the viewcone of the player. If the player in our level would look to the west, nothing would be rendered behind him (half of visleafs 1, and all of visleafs 2,3 and 4 wouldn't be rendered
- The mapsystem Valve uses ( BSP, Binary space partition ), also hides brush-sides that aren't directed to the player. For instance, in the example level below the blue faces will never be drawn if the player is east of them:
The red brush-sides aren't rendered because they aren't in the player's viewcone (=green, looking eastwards), yellow isn't drawn because that visleaf is considered to be hidden from the player, and blue isn't rendered because the player is looking at those brush-sides 'from behind' ( I'm sure you can imagine the 'front' of these faces being the side facing the west ).
For determining visibility, the vvis process actually uses a third portal (this portal being a portal that could occlude both checked portals, and is acually the portal between a leaf in the playing space and a leaf with CONTENTS_SOLID. What you have read untill now is just a simplification, it gets much more complicated. Because this is just interesting, but not necessairy to know, I will just give you a link to learn more about this concept:
As you can see this links to a site for Quake, which is the mother of BSP (Valve copied the BSP system from quake), and therefore partly of the hl2 engine. Like I already said you shouldn't worry about this technique, the simplified version I explained more than enables you in your optimization process.
|«- Previous Chapter||Next Chapter -»|
© Webdesign Copyright by Kolezan, contents Copyright by Ralph 'zombie@computer' van Hoorn