Category: Aircraft & Modeling

SASL Crash Fixed – You’ll Need a New SASL

Since El Capitan came out, SASL has been crashing on quit when used in aircraft with customized sound. While I work on neither SASL nor El Capitan, both are (at least partly) open source, so I spent a few hours yesterday and located the bugs.

The good news is: this bug is fixed in SASL version 2.4. The bad news is: you’ll need to make sure the aircraft you are flying is using SASL 2.4 – and this applies to every aircraft that you have that uses SASL.

If you develop an aircraft using SASL, you can get the latest free version of SASL here. Note that this new version is apparently 64-bit only.

If you are using a freeware aircraft that is no longer supported, I think you could theoretically drop in the new SASL and see if it fixes things. If the aircraft is payware, the aircraft author might not be thrilled to have to support a “modified” aircraft and might prefer to do the upgrade in-house.

If you are a developer of SASL or you use OpenAL, you can read the gory technical details here.

Posted in Aircraft, Development, News by | 9 Comments

Performance Analysis by Subtraction

In a previous post I discussed a new facility in X-Plane 10.25r1 (coming real soon) to disable aircraft-attached objects for performance optimization.  There is a second use for this feature: performance analysis.

This post is targeted at aircraft authors, particularly authors who create complex aircraft with Lua scripts or plugins.

The basic idea here is to remove work from X-Plane and measure the improvement in performance.  I strongly recommend you look at X-Plane’s framerate in milliseconds.  An improvement of 1 frame per second is a big improvement at 15 fps and almost nothing at 60 fps.  But saving 5 ms is always a good thing, no matter what framerate.

The GPU Is Confusing

Your graphics card is basically a second computer, with its own memory, its own bus, and its own CPU (in this case called a GPU).  Ideally the CPU on your computer and GPU on your graphics card are both working at the same time, in parallel, to present each frame of X-Plane.

OpenGL drivers accomplish this by building a “todo” list for the GPU, which the GPU then does on its own time.  Ideally the CPU is off computing flight models and running plugins while the GPU is still filling in mountain pixel shaders on screen.

For any given frame, however, one of the CPU or GPU will have more work than the other, and the other will be idle some of the time.

  • If you have a lot of GPU work (e.g. 4x SSAA HDR with clouds on a huge screen) and not much CPU work (e.g. no autogen) then the CPU will have to wait.  It will give all of its instructions to the GPU for a frame, then the next one, then the next one and eventually the GPU will go “stop!  I’m not done with the frames you gave me” and the CPU will wait.
  • If you have a lot of CPU work (e.g. lots of objects and shadows and plugins) but not much GPU work (e.g. a small screen without HDR on a powerful graphics card) the GPU will wait; it will finish its entire todo list and then go “uh, now what?”.  Until the CPU can get more instructions ready, the GPU is idle.

Here’s the key point: your framerate is determined by the processor that is not idle.  If your GPU is idle and your CPU is not, you are “CPU bound”; if your CPU is idle and your GPU is not, you are GPU bound.  Optimizing the use of the processor that is idle will not improve framerate at all.

Viewing Specific Processor Load in X-Plane

X-Plane’s “frame rate” data output gives you two useful numbers for figuring out where X-Plane is spending its time:

  • “frame time” gives you the total time to draw one frame, in milliseconds.
  • CPU load give you the fraction of that frame time that the CPU was busy.

For example, my copy of X-Plane is showing 9 ms frame time and .78 CPU load.  That means that the GPU needs 9 ms to draw the frame, but the CPU needs 7 ms to draw the frame – I am GPU bound. (I am also in the middle of the ocean, hence the low numbers.)

Unfortunately if you are CPU bound (CPU load > 0.95 or so) there is no current display for the GPU’s utilization; we are working on that for X-Plane 10.30.

Analyze Performance By Subtraction

Putting it all together:

  • You can calculate the actual CPU time spent in your add-on from the CPU load and frame time data outputs.
  • You can disable your add-on to see how much CPU time is now used; the difference is the CPU time your add-on is consuming.
  • You can change settings to be GPU bound (and confirm that by seeing CPU load < 0.95).  Once you are GPU bound, improvements in framerate when you turn off your add-on show the amount of time you used the GPU for.

Armed with this knowledge, you can find the real cost in milliseconds of GPU and CPU time of the various parts of your add-on.  You can find out what costs a lot (the panel? The 3-d? The systems modeling) and then focus your optimizations in places where they will matter.

