There have been many techniques described in the past to combat r_speeds, yet none quite like this. Before I go into its details, though, I need to cover some basics. One of the more widely used methods to reduce r_speeds is to convert sections of architecture to func_walls (or any other brush based entity for that fact) so as not to break up world brushes. For the remainder of this editorial, I will refer to func_illusionaries, func_walls, or whatever other entity you choose to reduce r_speeds as simply a brush based entity
If you need more clarification on the technique described above, I recommend reading this (Link: index.php?go=polygon_reduction_1)
excellent tutorial on basic techniques to reduce r_speeds. Now what are some of the disadvantages to using the above technique? Well the most obvious one is that entities don't VIS-block. A less apparent disadvantage is that they aren't even figured into the VIS calculations. Even a mapper with little experience soon realizes that the engine draws a lot more than what you can see
. These off-screen
elements are visible if gl_wireframe 2
is enabled in the console. You'll notice that brush based entities are visible more of the time than their world brush counterparts. The engine drawing these off-screen
polygons can be a great detriment to FPS in parallel with r_speeds.Note: If you are using Software rendering, use r_draworder 1 instead of the gl_wireframe command. When r_draworder is set to 1, the rendering order is reversed, so the farthest objects are drawn last, thereby making them visible when they would otherwise be hidden.
The method I'm about to introduce has its limitations, but it will certainly help lower the r_speeds associated with these off-screen
brush-based entities. What we're going to do is manually tell the engine when and when not to draw these off-screen
elements. I'll use a hallway leading into a semi large room example for this. Please refer to the figure below: If you're going to create brush-based entities in the room for the sole purpose of preventing BSP splits, then go ahead and name those entities. Doing so allows them to be targeted later. Furthermore, if the player does not start in this room, then change the brush based entities' fx_modes
and their fx_amounts
. Doing so will render them invisible. (Note: If brushes are completely invisible, then they are not drawn and their polygons won't contribute to the r_speeds)
Now place two env_renders
as shown in the diagram, both targeting the previously mentioned brush-based entities. Env_renders
are used to change the fx_amounts
(among other things) of any targeted object. We'll set one env_render
to change the brush based entities' fx_mode
and its fx_amount
. Set the second env_render
, if you're working with semi transparent brushes), and its fx_amount
if you're working with semi transparent brushes). Doing so will cause this env_render
to render the brush based entities within the room visible.
After naming the env_renders appropriately, create two trigger_multiples
in the hallway, as shown in the figure. Don't name these triggers. You want the player to trigger the events when they walk through these brushes; giving them a name would nullify that effect. The trigger_multiple
that is closest to the room's entrance will need to activate the env_render
that turns the brush based entities within the room visible; so label the trigger's target
field with the name
of the appropriate env_render
. The trigger_multiple
farthest from the room's entrance needs to do the inverse. It should target the env_render
that makes the brush based entities invisible. Finally, make sure to set the delay before reset
value on your trigger_multiples
If it isn't clear what is going on, let me run through the sequence of events. The player will be walking down the hallway towards the large room. At the moment, most of the details of the room are VIS-blocked out of the engine's renderer. Furthermore, the brush-based entities are invisible and thus not being drawn (where normally they would). This allows the mapper to put more detail into the hallway without fear of capping the r_speed limit. As the player approaches the room he walks through the first trigger_multiple and?nothing happens. Nothing is suppose to happen yet so we're still good. As the player walks even closer to the room the VIS-blocked objects within the room may or may not have been drawn yet. This is not up to us, it's up to the engine so it's not as significant. What is significant is that as the player walks through the second trigger_multiple, all the brush-based entities in the room are rendered (just before the player gets there). At this point, all the details of the hallway are behind the players FOV (field of vision) and are not contributing to the r_speeds. Thus, the extra polygons caused by the brush-based entities don't impact the r_speeds as badly at this location, as they would have further down the hallway (where the renderer would have to draw both the details of this large room and of the entire hallway).
Now as the player walks away from the room, he'll eventually hit the first trigger_multiple that will render the brush-based entities invisible, thus reducing the r_speed hit at this further location. The obvious factor is that the placement of these trigger_multiples is vital. The second one needs to be out of the line of sight of any brush based entities--otherwise, the player would see our effect, and we don't want that. That second trigger, however, still needs to be close enough to the entrance to be effective. The first trigger_multiple also needs to be placed intelligently. If it is too far away from the room, then the r_speeds would get too high before the brush based entities were rendered invisible.
As you can see, this method does have its limitations to hallways and corridors. And more importantly, it takes a lot of time and planning to implement this throughout a map. However, the fact is if you wanted to take advantage of this system, you could push the limits of detail and reality in the Half-Life engine even further than before - and isn't that what all good mappers strive to achieve?
This article is intended for advanced mappers. It is assumed that you possess at least a basic understanding of the Half-Life engine and its compile processes. In addition, this technique only works in single player maps - sorry to disappoint you multiplayer mappers.