Edit: Normally I label the overly technical posts as being for a target audience, but I did not this time. My bad — this post is really only of interest (and will only make sense) to serious 3-d modelers – the advanced airplane and scenery nerds!
The brightness of specular hilights is out of sync between HDR and non-HDR mode in X-Plane 10.11. This wasn’t intentional – it’s a bug. 10.20 will fix this; specualr hilights will have the brightness you see in non-HDR mode (which we think is more like they were supposed to work*) but the tinting of HDR mode (non-HDR mode was overly red in 10.11).
I get a lot of requests for ‘hardness’ control – that is, the exponent that controls how wide a specular hilight is. We’ll get this feature eventually – it’s too important to ignore. The main delay in having this feature is that X-Plane uses a deferred renderer, so the specular exponent has to be stored in the G-Buffer somewhere, and storage is tight.
For similar reasons, it is very very unlikely that we’ll ever have RGB tinting of specular hilights. Doing so is 3x as expensive in G-Buffer storage, and we need that storage for other features.
* That is, unless we discover that non-HDR mode looks spectacularly bad in some cases, in which case we may have to push things a little more toward how HDR was.
We have received a number of bug reports on the livery system in X-Plane 10, as well as complaints from both users and authors about how the system works. This post describes what I am thinking for liveries; if this proposal seems hair-brained, the comments section would be a good place to counter-propose.
Two notes on UI discussion before we jump into the details:
- We hate check-boxes. If the UI debate is “which is better, UI A or B”, then the answer is pretty much never “let the user pick A or B with a check-box”, because the point of UI is to present the program in a human-friendly manner. Having two different UIs with selection forces the user to become the UI designer, which is inherently harder. So while we don’t have zero check-boxes in our UI, we really try to keep the ‘have it your way’ stuff to a minimum; X-Plane is a product for sophisticated users and if we put in a check-box every time we get a request for one, the product would be absolutely unusable.
- In arguing for UI, describe what you want to do, not how you want to do it. If you describe an implementation but we can’t do the implementation, the discussion is over. If you describe what you want to do, we can find several implementations and pick the best one.
Liveries Now
As of X-Plane 10.11, you can:
- Select your livery when you open a plane using Open Aircraft…
But you cannot:
- Change the livery without reloading the airplane, mid-flight.*
- Select your livery from the Quick Flight dialog box.
- Change your livery quickly (since a plane reload is slow).
- Change which livery the QF dialog box picks for you – it always pick “no livery” (that is, default paint).
These first two bugs go hand-in-hand. Because you have to reload the plane to change liveries, you lose the initialization that Quick Flight may have done for you.
* There is one bug to note: if you go to the open aircraft dialog box, select a different livery and hit cancel, X-Plane will change your livery on the fly but not reload the plane. Some users have noticed this and use it as a back-door way to change livery mid-flight.
For 10.20
For the short term, I am converting the bug in the Open Aircraft dialog box into a feature – the dialog box will have a “change livery and keep flying” button to change your livery on the fly, and the “cancel” button will not unexpectedly change your livery. Thus the functionality of the old “open livery…” v9 functionality will be part of “Open Aircraft.”
This isn’t perfect, but it at least addresses the issues of changing liveries quickly, or changing them while flying, without having to know about and use a hidden UI bug.
For the Future
There are more features we’d like to do in the future:
- Have a dedicated livery-change UI again – perhaps one that ‘floats’ over the main window while you fly, so that you can see the liveries as you click on them. This would be a quicker way to rapidly preview a large number of liveries.
- Remember the last user selected livery in the per-aircraft preferences (along with quick-look keys) so that if you go to open an aircraft and don’t do anything else, we can pick the last livery you used.
- Someday have ‘drill down’ functionality in the Quick Flight window so that you can set more detailed info about your plane (livery, weight and balance, fuel, weapons) and then go back to the main QuickFlight window. This is a long ways off though.
None of this is going to make it into 10.20 – I mention it only to explain where we’re trying to go – the change for 10.20 are designed to not interfere with this future work. The future work is all based on user selected livery choice, with preferences an easy selection.
Livery Choice in Plane-Maker
This finally brings me to livery choice in Plane-Maker. I have always considered this a bit of a weird feature; it is inoperative in 10.20 and we are looking to get rid of it permanently – that is, setting a livery in Plane-Maker has no use in any of the above plans. Our view:
- The first livery you see if you first open a plane for the very first time in QuickFlight will be the default one.
- Preferences should record the users choice of livery, and this should be done entirely from X-Plane. It should not be necessary to open Plane-Maker to change livery preferences, any more than Plane-Maker is needed to change rendering settings or joystick preferences. User customization should be 100% in-X-Plane.
As I said before in the top of this article, if this seems half-baked to you, please describe what you want to do, not how you want to do it. And please understand that when it comes to UI, less is more; we need to identify a small, highly leveragable set of UI options to cover a wide variety of features. We don’t want to have 6 ways to do everything!
This rather odd 747 picture is from a quick test I did to make sure the shadow options in Plane-Maker were working right after beating the shadow code silly with a hammer. The wing objects have been marked “interior only” for shadows, and since we are in an exterior view…the wings don’t cast shadows. 🙂
Now this is a totally silly way to use the feature, but there is a legitimate use: mark as many of your interior objects as “inside shadow only” as possible; for example, in the 747 the interior passenger cabin object can be marked as interior only – it doesn’t cast meaningful shadows on anything outside the airport.
By marking an object as no-shadow in Plane-Maker you save the sim the work of drawing the object, which is good for fps. If your airplane is used for an AI plane, this makes AI plane drawing less expensive.
In fact, you save it the work of drawing it multiple times. X-Plane using a shadowing technique called “cascading shadow maps”. Basically X-Plane renders different parts of the world at different resolutions, so that the closer shadows (that can be seen in more detail on screen) have a higher resolution. The user’s plane ends up being drawn in a lot of these rendering passes, and as a result the cost of high-geometry-count objects in an airplane can be amplified several times over by shadows. So savings in object-shadow count matter!
(Given the choice of turning off shadows in Plane-Maker or via GLOBAL_no_shadow, use Plane-Maker; it stops drawing earlier and thus saves more CPU.)
I have updated the OBJ8 specification with the new X-Plane 10.10 commands. This blog post explains why we added some of these commands.
Pixel-Space Drag Manipulator
The pixel-space drag manipulator is a new axis manipulator whose drag length is measured in screen pixels instead of meters; its drag axes are always screen aligned, but it works both horizontally and vertically.
The goal of this manipulator is to make draggable knobs that:
- Have a good response speed for both slow and fast drags via a non-linear curve and
- Have the same drag sensitivity no matter what camera angle.
The axis manipulator has the problem that it works in 3-d; depending on how you look at the manipulation target (both position and rotation) the sensitivity of the drag can change radically.
Recommendation: use the regular drag-axis manipulator for levers and other physically moving items. Use the pixel-space drag manipulator for drags where the underlying target does not move, like knobs. Use button-type clicks for anything that just toggles – it’s easier on the user.
No Shadows
Three new attributes (GLOBAL_no_shadow, ATTR_no_shadow, and ATTR_shadow) allow you to exclude part or all of your object from shadow casting. Shadows can make certain types of geometry, like grass billboards, look silly; excluding them from shadows fixes artifacts.
Note that ATTR_no_shadow is different from ATTR_shadow_blend..
- ATTR_no_shadow: the geometry simply does not cast a shadow! This is meant to exclude objects like vegetation.
- ATTR_shadow_blend: the geometry does cast a shadow, but only if the alpha is greater than a certain ratio. This is meant to make windows with tint cast shadows correctly.
Recommendation: fix shadowing bugs using ATTR_no_shadow for non-instanced objects, and GLOBAL_no_shadow for instanced objects. Use the Plane-Maker check-box for parts on aircraft.
GLOBAL_cockpit_lit
This attribute lets you have your cake and eat it. In X-Plane 9, ATTR_cockpit gives you alpha blending, but ATTR_cockpit_region gives you correct 3-d lighting. You have to pick one or the other.
In X-Plane 10.10, GLOBAL_cockpit_lit gives you both. It makes ATTR_cockpit use 3-d lighting (while maintaining translucency) and it makes ATTR_cockpit_region respect alpha translucency (while maintaining cockpit lighting).
You can add this attribute to any airplane. This attribute should make it easier for authors to adopt correct 3-d lighting in their airplanes.
Recommendation: use GLOBAL_cockpit_lit on any airplane that uses ATTR_cockpit to change to 3-d lighting for your panel texture. Also see here for more guidance.
At this point the only thing holding up a public beta of 10.10 is, well, me. I am currently working on a set of related aircraft rendering bugs, and as soon as I can get the car off of jacks, we can go beta.
One of my goals or 10.10 is to close out the issues that stop payware authors from releasing final conversions of their aircraft to 10.10. By final, I mean conversions that won’t need any additional future editing. Right now X-Plane 10.05r1 has a few bugs that cause v10 to look different from v9, different depending on rendering settings, or just wrong. I want to fix those problems in a permanent manner so that authors can release aircraft and not worry about having to update.
Here are my goals for 10.10, roughly in priority order:
- Rendering should be consistent from X-Plane 10.10 onward through the rest of the v10 version run.
- Rendering should be consistent between HDR and non-HDR mode. Authors should not have to create two versions of textures where the HDR and non-HDRs offer the same capabilities. (In other words, while you might have to make two textures to bake lights when in non-HDR mode, you shouldn’t have to make two textures to correct for differences in color-correction between the two renderers.)
- Where possible, non-HDR mode should match X-Plane 9.
The switch of priority between item 2 and 3 is a fundamental change in priority from what I originally intended for X-Plane 10.
Originally I thought that the best thing to do would be to keep non-HDR rendering as close to v9 as possible, so that at least content would look correct with HDR off.
My new thinking for 10.10 is that we should aim for consistency between HDR and non-HDR modes. Realistically, an author is going to have to make at least a few adjustments in moving v9 content to v10; better to have the cost of rendering engine changes be borne out in a v9->v10 upgrade than to have every v10 airplane require double authoring to cope with HDR vs. non-HDR differences. In the long term, it’s best to not have v9 haunt v10 like a ghost years after authors are making exclusive v10 content.
Why is HDR Mode So Weird
This begs the question: why is HDR rendering so weird? Why does it look different from non-HDR rendering, and why doesn’t it look the same as v9? What did you guys do?
There are a number of changes to how we render in X-Plane 10, some specific to HDR rendering, and some sim-wide.
- The entire sim now works with a linear lighting equation. Basically when the sim performs lighting calculations on the GPU, it thinks in terms of photons and not colors, which produces more realistic results in most cases. With lots of light sources, linear lighting is absolutely necessary for combining those lights.
- The order of rendering operations is very different between HDR and non-HDR mode, and the formats that they render into (24-bit RGB vs. floating point, etc.) are very different. HDR is fundamentally a two-pass format.
X-Plane maintains two separate rendering paths for HDR vs. non-HDR and they are quite different in both what happens at each stage and when the stages occur.
Fixing some of the authoring bugs has required further changing the HDR pipeline to allow for correct rendering. The up-side of this change in pipeline is that the new one supports better HDR tone mapping and possibly even better fill rate performance. The down-side is that it’s a lot of complex code to touch and it may take a few betas to work out the bugs.
I finally finished up an update to the OBJ8 specification, as well as the forest specification – see here for the documents. These specifications are mostly of interest only to developers who are working on scenery exporters.
The OBJ specification is very thick – here are some of the hilights of what’s new.
Global Lighting
In X-Plane 10, you create global spill lights by attaching a light to an object. (Thus, spill can come from any object-bearing part of the sim – an airplane, custom scenery, etc.)
One way to do this is with the existing named and parameterized lights – these features existed in version 9, but in version 10 there are some spill lights added to the light list.
What may be of more interest to custom authors is the new LIGHT_SPILL_CUSTOM command. This lets you build a completely customized spill light. You control its size, color, shape and direction. You can even optionally run the light through a dataref, giving a plugin custom control of the light.
Draping
In X-Plane 10, an object can contain geometry that is “draped” on the ground – that is, X-plane will subdivide, bend and modify part of your object mesh so it sits perfectly on the ground even if the ground is sloped. ATTR_draped makes this happen.
This feature is a much better alternative to using ATTR_poly_os to make marks on the ground. Draping produces objects with better performance, and the geometry always sits on the ground with no artifacts.
As an added bonus, you can optionally use a second, different texture for the draped part of your object from your regular object. (Internally the draped geometry actually becomes something like a .pol file – this is why it can have its own texture.)
Draped geometry makes it much easier to make airport markings. If you want a parking spot, simply draw it on a quad, make it draped, and drop it into place with WED. Tom uses this heavily in our airport library.
Draped geometry also makes it easier to have ground markings that match the object they come with. For example, if you want a house and the house comes with a driveway texture, you can make the driveway texture a draped quad and when you place the object, the draped driveway is always in the right place.
Global Attributes and Instancing
In X-Plane 10, it is possible to set a few key attributes (blending and shininess, among others) globally for the entire OBJ, rather than using an ATTR_ to change part of the object.
These global attributes make hardware instancing possible. In hardware instancing, X-Plane draws many objects with a single instruction to the CPU. In order for this to happen, X-Plane must be able to draw the entire object without needing CPU intervention mid-object. This means an instanced object has to be free of animation, attributes, and a few other features.
The global attributes let you set things like shininess and still have a single-call draw object, ready for instancing. Alex uses these heavily in the urban autogen, and it really helps performance.
My fear is that global attributes are going to be a source of confusion for authors. When should you use them? How do you add them? This is my thinking:
- Modeling program exporters should allow an author to identify an object as “for instancing” or not.
- Authors should check “for instancing” for any object that is heavily repeated. (A car or a single tree or a static airplane, for example.)
- The modeling program can then try to prefer global attributes for instancing objects but not for regular ones, which should come very close to optimal behavior.
Conditionals
Conditionals are simple logic statements that include or ignore parts of an art file based on the rendering settings. In particular, they let you change an OBJ based on whether HDR is on or shadows are on. For example:
IF GLOBAL_LIGHTING
TEXTURE_LIT my_airplane_hdr_LIT.png
ELSE
TEXTURE_LIT my_airplane_LIT.png
ENDIF
In this example, which LIT texture the OBJ uses will depend on HDR.
Because the conditionals can be used anywhere in the OBJ, you can change any aspect of the OBJ to customize for HDR. You can replace a texture, remove lights, add more geometry, etc.
I don’t know how heavily people will use conditionals, but they give authors the option to make one file tuned for both HDR and non-HDR, shadows and non-shadows.
I think the two most common uses of conditionals will be:
- Providing alternative LIT textures when HDR is on or off. Note that only one texture is ever loaded (when the HDR rendering setting is changed, X-Plane unloads one and reloads the other) so this does not increase VRAM.
- Removing drop shadows that are baked into a model when shadows are on.
That second case would look like:
IF NOT GLOBAL_SHADOWS
ATTR_draped
# This is the shadow geometry
TRIS 300 6
ATTR_no_draped
ENDIF
When global shadowing is turned on, the entire set of draped geometry disappears, removing baked vs. real shaodw conflicts.
This is a screenshot of Javier’s new version of the X-15 for X-Plane 10. In this case I have hacked the rendering engine to show the specular channel* (the alpha channel) of Javier’s normal map as the texture of the airplane. In other words, that is the per pixel shininess that Javier “drew into” the normal map. there isn’t any lighting on the airplane; the bright edges are simply parts of the plane that are completely glossy.
Just look at how gnarly and detailed and full of goo it is! When you look at the plane under normal lighting conditions you simply see the regular texture. But when the sun reflects off of the plane, the reflection is messed up by this complex specularity pattern. The fact that the sun reflections change unpredictably and dynamically is what sells the illusion.
I mention this because normal maps are expensive – they aren’t compressed and can chew up 4 or 16 MB of VRAM easily – they have to be at high resolution to get the subtle bump details. As long as you’re going to have the resolution, make use of it by putting “texture” into the specular channel – it’ll make your materials seem a lot more complex.
X-Plane 10: X-Plane 10 will allow you to use a gray-scale PNG as a specular-only image, for this kind of “texture” at 1/4 of the VRAM cost, in case you don’t need the actual bump mapping.
* 3-d nerd: X-Plane’s terminology is different from what you’d see in a typical 3-d modeler materials editor. What we call “shininess” is the specular level – that is, how bright specular hilights appear to be. In a 3-d editor this is usually an RGB color, but X-Plane only gives you a single level control; the specular hilights take on the tint of the sun instead.
The “shininess ratio” or “specular exponent” you’d see in a 3-d editor isn’t available in X-Plane – it is set to a fixed exponent by the sim. The unconventional names is a historical artifact.
Propsman pointed this one out to me yesterday: apparently Blender tangent-space normal maps run from a value of Z=-1 (no blue) to Z=1 (100% blue). This is not how X-Plane normal maps work; our normals go from Z=0 (no blue) to Z=1 (100% blue).
This difference is easy to miss because X-Plane has to renormalize the normal map as the last step of processing the normal map. This turns a big artifact into a small one. The general effect of using the Blender convention rather than X-Plane’s is that your normal map will look ‘less bumpy’ for fairly extreme amounts of bump.
To fix this, simply remap the colors of your blue channel in PhotoShop or some other image editing program. Basically you’ll want to set what was 50% blue to 0% blue, and keep 100% blue the same. This will extend the lighter half of the blue channel over the entire blue channel.
If you have any blue less than 50% in the image, um, that’s a normal that points backward, and X-Plane doesn’t support that.
X-Plane 9 allows you to categorize objects as being on the plane’s outside, inside, or glass. X-Plane depends on these flags being right for a few things:
- The draw order of the airplane is determined by the object types – glass is drawn last to avoid translucency artifacts.
- Interior light from the plane is only spilled on the “inside” objects.
- Glass objects are excluded from shadow calculations to avoid having opaque windows in the airplane shadow.
It is important that you use these flags as intended; X-Plane 10 depends on this information as well, and X-Plane 10’s global spill and global shadowing algorithms are more sensitive to incorrect categorization of objects than X-Plane 9’s forward renderer.
In particular, you should have glass for the airplane windows in an attached object tagged as type ‘glass’; do not attach your glass to the cockpit object, which cannot be categorized as glass. If you have an old plane with glass in the cockpit, consider cutting the object in half in a 3-d editor and attaching the glass separately.
(You should also use our prop disc animation, rather than use an OBJ for prop discs; the OBJ format doesn’t contain the z-buffer tricks necessary to make the prop look right.)
X-Plane 10 will have rendering options for global illumination and global shadows. This leaves one question: what if the user has these features disabled?
The plan for version 10 is this: the OBJ file format will have some extensions to allow conditional commands based on rendering settings. A few notes on these conditional commands:
- They will only be based on rendering settings.
- They will be evaluated once when the object is loaded. (If rendering settings change, the object will be reloaded.)
The idea is to be able to change which lit texture you use or remove a set of shadow polygons depending on rendering settings.
The conditionals are evaluated once at load time so that the object can be fully optimized based on the particular set of conditionals used. For example, if your drop shadow (with ATTR_poly_os) is fully removed at load time (because global shadows are on) your object now has fewer attributes, which is good for frame-rate.
This is very different from ANIM_hide. The hide animation may or may not hide depending on datarefs; to keep this fast, you cannot “hide” an attribute, only triangles. This means you “pay” for your atttributes no matter what.
The motivation for both designs is this: if the set of attributes in a file never changes (e.g. they are either conditionally removed at file load once, or they are always present regardless of animation) then we can optimize the attributes of an object once knowing how they relate to each other, to create the leanest, meanest OBJ.