Support Performance Analysis in Your Add-Ons

In order to tell what part of you add-on is consuming CPU and GPU time, you need to be able to separate your add-on into its sub-components and disable each one.

If your add-on makes heavy use of plugin code or scripts, I recommend putting in datarefs that turn off entire sub-sections of processing.  Good choices might be:

  • Bypassing custom drawing of glass displays in an aircraft.
  • Bypassing per-frame systems calculations.
  • Bypassing per-frame audio code, or shutting off the entire audio subsystem.
  • Turning off any 2-d overlay UI.

You use DataRefEditor to turn off each part of your system and see how much framerate comes back.  If you get 5 ms of CPU time back from turning off your 2-d UI you can then say “wow, the UI should not be so CPU expensive” and you can then investigate.

X-Plane Supports Performance Analysis

The technic of shutting a system off and measuring the increase in performance is exactly how we perform performance analysis on X-Plane itself, and as a result X-Plane ships with a pile of “art controls” that disable various pieces of the simulator.

This article provides a big list of art controls you can use to disable parts of your aircraft and measure the performance improvement.

Here’s where object-kill datarefs come in: the “cost” of drawing an object is mostly inside X-Plane (in driver and OpenGL code) but also in the time spent calling dataref handlers that drive animation.  With an object-kill dataref, you can turn off your objects one at at time and see which ones consume a lot of CPU and GPU time.  If an object is found to be expensive, it might be worth an optimization pass in a 3-d editor, or some time spent to improve the scripts that control its datarefs.

 

Posted in Aircraft & Modeling, Development by | 4 Comments

Kill Your Objects

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.

Inside/Outside Views

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:

  1. 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.
  2. For each object that is expensive, I would look at my model, and develop simple rules for when I can avoid drawing them.
  3. 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.
  4. 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:

  1. 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.
  2. 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.

Posted in Aircraft & Modeling by | 8 Comments

X-Plane 10.22: LuaJIT Memory for Windows and Linux

There are a number of changes to how X-Plane 10.22 beta 1 handles memory for LuaJIT plugins.

Windows and Linux 64-bit: X-Plane Manages Memory

Previously, 64-bit Windows and Linux LuaJIT plugins had to allocate their own memory, and often they did not succeed.  64-bit LuaJIT can only use certain special areas* of memory; if, by the time a LuaJIT-based plugin loads, some other code has used all of that memory, then the LuaJIT plugin cannot operate.

With 10.22 beta 1, X-Plane pre-allocates as much low memory as it can and then provides it to LuaJIT plugins on demand.

This change should fix problems where LuaJIT-based plugins run out of memory, fail to load, etc. on Windows with lots of scenery packs and rendering settings cranked up.

If you ship a plugin that uses LuaJIT, make sure your plugin can use the memory provided by X-Plane.  The process for doing this was defined during the X-Plane 10.20 beta and has not changed, so plugins that are coded correctly will just work.

OS X 64-bit: Crash Fix

Previously for OS X, when a LuaJIT used up all available low memory that X-Plane had reserved, X-Plane would crash.  This was a bug in our code; X-Plane now correctly simply tells the plugin “sorry, we’re out of memory for you.”

I have said this before in forum posts and I will say it again: your plugin should not exhaust Lua memory! There is typically over 1 GB of LuaJIT memory available; if your plugin exhausts it all, your plugin is doing something wrong.

So it’s good that this won’t crash, but if there were plugins that were causing this crash, those plugins probably need to be carefully examined – their memory use was way too high!

New Stats to Monitor Memory Use

There are two new “stats” in DataRefEditor (pick the “show stats” sub-menu option) for Lua memory use: lua/total_bytes_alloc and lua/total_bytes_alloc_maximum.  The first one tells you how many bytes of memory all Lua plugins are using, the second shows the highest memory allocation ever recorded.  A few notes:

  • This only measures memory use provided by X-Plane.  So 32-bit plugins will show “0” for both, because in 32-bit plugins, X-Plane does not provide memory to Lua.
  • Lua is garbage-collected, meaning it allocates memory for a while, then periodically throws out unused stuff.  So it is normal to see this value slowly rise over time, then periodically drop down by quite a bit.  It is not normal to see these values increase indefinitely without ever dropping down.
  • If your 64-bit Windows plugin uses LuaJIT but registers “0” for lua/total_bytes_alloc, your plugin is not getting memory from X-Plane and is not working correctly; fix your plugin ASAP!
  • This memory includes allocations by Lua scripts.  It does not include memory for textures, sounds, and other “native” resources provided by SASL or Gizmo.  So you should not see a 4 MB allocation just because you made a 1024 x 1024 texture, for example.

