Custom Lights

Custom lights are Lighting Billboards that can be customized as part of an OBJ. This article discusses the mechanism behind custom light billboards in detail; see Custom Lighting Billboards for an overview of all possible ways to create lighting billboards in X-Plane.

=Rendering of Custom Lights=

Custom lights are always rendered as a textured billboard (no matter what the user's settings and hardware). The texture of the billboard is a subsection of the OBJ texture. The lighting parameters specify RGBA tinting of the texture, as well as the texture coordinates, and apparent size of the billboard.

Custom lights may have a DataRef associated with them; if the light does have a dataref, that dataref modifies the lighting parameters when the light is drawn, for animated effects.

Like named lights, custom lights are affected by animation (both rotation/translation and show-hide) as well as the object's position. When a dataref indicates that a light is "directional" in a certain direction, remember that this is relative to the object, and can be affected by animation.
 * Example: if you attach a landing light to an airplane and put it inside an animation for the landing gear, then the light's directionality will change as the plane flies and as the gear retracts.

=Custom Light Architecture=

In order to understand how custom lights work, you must understand that datarefs can act as processing functions as well as sources of information. Behind every dataref is some code (in a plugin or X-Plane) that provides the dataref value.

When a custom light is drawn, the following steps occur:
 * First, X-Plane starts with the 9 parameters from the OBJ file.
 * X-Plane passes those 9 parameters to the dataref code (in a plugin or X-Plane) for the custom light (if it has a dataref associated with it).
 * That custom dataref code can then modify or replace the parameters.
 * X-Plane then draws the billboard with the parameters (as modified by the plugin).

This process happens each time the light is drawn - that is, the next time the light is drawn, X-Plane starts over with the original OBJ parameters.

= Usage Models for Custom Lights and Datarefs =

There are a number of ways to use custom lights (with or without datarefs):

Simple Custom Lights
The simplest way to use a custom light is to not use a dataref at all. Your light will be drawn based on the parameters in the OBJ file.
 * Example: an object uses a custom light with no dataref to make a simple, omnidirectional, always-on light.

Custom Lights with Plugin-Replaced Parameters
A more complex use involves using a plugin that replaces certain parameters.
 * Example: The dataref sim/graphics/animation/lights/airplane_strobe_light replaces the red, green, and blue parameters with 1.0, an the alpha parameter with 0.0 if the airplane strobes are not flashing or 1.0 if they are. Thus adding this dataref to a custom light makes it into a white strobe.

In this example, some of the light parameters (size, texture coordinates) work normally. Other parameters (RGBA) are replaced by the plugin, so the values in the OBJ file do not matter. You can put any RGBA into your custom light with sim/graphics/animation/lights/airplane_strobe_light and it will always come out white.

Custom Lights with Plugin-Modified Parameters
The most complex case is the one where lighting parameters are interpreted by a plugin and then replaced. In this case the "meaning" of those lighting parameters depends on the dataref.
 * Example: the dataref sim/graphics/animation/lights/airplane_landing_light interprets the red, green, and blue parameters as a direction vector for the light. The alpha parameter is interpreted as an index number for the landing light switches.  So RGB = 0 0 -1 means that the light points toward the front of the aircraft.  (This is a light where X = 0, Y = 0, and Z = -1.)  A = 2 would mean the third landing light is used; A = 0 means the first landing light.  The dataref replaces the RGB values with 1,1,1 (white) and the alpha value with the brightness based on the current camera angle, or 0.0 if the light is off.  The result is a directional landing light.

In this example, the meaning of RGBA is completely changed - instead these four parameters form a vector and light number. In return for this flexibility, the author loses control of the tint of the light (because the dataref always sets the light tint to white).

Most X-Plane provided datarefs for lights reinterpret the RGBA values (and replace them with white and a variable-level alpha); lights can be colored by coloring their texture. Typically the texture coordinates and size are not modified.

=Custom Lighting Parameters=

Nine numeric parameters define the appearance of a custom light. Those parameters are:
 * Red, Green, Blue, and Alpha Levels. These four numbers define the tinting of the lighting billboard.  (The alpha level fades the light out - at alpha=0.0 the light is not drawn.)  These numbers are ratios from 0.0 (minimum) to 1.0 (maximum).
 * Size. This number describes how big the billboard looks.  Note that this number is not in meters - the size of lighting billboards changes non-linearly with distance.  Use experimentation to tune the light appropriately.
 * S1, T1, S2, T2. These four numbers define the rectangular texture coordinates from your OBJ texture for the image to use as a billboard.

= X-Plane Datarefs for Custom Lights =

X-Plane provides a number of datarefs for custom lights. They are all in the path:

sim/graphics/animation/lights/

For example: sim/graphics/animation/lights/airplane_landing_light.

You should also read part of: xpsdk: PluginsAndObjects. This documentation is intended for plugin developers but may be useful.

Understanding the Documentation for Custom Light Datarefs
Custom light datarefs typically change the meanings of the 9 lighting parameters (RGBA, size, texture coordinates). For example, you might see this:

INPUTS: RGBA form a 4-part direction vector - see PluginsAndObjects. X-Plane 921 and newer: RGB form a 3-part direction vector; A is interpreted as an index number for multiple landing light switches. OUTPUTS: Alpha is set to brightness or 0 if it's off. RGB is set to white. SPECIAL BEHAVIOR: This light will turn off if the landing light is off. DESCRIPTION: This provides a directional light that follows the airplane's landing lights.

The most important sections are "inputs" which tells which of the 9 parameters have special meaning to this dataref, and "outputs" which tells which of the 9 parameters are replaced with new values.

You can find links to the complete list of datarefs here. For datarefs for custom lights, view the HTML datarefs, and click on the link for documentation.

Typical Conventions for Light Datarefs Created by X-Plane
Datarefs provided by X-Plane for custom lights typically have a few common properties:
 * Custom configuration is always done with the RGBA color parameters.
 * The color is almost always replaced with white. (The intention is to color your light using the texture.)
 * Alpha is almost always replaced with the light brightness.
 * Size and texture are usually left alone.

Mathematics of Directional Lighting Parameters
There are a number of common conventions used by X-Plane for directional lights.

RGBA directional lights
Many light datarefs treat either RGB or RGBA as a "direction vector" for a directional light. For example, the airplane landing and taxi lights do this.

The red, green, and blue lights represent the direction of the light in the X, Y, and Z axis in object coordinates.

For example (assuming the object or plane has a rotation of 0 degrees, e.g. it is facing north):
 * RGB = 1,0,0 is a light that shines to the east.
 * RGB = 0,0,-1 is a light that shines to the north.
 * RGB = 0,1,0 is a light that shines straight up.
 * RGB = -0.7,0,0.7 is a light that shines to the south-west.

The alpha parameter is a fixed amount of brightness that is always added to the light. So for example, RGBA = (0.5, 0, 0, 0.5) would create a light that shines to the east, but is also always on a little bit. (See "Tricks for directional lights" below.)

RGB directional lights
Some lights only provide RGB for direction. In this case, RGB operates the same as above, but no constant brightness is added. Typically in this case the alpha parameter is used for something else.

RG Rescaling
Some lights indicate "red green rescaling". In this case, the light always faces north (as if its direction vector was 0,0,-1). However, the magnitude of that direction vector is multiplied by the red value of the light, and the green value is then added. So for example, R=0.5, G=0.5 would create a light that shines to the north with 100% intensity, but in other directions at 50% intensity.

Tricks For Directional Lights
The magnitude of the normal vector can be calculated as:

M = sqrt(x*x+y*y+z*z)

This magnitude affects the overall brightness of the light. Normally you would want M=1 for a light that reaches maximum brightness when the user looks at it. But you can create some interesting effects by using a norma vector such that M is not 1.0.

In particular if M is larger than 1.0 and the constant term of the light (the alpha channel) is negative, the result is a light that is more tightly focused (e.g. it becomes invisible when viewed only a few degrees off axis). Example:

R = 0 G = 0 B = -10 A = -9

In this example, the magnitude of the normal vector M = 10, and the constant term is -9. (Note that B being negative points the light north ... B = 10 would point it south. The magnitude is always positive!)

Similarly, if the light is red-green rescaled, you can achieve the same effect with:

R = 10, G = -9

If M is smaller than 1.0, the constant term can be used to widen the light. For example:

R = 0.5, G = 0, B = 0, A = 0.5

In this case, the light won't fully disappear until directly behind it. For a red-green light, you would use:

R = 0.5, G = 0.5

Plugins and Custom Lights
Plugins can provide custom lights - plugin authors should read xpsdk:PluginsAndObjects for more info. Datarefs provided by plugins for custom lights will not start with sim/graphics... but rather have a plugin-specific prefix. If the plugin is not loaded, the light will show the lighting parameters unmodified.