X-Plane 10.25r1 will go final soon (this week I think) and will be almost the same as 10.25b3. There is one new feature that I am ‘squeezing’ into the RC at the last minute. Squeezing features into an RC at the last minute is not very good project management discipline, but in this case the feature is simple in its implementation and will allow custom airplane authors to improve framerate a bit.
The feature is “object-kill” – that is, the ability to completely disable (via a dataref) attached objects from being drawn. Even when objects are hidden, they have CPU overhead; this features lets authors determine (in their plugins) which parts of the plane are not needed and completely remove them. That big link explains how to use it and what it does.
How the Killers Kill Objects
X-Plane is, for the most part, not like a first-person shooter or racing game; those games have incredibly detail-rich environments, but they also have players that (mostly) stay on the ground, and environments with a lot of near objects blocking far views. By comparison, with X-Plane, once you take off and climb to about 300 feet AGL, you can see nearly everything around you.
For this reason, X-Plane takes a fairly different strategy than shooters when it comes to figuring out which objects to draw, and which not to draw.
- X-Plane only eliminates objects that are off-screen (behind you, off to the side), too far away, or too small due to distance.
- First person shooting games try to eliminate objects that are occluded by nearby scenery. (They also eliminate the off-screen and too-small objects.) Here are two Wikipedia articles on the basic techniques.*
We don’t try to eliminate occluded objects because the cost of searching for them would hurt fps at all times; since a lot of the time almost no objects will be occluded, we skip the step, saving overhead.
First person shooters often pre-compute “hint” information to determine which objects can be hidden. This is not possible for X-Plane because the loaded scenery may be a mix of several scenery packs; while we could pre-compute occlusion information for the global scenery, custom scenery might eliminate the occluders (using exclusion zones), rendering our pre-computed information wrong.
But there is one environment where X-Plane looks a lot more like a first person shooter: inside the virtual cockpit. The VC is an environment where there is a ton of detail at high density and a lot of occlusion.
Here’s the problem: first person shooters often set up culling data ahead of time in their modeling environments; the engine only evaluates the precomputed hints. But airplane scan be modeled in any number of programs: Blender 2.49, Blender 2.6, 3DS, ac3d, or any program that can create 3-d.
Therefore the intention of object-kill is to let authors do their own culling and simply tell X-Plane (via datarefs) the result. These techniques could be portal-style occlusion techniques, computed automatically, or simple rules coded in a script.
The X-Plane 3-d cockpit camera is a completely free camera – you can walk out of the cockpit, through the cabin, out the door, and go look under your wings. I think that this kind of ‘freedom to roam’ adds a nice element of ‘playability’ to X-Plane, but it also comes at a performance cost. We do not provide separate “interior/exterior” objects – every object is drawn in both the interior and exterior views, because the views are fluid. You can always look in the window from an exterior view, and you can always walk outside from an interior view.
If you need distinct inside/outside views to improve performance, you can use object-kill to implement this feature. Simply write datarefs to determine when the view is ‘inside’ or ‘outside’ and wire up each object with a dataref to kill it. Kill your interior views in exterior views and vice versa.
(See below for more subtle ways to optimize objects.)
How Would I Use This Feature?
I am not an aircraft author, so that’s a highly theoretical question, but here is how I would use this feature:
- I would wire each object up to its own custom dataref and turn each one off in DataRefEditor. For each object, I would note the change in CPU and GPU usage. From this I can determine which objects are actually expensive.
- For each object that is expensive, I would look at my model, and develop simple rules for when I can avoid drawing them.
- I would code some ‘predicates’ – that is, functions that tell me about the state of my objects. The idea of predicates is to summarize a set of conditions in question form.
- I would then code these rules into simple plugin-based datarefs to hide the objects at the right times.
Here are some of the predicates I would look at:
- Is the camera in the cockpit? (This requires looking at the XYZ of the pilot’s head position and comparing it to a box I determine from my model, as well as the current view mode.)
- Can the pilot see backward? (This requires looking at the pilot’s head horizontal rotation.)
- Is the cabin of the airplane visible? (E.g. for planes with a cockpit door, is that door closed?)
Then I can easily write rules like:
- “if the camera is in cockpit and (the pilot cannot see backward or the cabin is not visible) kill interior cabin.”
- “if the pilot is in the cockpit and the pilot cannot see backward, kill the entire external model.”
- “if the pilot is in the cockpit, kill any details underneath the aircraft (gear, gear door, baggage doors, etc.).”
Two last thoughts on performance tuning by removing objects:
- It make sense to spend more time tuning performance on the views that matter most. Note that the above rules are all for the virtual cockpit. The virtual cockpit is where users will spend most of their time in the plane, including hand-flying it, so performance matters.
- You need the most fps gains on the views that are slowest. So if the virtual cockpit is slower than external views (which it almost always is) it makes sense to do more work to optimize the virtual cockpit.
* I wrote some very simple anti-portal culling code for X-Plane in an attempt to measure what kind of performance gains we might get. The conclusion: not much.
The problem is that X-Plane heavily groups objects into large clusters so that it can submit them via hardware instancing. When a lot of objects are visible, this optimization makes a big difference in performance – it can be a 10x improvement in speed. But the large groups also mean that, at any given time, at least some part of a cluster is on screen, even when portals are used.
When I turned off the grouping, portal culling cut the object load in half (after some hacking the engine). That’s a big win, but the grouping gives us 10x the object budget, so we hurt object performance by 10x, and then improved it by 2x – not a win in the end.