* The lowest 2 GB of virtual memory, to be specific.  Most other code running in X-Plane (the sim itself, the OpenGL driver, OpenAL, the operating system, other plugins) can use any memory, but they tend to consume some of this “LuaJIT-friendly” memory during normal operations.  Thus X-Plane’s strategy is to pre-allocate the LuaJIT-friendly memory and reserve it only for LuaJIT use.

Posted in Aircraft, Development by | 11 Comments

X-Plane 10.22 Beta 1: Memory for Lua and Landing Gear

X-Plane 10.22 Beta 1 is available now (release notes, bug reports).  To get this beta you’ll need to check “Get New Betas” in the X-Plane 10 Installer’s update screen.

This is a very small bug fix patch; there will not be an art asset update, and we’re only including three fixes that we think are critical enough to release ASAP, as well as support for the latest Xavion iPad app.

I will comment on Lua memory allocation in a separate post.

Landing Gear Problems

Plane-Maker 10.21 has a bug: when you save your airplane, the weight distribution coefficients for landing gear are calculated incorrectly, causing the plane to tilt or lean on the runway.  Astute users noticed that resaving the plane in Plane-Maker 10.20 fixed the problem.

This bug is fixed in Plane-Maker 10.22; if your plane has “the leans”, just re-save it in Plane-Maker 10.22 and the problem should resolve itself.

This bug was always a bug in Plane-Maker, not in X-Plane itself; airplanes whose data was not saved incorrectly would fly correctly in 10.21, which is why it took a while for the bug report to get to us.

Copy Protection

First: let’s agree to disagree re: copy protection.  No one likes copy protection, and we can all agree that copy protection is always imperfect.  (That is, it never avoids annoying users completely and it never stops piracy completely.)  Users who buy products and the companies that sell them often disagree about where to draw the line between deterrence and annoyance.

So please: no rants about how awful DVDs are in the comments section.  The goal of this part of the post is to explain what we fixed so that users who have seen a known bug can have better situational awareness.

X-Plane 10 “remembers” that you have inserted X-Plane DVD 1 recently, so that you do not need to have the DVD constantly in the drive to fly.  Right now X-Plane needs to see DVD 1 (for each product you purchased) every seven days or so.

Every now and then we get a bug report from a user where the process of saving the DVD information fails; due to a bug in X-Plane 10.21 and earlier, when this process fails, the DVD would not enable scenery loading at all and the user interface would tell a global scenery user that a regional DVD was found.  This was very confusing and also annoying (since it stops paying customers from using the product).

The bug in X-Plane is fixed in 10.22; furthermore if the preference-saving process fails we now put up a message for the user to contact tech support; previously it was a small item in Log.txt.  If this preference-saving process fails, we want to know about it and fix it.  (So far the only cases we’ve seen are Hackintoshes with hardware configuration issues and one case of a borked network preferences file.)

Water, Water Eveywhere

There is a separate bug in the copy protection system that I couldn’t fix for 10.22; we’ll revisit this issue for 10.30.  The issue is this:

  • When X-Plane needs to see your DVD to get out of demo mode, it tells you after you have started your flight.
  • By that time you are on a runway that is all water.
  • When you insert the DVD, does not reload scenery; you have to go to another airport and then come back to your original airport to “force” a scenery reload.

This behavior is confusing – X-Plane says “now you can fly anywhere in the world” but where’s your scenery?  We get a fair number of tech support calls about this.  The problem is that if we reload scenery when the DVD is inserted and your airplane is on the runway (in water-world) then once scenery is reloaded your aircraft is underground and your aircraft is destroyed.  So a fair number of things need to change (e.g. when we check for the DVD, what we do when we find it) to fix this use case.  That’s too much change for 10.22 and will have to wait for 10.30.

Posted in Aircraft, News by | 10 Comments

Using the Correct Wing Datarefs

This topic is confusing, so I’m going to try to summarize “how to do it the correct way” without going into “under the hood”, first.

DataRefs of the form:

sim/flightmodel2/wing/dataref_name[N]

give you information about the wings – in particular, they tell you the degrees of deflection of the flaps, elevators, etc. etc.

