Tutorial written by Aavener
Mirrored here for archival purposes
“Exit Visibility Optimization”
First of all let’s clear something up before any confusion may arise. Whenever I refer to the word ‘room’ (quotes included) I am not merely referring to the popular definition of it but a more technical, Max FX oriented one: ‘room’ is a section of a level that has been divided from other sections through exits and which occupies the topmost MaxED hierarchy level. Now that we have that one out of the way, let’s begin.
How it works
Exit placement is basically a matter of taking advantage of limited line of sight. The engine draws anything directly in the field of vision (think of it as a view cone that contains everything that is visible to the player from the his current location/angle) and that is also part of the ‘room’ the player is currently in, no matter if is all actually visible or not (let’s say it doesn’t take into account the presence of walls or any kind of geometry that obstructs the view for instance). Therefore by creating exits the mapper limits whatever is on the field of vision to what’s inside the room and what can seen trough an exit. This works pretty well because it ‘isolates’ a particular section of the level, a ‘room’, and makes sure that the engine is only drawing what is visible through the view frustum (or field of vision) but limited to the current room.
The exit placement idea is definitively a clever one because it allows the developers to establish an area which has a clear line of sight to another ‘room’ (the opening covered by the exit) and therefore the engine can be 100% sure that the player can only see what it’s inside the ‘room’ he is in and what may be visible though the exit. This is the reason why mesh won’t be split by exits unless every single opening between two potential rooms is covered by an exit. If this didn’t happen and you could actually split a mesh even with a missing exit, whenever the player’s field of vision crossed that opening the so called ‘hall of mirrors’ effect would appear. Why? Because the engine wouldn’t draw the portion of the other room that the player should be seeing as there is no exit covering the opening.
This whole exit placement idea works because in situations when there is another area of a level directly on the player’s view frustum but still behind a wall and in another ‘room’, the engine can be certain that the player can’t see it because it knows that area is in another ‘room’.
But for the exit optimization to be usable, you need doorways and narrow places that limit your view. The best spots to place exits are the ones of the level whose architectural features somehow limit the view. The mapper can then take advantage of this and place an exit to avoid whatever is being blocked from the view to be drawn by the engine. I recommend to carefully plan the exit placement when even in the ‘blueprint’ stage so that you can better distribute in an optimal way the potential video card intensive elements such as highly detailed meshes or areas.
Imagine there’s a part of the level (which I will refer as ‘hidden room’ from now on) that’s located behind a wall and therefore the player can’t see. If the player happens to see in the direction of the ‘hidden room’, it will fall into the player’s field of vision. Now, let’s analyze two possible outcomes in terms of what the render might draw (press Caps-Lock in MaxED’s view mode with exit acceleration on to see what’s being rendered at a given time):
Scenario 1: If the hidden area happens to be part of the same ‘room’ as the one the player is in (which means there isn’t any exit between both sections) then the engine will certainly draw it unnecessarily.
Scenario 2: Here’s where the exit visibility optimization feature kicks in. If the ‘hidden area’ is in fact another ‘room’ then the engine will cut it off because it assumes correctly that if it’s in another ‘room’ and the player can’t really see it (which he actually can’t as there is a wall blocking the view).
It is also important to have in mind the engine will still render any portion of another ‘room’ that can be seen through an exit. Take into account it will only draw the particular portion of the ‘room’ on the other side of the exit that the player is able to see
On the other hand if there are no exits, the ‘part’ ( I am calling it ‘part’ and not ‘room’ because there are no exits) of the level on the other side of the doorway will be rendered completely even though the doorway blocks the view considerably
Another concrete example of the difference that can make exit visibility optimization in the game can be seen on the outdoors area that surrounds the Aesir skyscraper (part3_level6.ldb file). This level was made in such a way that the whole outdoors area is part of the same ‘room’ while the Aesir skyscraper and everything it contains make up several other ‘rooms’.
Picture 7 shows the exits (white outlines) that separate them. Now, visualize the player standing outside the Aesir building and staring at it as picture 8 shows.
Because the whole outdoors is actually a single ‘room’, even though the player can’t see what’s on the sides and behind the Aesir building, all that is still being rendered as picture 9 proves.
This happens because the field of vision includes a lot of objects (lampposts, cars, buildings, etc) that are considered to be in the same ‘room’ as the player’s (the outdoors area) and are therefore drawn. The inside of the Aesir, despite being in the view frustum, isn’t rendered because it is a separate ‘room(s)’.
‘Rooms’ also work well within to the game’s structure as a means of organizing the level’s content (which I remind you, usually includes a lot of FSM entities and DO’s) into smaller bits. In addition, the separation of the level into ‘rooms’ allows the mapper to do a partial export or a partial rendering which can be very useful on large, complex levels.
Toggling exits on an off is a very useful feature that is definitively worth to be put in practice. It saves the engine from doing the exit calculation (rendering what the player can see through the exit) because it safely assumes the exit is ‘covered’ somehow (probably with a door).
The whole visibility optimization idea that spawned the exit and ‘rooms’ approach is also very useful when working on MaxED (make sure that you have got exit acceleration turned on). It also speeds up the radiosity rendering process (make sure all meshes are in their respective ‘rooms’ before rendering) because it saves the engine from having to render areas that are not even visible to the player when calculating the lighting solution.
Some may consider exit visibility optimization knowledge a bit too much of theory and too low on the practical side of things. However, in reality, understanding how this stuff works is essential for achieving good, performance-wise level planning and optimal exit placement which in turn has a major effect on the performance of any Max Payne level. Besides, who can deny the appeal of having a better vantage point when looking at the Max FX tech throughout the comprehension of its many features?