The code that decides what parts of the plane get drawn in what views is, to put it midly, byzantine. The code evolved, and in this process became more complex and convoluted.
One of the side effects was a series of bugs that couldn’t easily be fixed – typically it was a case where some new piece of code had to do some drawing, but the decisions on how to draw were being made by legacy code that had no business making those decisions.
So for beta 6 I rewrote that code.
Here’s what this means: if your airplane starts showing the wrong “stuff” in various views in beta 6, please send me the plane, and a description of what it does in 922 and 930b6.
The risk is that I may have missed some of the quirkier behaviors that 922 was capable of. My goal is to have 922’s behavior, but with clean code. So if things changed, please let me know!
X-Plane 930 beta 4 will be out real soon, and it has a somewhat significant new instrument feature: all instruments (not just generic instruments) can have additive lighting.
But wait – what is additive lighting? Additive lighting is the basic equation X-Plane uses for “lit” stuff. Basically it says that the _LIT texture is added to the daytime texture to simulate the effect of an object that reflects sun light and emits its own light. Here’s a more detailed
It used to be that the _LIT textures for instrument overlays were used instead of the daytime ones at night. Generic instruments introduced a new lighting mode, “back-lit”, where the LIT texture is added to the daytime texture. This lets you make an instrument that has a light behind it to illuminate the markings at night.
In particular, when an instrument is back-lit, the amount of LIT texture added in is a function of the instrument light levels (the pilot can turn this up and down) while the amount of day time texture is a function of the sun and spot light shining on the area.
Originally I did not want to extend the legacy instruments to support back-lit lighting. What finally made me change my mind was the amount of detail in some of the standard mechanical instruments. As an exercise, I converted the six pack and nav instruments of Max’s default Cessna to generic instruments.
The conversion required a lot of new (and very weird) datarefs, some esoteric extensions to the generic needle instrument, and it lacked some of the finesse of Austin’s built-in instruments. All of these problems stem from one limitation: the animation action of generic instruments cannot be nested.
(Of course there is a practical consideration too – for an author with legacy instruments, rebuilding with generics takes time. Typically it took about 4-6 generics to model each built-in instrument in the six pack. The conversion only took me about eight hours, but I have access to the source code of the built-in instruments, a luxury authors would not be able to leverage.)
So in the long term, I am at least investigating the notion of nested animations and movements for generic instruments; I think that this would be the final flexibility needed to model just about anything with generic instruments.
But for the short term, you can back-light your built-in instruments; just set the lighting mode to “additive” and create the LIT textures.
A number of users have commented that the X-Plane 930 betas looks “shinier” than before. There are actually two separate features going on :
- Separate specular hilights. Specular hilights are bright areas on the plane that simualte the refelction of the sun on a shiny surface. X-Plane has had specular hilights for a while (available by the “shiny” check-box in Plane-Maker or ATTR_shiny_rat for an OBJ). What’s new is: while previously the hilights were modulated by a texture, they are now independent of the texture. This change means that even a black surface can look shiny now. Before the black surface would “tint” the hilight black, making it invisible. Now we can have a white hilight on a black surface for a glossy look.
- Per-pixel lighting (when shaders are on). Before the lighting calculations were performed on each vertex on a model, then the color from the lighting was interpolated. The problem with this is that if there is a very local lighting effect (like a specular hilight) that is smaller than one triangle, you can’t see it (since we can only see the lighting at far apart vertices). With 930, the lighting calculations are done per pixel, making the lighting effects look smoother.
Here we have the default 747, as of 922. It’s a little bit tricky to tell what’s going on because the texture has been painted to look like there are lighting effects. But the white “specular hilights” on the engine nacelles are due to the sun position. Lighting is per-vertex and specular hilights are not separate.
Next we have the same plane in 930 without shaders:
Note the increased brightness on the nacelles and fuselage. What’s happening is the hilights are no longer modulated by the texture, so they show up a bit more.
Finally, the plane in 930 with shaders. Now the hilights look smoother and much brighter. This is because the hilights are calculated on a per-pixel basis. Note how the hilights are small – smaller than the triangle size on the engines. We didn’t get the full “glare” effect before because the brightest part of the hilight did not land on a vertex at all, and was thus never seen.
Note that the change in specular hilight handling (moving to separate specular hilights) is a bit of a compatibility break. Previously authors could count on not having specular hilights on dark parts of a plane, even if they set the plane to be shiny.
I am not sure how we will ship the final version of 930. I have received very few (none, to be exact) complaints about dark surfaces appearing “too shiny”, and a lot of users like the new shiny look.
The alternative to the current scheme (specular hilights are separate by default) is to have this be a selectable feature. Older planes would look the same as they always did, but planes would have to be modified to make them look truly shiny.
It is true that in X-Plane 922, some programmer dialed down the effective range of VORs.
That programmer was me. (This is what happens when you let a non-pilot go poking at the nav code.)
The bug report was that a rather far away VOR could be received on the ground at KSFO; looking at the actual service volume, the notion that this could happen was crazy. I ended up tuning the distance calculation and also the “fudge factor”. The fudge factor is the increase in the service volume of VORs in the sim from the listed usable service volume (which is really more like a guaranteed minimum) that lives in the nav.dat file.
Here’s the real problem: VOR range has a lot to do with altitude, but X-Plane does not simulate shaped 3-d service volumes. I think we will, but probably not for 930. So for now we have to pick a fudge factor that is large enough to make IFR navigation work without allowing you to receive any VOR from any location.
Beta 3 is still a bit short for VOR range – beta 4 or 5 may improve things a bit.
Note that it is possible to change the service volume of navaids in the nav.dat file. For example, KBOS and KLAX both have extended localizers; the fudge factor for a localizer doesn’t have to be 5x to allow KLAX to have a 100 nm final; the nav.dat entry for KLAX includes this special case.
930 will have some new options for attached objects. One is to declare a “glass” object. When an object is declared to be glass, it is moved to the very end of the drawing order – even after the cockpit object.
The idea of glass objects is to let you make translucency that works from any view angle. To make multiple layers of glass, the trick is to use pairs of one-sided triangles. The glass (visible from the inside only) goes first, then the glass (visible only from the outside) goes second. All of this goes into the object with the “glass” property in Plane-Maker.
One side benefit of the two-triangle approach is that the inside and outside of the windows can be tinted differently.
Having glass objects does three things for us architecturally:
- It takes pressure off the interior cockpit object. The interior cockpit is the only object that can have manipulators, so texture space in the interior cockpit object is quite valuable. By allowing translucency in an attached object, you can put your window textures somewhere else and save texture space for the cockpit object.
- It gets around the current weirdness where the interior cockpit object is drawn last but the exterior cockpit object is drawn first. The glass object is always drawn last. Period.
- It sets us up someday for some kind of shadowing scheme in the cockpit. This is a bit pie in the sky, but most pixel-based shadowing algorithms go a bit bonkers on translucent geometry; by flagging the whole object as “glass” we can simply omit it from shadow calculations.
The 921 draw order has the exterior cockpit object drawn first (if drawn) and the interior cockpit object drawn last (if drawn). This made sense at the time – the exterior cockpit object was being used primarily for a pilot figure, with windows in the ACF paint – so it had to be drawn before the ACF fuselage. The interior cockpit object has to be drawn last because the coordinate system is changed to a super-close-to-the-user coordinate system that has to be drawn last.
Now that there are attached objects, people are modeling a lot more of the airplane, the usual approach is to have all 3-d present all the time, so that a roaming camera won’t reveal missing parts of the airplane.
As of X-Plane 9, life was simple: ATTR_cockpit and ATTR_cockpit_region caused your triangles to be textured by the panel, and they could be clicked. ATTR_no_cockpit went back to regular texture and no clicking.
Well, it turns out that secretly ATTR_cockpit was two attributes jammed into one:
- Panel texture – that is, changing the texture from the object texture to the panel texture.
- Panel clickability – that is, mouse clicks are sent to the 2-d panel and act on those instruments.
With X-Plane 920 and the manipulator commands, this “clickability” aspect is revealed as a separate attribute, e.g. ATTR_manip_none sets no clickability, and ATTR_manip_command makes a command be run when the triangle is clicked. These attributes can be applied to any kind of texture – panel texture or object texture.
So how does ATTR_cockpit work in this context? Basically you can think of ATTR_cockpit as two “hidden” attributes:
and similarly, ATTR_no_cockpit is like
With this you can actually get any number of combinations of attributes, but the code is sometimes unexpected. In particular: if you want a manipulator other than the panel or none, you have to specify it again. Example:
# set command manip
ATTR_manip_command hand sim/operation/pause Pause
TRIS 0 3
# we now have to reset the cmd manipulator!
ATTR_manip_command hand sim/operation/pause Pause
TRIS 3 3
# we have to reset the cmd manipulator again!
ATTR_manip_command hand sim/operation/pause Pause
TRIS 6 3
Similarly, if you want the panel manipulator, you may have to reset the cockpit!
TRIS 0 3
# now make the mesh not clickable
TRIS 3 3
# Mesh clickable again
TRIS 6 3
The good news is: this isn’t nearly as wasteful as it seems. X-Plane’s object attribute optimizer is smart enough that it will remove the unnecessary attributes in both cases. In the first one, what you end up with is one manipulator change (to the command manipulator), and the panel texture change is done without changing manipulator state at all. In the second case, you end up with the manipulator change, but the panel texture is kept loaded the whole time.
In other words, even though the double-attributes or duplicate attrbibutes might seem to be inefficient, the optimizer will fix them for you.
One reason you might care: the cost of panel texture is one-time – that is, you pay for the size of the panel texture once per frame. But the cost of manipulatable triangles is per-triangle! So having more is bad. With ATTR_manip_none, you can use the panel texture but not have it be clickable, which can be a big performance win.
930 will handle manipulatable triangles a lot faster than 920 — but that’s still not a good reason to have all of your triangles be clickable!
This article is still unfinished
, but I am trying to put together some info on how to detect performance problems like too many clickable triangles.
There are two ways to make 3-d instruments in your 3-d cockpit:
- Create 2-d instruments on a panel and use the “panel texture” (ATTR_cockpit or ATTR_cockpit_region in your OBJ) to show those 2-d instruments in the 3-d cockpit.
- Model the instruments in 3-d using animation.
So…which gives better framerate? Well, it turns out that they are actually almost the same…a few details:
- If your card can’t directly render-to-texture, there is an extra step for the panel texture. But that would be a weird case – all modern cards can render directly to textures unless you have hosed drivers.
- For very small amounts of geometry, there’s pretty much no difference between rotating a needle using the CPU and telling the GPU to do it by changing the coordinate system.
- The panel texture does put pressure on VRAM – if you’ve had to go to a 2048×2048 panel texture to have enough space, it’s going to hurt you.
Both approaches are actually quite inefficient – you get best vertex throughput on the card when you have at least 100 vertices per batch. But if a panel has 800 batches, you don’t necessarily want to do this – you’d pick up 80,000 vertices just trying to “utilize” the graphics card. That’s not a huge number, but it’s big enough to consider. Panels have enough moving parts that they’re going to push the CPU more than the GPU.
A number of authors like the 3-d approach because they are more comfortable with 3-d tools, and because it can look sharper (since there is no intermediate limiting texture resolution).
There is only one case where I would advise against the 3-d approach: if it takes a huge number of animation commands to accomplish what can be done in one generic, use the panel texture; the generic instruments are all coded cleanly and none of them take that much CPU power. But some of them produce effects that would be relatively difficult to reproduce with animation.
Sometimes you have to break a few eggs to make an omlette. Or at least, you have to consider whether breaking them is acceptable. Often I hit cases where the cost of supporting a legacy feature is somewhat painful.
One way to decide what to do is to change the feature early in beta, see who squawks, and then change it back if necessary. There are two I am looking at for 930.
It turns out that glass instruments fade to black, not to transparency. This is a little bit weird, because that means they will leave black footprints if they are on top of a non-black background. My guess is that most people use them on black screens and thus did not notice.
If people really need fade-to-black glass instruments, I’ll just create a new lighting type (glass-transparent), but if everyone can live with fading to transparent, it’s certainly the more useful case and probably what most people always wanted.
Separate Specular Hilights
For as long as I’ve been involved, X-Plane’s specular hilights are modulated by the object or airplane texture color. In other words, if you paint your airplane red, you get red hilights, and if you paint it black, you get no hilights at all.
This is not a very good way to do things for a few reasons:
- Under this scheme, you can’t make a shiny black object.
- Someday we will add gloss maps – but the glossy part of the gloss map will be defeated by the black texture.
So for 930, I am looking at not modulating specular hilights by texture. (This is called “separate specular hilights” in OpenGL lingo.) My guess is that they will look enough better in almost every case that people would rather have it this way.
Should specular hilights be white for a black object? Yes! A specular hilight is a simulated intense reflection from a very far away, very bright object (the sun). So it should take its color from the sun, not the object itself. To this end, I have also (finally) set the specular hilights to take on the daylight sun color, so that they get fainter and yellowish at dusk. This makes dusk and dawn look a little bit less strange.
(Nerd note: Technically, for the day texture to be an albedo texture, it shouldn’t affect specular hilights.)
Microsoft extended Windows XP sales yet again, more or less. But rather than rant about how the Vista user experience makes me want to tear my fingernails off or how brain-damaged it is to try to put DRM into drivers, let me instead focus on Windows as an example of the cost of contracts.
I have ranted in the past
about how the boundary between X-Plane and a third party, or the plugin system and third parties, or even two third parties, is a contract. Consider:
- The named light list forms a contract between X-Plane and objects, e.g. X-Plane guarantees that there will be a named light called “airplane_landing” and that it is a good choice for landing lights. (This implies that X-Plane won’t change what it looks like to be inappropriate for landing lights, and that third parties won’t use it for inappropriate uses, like airport apron lights.)
- XPLMGetDataf forms a contract between the plugin SDK and plugins, guaranteeing that there will be a function in the XPLM called “XPLMGetDataf” that takes a dataref and returns its value. (This implies that Sandy and I won’t rename it or change its arguments or remove it all together, and that plugins won’t pass non-datarefs in as arguments.)
- Even a paint kit forms a contract – the airplane maker is essentially saying “the tail will be mapped to the upper left of the texture, and I won’t remap my UV” and the livery maker is saying “I will put an image in the upper left corner that looks like a tail.”
By comparison, the clouds are not a contract – there is no way third parties can customize the look of the clouds, so we can change the algorithm by which we create them pretty much at will. We could switch to a volumetric approach for all clouds or even go back to 2-d without worrying about third party interaction.
Okay – that’s a lot of words about contracts…what does that have to do with Vista? Well…
The Cost of Changing the Contract
Two major aspects of why Vista has been a worse experience for users than Windows XP come directly to the need for Microsoft to change contracts.
- For years, applications have run on Windows with admin rights. This is not good – it means that any process can do serious damage to the system if hijacked – and on Windows processes get hijacked on a fairly regular basis!
- For years, audio and video drivers have run pretty much unprotected. This was good from a performance perspective, but also caused a lot of BSODs. On Windows, drivers are third party components and are quite possibly not checked by Microsoft (especially video drivers) so letting them run without protections is risky.
In both cases, the problem is that the old contract is both (1) poorly designed* and (2) being used by a lot of third parties. What choice did Microsoft have? Continue to let apps run in admin mode and hijack the whole machine any time the user picked up a virus? Or change apps to run in user mode and hope that the applications didn’t depend on this guarantee?
(At this point, Raymond
might go ballistic and point out that the Windows API doesn’t really promise admin rights and apps should not have been doing all of these naughty behaviors in the first place. I don’t know what the Win32 API declares…the difference between what a platform declares and what it does is important enough to warrant another post. Certainly with X-Plane we have to worry a lot about third parties depending on behavior that was unintentional but turned out to be useful.)
Vista has been a difficult transition because it changed a bunch of rules (that needed to be changed). In the long term, I am sure that both of these decisions are for the better — eventually applications won’t be counting on administrator rights, so we won’t have to fume about UAC (or shut it off), and a hijacked web browser won’t be nearly as dangerous.
On the video driver front, the Vista experience is pretty reasonable now – there has been a lot of improvement since Vista first came out. I expect applications and UAC to take a lot longer – video drivers get revised quite frequently; applications seem to linger around forever.
I’m Not Signing That
If we end up with a situation like this in X-Plane (the contract is used heavily by third parties and not well designed) we only have two options, and they’re both bad:
- Break the contract. Third party content stops working, users are angry, authors are angry.
- Stick with the contract and mitigate as best we can. Usually this means writing more code (slows down new features), using a less optimal implementation (lowers frame rate), etc.
This is why my first reaction to any file format extension is: “is this going to be a PITA in a year”? The benefit might be visible now, but the cost could plague us indefinitely.
What You Want, Not Where You Want It
If you would like to request a feature, tell me what you want, not where you want it implemented. I bring this up because many of the feature requests I get are very specific and describe an implementation, not a goal. (To draw an analogy, it’s as if I call a general contractor and say “dig a big hole right here” without telling him “it is for a swimming pool”.)
The reason “what not how” is so important is because many of the “how” implementations that people send me involve creating new contracts with third parties. I am going to try to design the feature with the minimum contractual obligations – that is, to do just what is intended and hopefully not much more.
But if I can’t tell what you are trying to do, I can only say “I won’t code this implementation – the cost of long term support due to contractual obligations outweighs the usefulness.” It might be that there is another way to implement the feature that would not put a long term burden on the scenery system or airplane SDK and still provide all of the benefits.
* Poorly designed? Or perhaps well designed for a previous problem – if the problem changes, the design might not be appropriate. Or perhaps not even designed at all – sometimes contracts evolve without a lot of central planning. All of these things have happened in X-Plane. In the case of Windows, I suspect it’s the previous-problem case — that is, what made sense for much smaller computers where the scope of what could be done was quite limited no longer makes sense for big modern computers that are capable of a more expensive and robust solution…just my speculation.
You might not believe this (due to the general lack of scenery system documentation) but I do spend some brain power thinking about X-Plane documentation for third parties!
Consider two approaches to documentation:
My question is: which of these approaches is more “readable” or “clear” to you as a third party? Each one (the formal website vs. the Wiki) has pros and cons, but I can’t judge “usability” of the documentation myself. Is it easier to find things on the website? On the Wiki? Comments welcome!
(I need to decide where to put future documentation, hence the question “which works better for those who read the documentation.)