But what number do you use for N?

The answer is: you pick “N” depending on which airfoil you are animating!

In X-Plane, the horizontal and vertical stabilizers are “wings” too – we call anything that has an airfoil a wing.  So you use this table to pick an N that matches what you are doing.

Good:

sim/flightmodel2/wing/aileron1_deg[0] # left aileron
sim/flightmodel2/wing/aileron1_deg[1] # right aileron
sim/flightmodel2/wing/elevator1_deg[8] # left elevator
sim/flightmodel2/wing/elevator1_deg[9] # right elevator
sim/flightmodel2/wing/rudder1_deg[10] # rudder

Usually not good:

sim/flightmodel2/wing/aileron1_deg[8] # aileron on an hstab??
sim/flightmodel2/wing/aileron1_deg[10] # aileron on a rudder?!
sim/flightmodel2/wing/elevator1_deg[0] # elevator on a wing?
sim/flightmodel2/wing/elevator1_deg[10] # elevator on a rudder?
sim/flightmodel2/wing/rudder1_deg[0] # rudder on a wing??

The moral of the story is: pick an array index that matches the part of the plane you are trying to animate!

Unusual Airplanes

I said “usually not good” above because there are airplanes with rudders on the wings (think of a flying wing) or V-tails where the tail is half-rudder, half-elevator.  The rule still applies: use the index that you are animating!  So if you have a rudder on your wing, then use index 0 (left wing 1) for the left wing, etc.  The important thing is to pick an array index that matches the Plane-Maker part.

Why Is It Like This?

If you understand what was written above, you should probably stop reading now. And if you didn’t understand it, you should probably stop reading now.

Okay then.  Why are the datarefs like this?  The answer is that X-Plane is a completely flexible simulator: it lets you put any control surface on any flying surface.  If you want to make an experimental design with elevators on the wings, X-Plane is not going to tell you that your idea is stupid.  (I might tell you that the idea is stupid, but you can ignore me, because the only airplane I ever designed from scratch in Plane-Maker couldn’t take off without JATOs.)

In particular, because any flying surface can have any control surface, the datarefs are set up with array indices for all flying surfaces for all control surfaces.

But if your airplane does not have rudders on the wings, the value of those daterfs won’t be useful – they might be ‘correct’, they might be zero, they might be wrong.  Don’t trust them!  Use the correct array index for the correct wing and your plane will work correctly.

Posted in Aircraft & Modeling by | 6 Comments

Aircraft Authors – View LuaJIT Memory Usage

If your add-on uses LuaJIT (e.g. via SASL, Gizmo, FlyLua, or directly) then this tool may help.  It’s a special build of X-Plane 10.21 for 64-bit Mac that can show total Lua memory use.  Use DataRefEditor and filter on “lua” to see the numbers.

Since Lua uses garbage collection, you’ll see the number rise up and then “fall” periodically as garbage gets cleaned up.  Non-Lua allocations by plugins are not counted.

If you use LuaJIT in your add-on (or a plugin that uses LuaJIT), please try to keep the amount of Lua memory used below 300 MB or so – more is available, but if you use it all, your plugin won’t inter-operate with other plugins.

Posted in Aircraft by | 3 Comments

Double Your Framerate: Pre-Fill

That got your attention, eh?  Sorry, this is not a tip on how to tune your X-Plane system; it’s a tip for aircraft authors to make sure their 3-d cockpits are running at maximum performance.

Prefill is when X-Plane blocks out the clouds that will be behind the airplane cockpit.  The biggest cause of GPU slow-down is cloud rendering, so reducing the area that the clouds have to fill is really important.

In the 2-d cockpit, X-Plane pre-fills automatically.  But in a 3-d cockpit, the airplane author has to specify which objects should be used to pre-fill.

Aircraft Authors: go watch this video or read this page to learn how to set up pre-fill in your aircraft!  If you aircraft has a 3-d cockpit this optimization is very important!

Posted in Aircraft, Cockpits, Modeling by | 9 Comments

Light Sizes – A No Win Situation

Update: We are going to release a new release candidate (10.21 rc2) tonight that puts the light sizing back to normal, while still fixing the SSAA bug.  This will have two effects:

  • Runway lights won’t be as bright as in the RC.  Sorry guys, we will get this fixed, but clearly it’s not something that I should try to change by jamming a code change in at the last minute.
  • Airplane lights will look the same as they do in 10.20 and 10.11.

The rest of the original post follows…

I jammed a change into X-Plane 10.21 rc1 that maybe wasn’t such a great idea: in X-Plane 10.21 the light billboards get bigger when your screen resolution gets bigger.

The idea behind this change is that the percentage of lit pixels in the night scene should not get smaller when you go to a bigger monitor – if they do, then the night scene looks dark.  In X-Plane 10.20 (and 10.10 and 10.05!) the billboard sizes are fixed in pixels – in a bigger monitor they tend to be tiny little dots, potentially harder to see.

This change makes a mess of aircraft lighting, and almost certainly needs to be changed (again) for an RC2.  But the choices aren’t good.

  • If we keep the old behavior (light size is constant in pixels) then authors have a lousy choice: make the lights too big in a small window or too small in a big window.  There’s no way to get your billboards to look good on a laptop and a 1440p monitor.  This is what authors have been living with, and it’s lousy.  If you make a plane, you know that your lights only look right if the user has the same screen resolution as you – something you just should not assume.
  • If we take the new behavior, what size should the lights be?  We have to pick a screen size to use as “official” from 10.20.  In rc1, I picked 1024 x 768 – that is, the smallest resolution we support.  This choice makes the runway lights look good, but virtually all airplanes are going to have lights that look too huge.

So I am considering one of the following choices:

  • Match the 10.21 lights to 1020 at 1080p (or some other intermediate resolution), in the hope that most airplanes will look good on average.
  • Revert the change entirely (and keep only the fix for 4x SSAA) and solve this in 10.30.  This isn’t good because (per above) authors are again stuck with the airplane only looking good at one resolution.  But at least in 10.30 we could do something more clever (e.g. different behaviors for old and new airplanes or who-knows-what-else).  Alex is still out of the country, so the thought of punting this until he can look at the results of some of the choices is tempting.
  • Apply mixed behavior (e.g. different math for scenery vs. airplanes).  With anything “clever” like this, we risk the equations getting complicated, with too much fine print for authoring.

Anyway, I think it’s 95% likely we’ll cut an RC2; I’ll post something when we pick a strategy.

Posted in Aircraft & Modeling, News by | 5 Comments

Customizing Spill Lights – Two Ways

If you are creating an airplane or scenery pack and you need to create a fully customized spill light (visible in HDR mode only in v10) there are two ways to do it.

First, we have a parameterized light called “full_custom_halo” that takes nine parameters, e.g.

LIGHT_PARAM full_custom_halo 0 20 0   1 0.5 0.5 1    50  0 -1 0   0.5

(Phew!)  The first 3 numbers 0,20, are the XYZ position (this light is 20 meters above our object origin).  The next four are the RGBA color (100% red, 50% yellow, 50% green, 100% brightness*), so it’s a very light red.  RGB colors for spills are in linear space, so you’ll have to experiment to get your colors perfect.  The size is 50 meters (a huge light throw), and it points in the direction 0, -1, 0 (straight down).  0.5 is the “semi-width” of the cone – 60 degrees in this case.  Basically cosine(cone width * 0.5) gives you this width parameter, or pass 1.0 for an omnidirectional light.

This light is on all the time – use full_custom_halo_night for the night version.

There’s a second option: OBJ files have a custom spill command:

LIGHT_SPILL_CUSTOM 0 20 0   1 0.5 0.5 1    50  0 -1 0   0.5  your/dataref/here

The position and 9 light parameters all have the same meanings, but in this case you get to provide a dataref.  The dataref must be a float-array dataref of size 9; when your dataref callback is called, the array is pre-initialized to the 9 params, and you can change them at will.  With this dataref, your plugin can change the light parameters in real-time.

Which technique should you use?

  • Use LIGHT_SPILL_CUSTOM if you need the dataref to do clever customization.
  • Use the PARAM_LIGHT with the nine params if you don’t need the dataref.

For scenery the param-light version may be notably faster when used many times in an object.  So if you’re building a light used a lot (a streetlight, a taxiway light, an airport lighting fixture) you really want that param version.

Update: this was not documented at the time, but if you are using datarefs with LIGHT_CUSTOM_SPILL, the dataref format does not match the OBJ8 format.  This page now documents the right format for plugin objects!

* The mathematically minded will note that there is no need to have an alpha on lights because they are additive.  This is true – just set alpha to 1.0 and use darker colors!

Posted in Modeling, Scenery by | 2 Comments