Howto:Illuminate faces

From FlightGear wiki
Jump to navigation Jump to search
This article or section contains obsolete information.

Please refer to Howto:Lightmap instead.

Imagine you see a skyline with a countless amount of lights. Somewhere in front of you there's a stretched row of lights. That's the runway you will land on. That's how you will experience a flight in the dark of the night. In reality. But in FlightGear there aren't much illuminated buildings. So here's a howto that teaches you how to make lights and illuminated buildings. Enjoy!

Basics

To make something of your building, airport, plane or what else illuminate we need an .xml file. In that .xml file we will place some stuff. Every animation (lighting is an animation) starts with the <animation> tag. Followed by the type of animation. For illumination we use the material-type. Now comes a very important part: the objects. Here we need to place the objects that should react on the animation. If we have a building with a antenne on top of it and we only want the antenna to illuminate we need to make that a separate object. So every part that you want to be illuminated should be separated. You could do that in Blender, SketchUp or any other software you're using. Last part is the emission part. The emission will tell FlightGear in what color the object should be illuminated. By combining the three primary colors (red, green and blue) you can create any color you want. If we did everything as described above with a red light we will get something like:

<animation>
 <type>material</type> 
 <object-name>Light1</object-name>
 <object-name>Light2</object-name>
 <emission>	
  <red>1</red>	
  <green>0</green>	
  <blue>0</blue>
 </emission>
</animation>

Blender users

White lights

Blender emit property location

Blender users may create illuminated faces directly from blender itself. But what makes a face to be illuminated in Flightgear ? Well, Flightgear can not take full advantage of all the properties a blender surface can take (fgfs is not a full featured rendering program nor wants to be), there is anyway a method to make faces in blender emit light by their own. First of all we have to remember that whatever program we are using to model an object if we want to use it in Flightgear we have to export it in AC3D format. Materials in AC3D format have line like this one:

MATERIAL "MaterialName" rgb 1 0 0 amb 0.5 0.5 0.5 emis 0 0 0 spec 1 0.9999 0.9999 shi 32 trans 0

Look at the 3 numbers after the emis word (0 0 0). this tells that this material does not emit any light by itself. This is the common row we get when exporting an object in AC3D format from blender. If we wish to illuminate it we can take advantage of the Emit material property under the Shaders panel. If we want a slight emission we can give a value like 0.4 to it. We will get a surface that will emit white light:

MATERIAL "MaterialName" rgb 1 0 0 amb 0.5 0.5 0.5 emis 0.4 0.4 0.4 spec 1 0.9999 0.9999 shi 32 trans 0

Using the blender emit property we can obtain always illuminated surfaces without using any xml configuration file. Just remember that this surface will always emit light in every moment of the day. Also see AC files: Basic changes to textures and colors.

Colored lights

Colored lights can be obtained from blender using a trick of the ac3d default exporter script. We will not use the emit property anymore, but we will use the mirror color of a material as emission color. So after having set the material mirror color to the considered value we have to teach the exporter to use it and convert it to an emis property. This is done by setting the property MIRCOL_AS_EMIS to True under the Blender registry. The Blender registry is a folder generally located in $HOME/.blender/bpydata/config . Here you will probably find an ac3d_export.cfg file. Edit it and change the row:

'MIRCOL_AS_EMIS': False,

to

'MIRCOL_AS_EMIS': True,

Now every time you will export to AC3D format all the materials will get the emis property the same value as their mirror color.
Attention ! Generally blender creates new material setting mirror property to white color (1 1 1), before exporting you have to set all the non illuminating surfaces material mirror color to black (0 0 0) otherwise all the object will be like a big white thing in your scene.
Warning ! The import from an ac3d file does not take in consideration of the MIRCOL_AS_EMIS set to True. Blender will make a media of the values and set it to the emis property (Instead of the mirror color). Fortunately this will be fixed with upcoming Blender version 2.49. Meanwhile blender 2.48 users can use update version of the importer script that fix the import problem and setting:

'EMIS_AS_MIRCOL': False,

to

'EMIS_AS_MIRCOL': True,

in the ac3d_import.cfg config file.

Variations

The light we made above is always illuminated. Below I placed some variations that make the light only illuminate at dark or in changing colors.

Illuminate during dark

If you want a face to illuminate during dark we use the sun angle property (/sim/time/sun-angle-rad). The value is expressed in radians from the zenith, so a common value where our face should start illuminate is pi/2, or 1.57, right on the horizon. But you could change the value if you want to illuminate earlier or later. Depends on your needs.

To turn lights on if the sky is dark:

<animation>
 <type>material</type> 
 <object-name>Light</object-name>
 <condition>		
  <greater-than>		
   <property>/sim/time/sun-angle-rad</property>
   <value>1.57</value>
  </greater-than>
 </condition>
 <emission>	
  <red>1</red>	
  <green>0</green>	
  <blue>0</blue>
 </emission>
</animation>

And to turn the lights off during day: This bit is not needed anymore since FG version 1.9.1. The light is switched off automatically when the above condition is no longer true.

<animation>
 <type>material</type> 
 <object-name>Light</object-name>
 <condition>		
  <less-than-equals>		
   <property>/sim/time/sun-angle-rad</property>
   <value>1.57</value>
  </less-than-equals>
 </condition>
 <emission>	
  <red>0</red>	
  <green>0</green>	
  <blue>0</blue>
 </emission>
</animation>

Changing illumination color

Sometimes there are lights that change colours every now and then. It's not very hard to implement this in FlightGear. There are multiple ways to do this, but we will use the /sim/time/utc/ property. The example below changes color from red, green to blue every. We specified that the color should be red at every time behind 0 second. So if the time is 15:20:05 the color will be red. But at 22:01:21 color will be changed to green. Using this you could even make the lighting color be different every second of the day. Another possibility is a light that illuminates only between two specified times like from 21:00:00 till 6:30:00.

<animation>
 <type>material</type>
 <object-name>Light</object-name>
 <condition>	
  <equals>		
   <property>/sim/time/utc/second</property>				
   <value>0</value>	
  </equals>
 </condition>
 <emission>
  <red>1</red>	
  <green>0</green>	
  <blue>0</blue>	
 </emission>
</animation>
<animation>
 <type>material</type>
 <object-name>Light</object-name>
 <condition>	
  <equals>		
   <property>/sim/time/utc/second</property>				
   <value>20</value>	
  </equals>
 </condition>
 <emission>
  <red>0</red>	
  <green>1</green>	
  <blue>0</blue>	
 </emission>
</animation>
<animation>
 <type>material</type>
 <object-name>Light</object-name>
 <condition>	
  <equals>		
   <property>/sim/time/utc/second</property>				
   <value>40</value>	
  </equals>
 </condition>
 <emission>
  <red>0</red>	
  <green>0</green>	
  <blue>1</blue>	
 </emission>
</animation>

Changing illumination color directly via parameters

It is possible to perform the change of color through the use of properties through the tag <red-prop>, <green-prop> or <blue-prop> to be associated with a parameter defined in the property tree. For example:

    <emission>
        <red>0.12</red>
        <green>0.0</green>
        <blue-prop>sim/G91/Test/V0_1B</blue-prop>
        <factor-prop>sim/G91/re_emit/gauge_red_light</factor-prop>
    </emission>

<factor-pro> always works on the three colors, so any color mixing should be managed using a NASAL or JSBSim function so that the colors are harmonized together.

In this example we mix two colors on a surface (for example the cockpit). The two colors correspond to the red used to illuminate the cockpit and the blue emitted by a wood lamp to illuminate the instrument quadrants. The mixing between the two colors has been assumed as 20% for Wood's light (a value quite close to reality for metallic surfaces), therefore two variables are prepared, one for red and the other for Wood's luve (UV ):

   setprop("sim/G91/re_emit/gauge_phosphorescent_light",pl_phosphorescent_emission * light_by_tension_bus);
   setprop("sim/G91/re_emit/gauge_UV_light_on_red_light",pl_phosphorescent_emission * light_by_tension_bus * 0.2);

The <factor-prop> at this point becomes constant and indicates the reflection factor of the material (high for a glossy or light and lower material for an opaque or dark material). In the example we use the value 0.12. The <factor-prop> tag cannot handle constant values and therefore the <factor> tag should be used, so it is possible to use the same function for different types of materials in different lighting contexts.

    <emission>
        <red-prop>sim/G91/re_emit/gauge_red_light</red-prop>
        <green>0.0</green>
        <blue-prop>sim/G91/re_emit/gauge_UV_light_on_red_light</blue-prop>
        <factor>0.12</factor>
    </emission>

Changing texture if illuminated

To change the texture of an illuminated face we add one single row to the file.

NOTE: This does not work with versions between GIT/2.2.0 snapshot releases and 1.0.0!

<animation>
 <type>material</type> 
 <object-name>Light</object-name>
 <condition>		
  <greater-than>		
   <property>/sim/time/sun-angle-rad</property>
   <value>1.57</value>
  </greater-than>
 </condition>
 <emission>	
  <red>1</red>	
  <green>1</green>	
  <blue>1</blue>
 </emission>
 <texture>Light_lit.png</texture>
</animation>
<animation>
 <type>material</type> 
 <object-name>Light</object-name>
 <condition>		
  <less-than-equals>		
   <property>/sim/time/sun-angle-rad</property>
   <value>1.57</value>
  </less-than-equals>
 </condition>
 <emission>	
  <red>1</red>	
  <green>1</green>	
  <blue>1</blue>
 </emission>
 <texture>Light.png</texture>
</animation>

Switch to another part of texture if illuminated

For v1.9 or later, the way to change textures is the textranslate animation, which lets you "slide" across a texture map. This animation is applied to a single image which has the daytime and nighttime textures placed next to each other.

The width in pixels of texture map (if it is being moved sideways) should be an integral power of two (eg. 20=1, 21=2, 22=4, 23=8, 24=16 and so on). For this example, this texture map has two sides that are each 256 pixels wide. The left side is for day-time textures, the right side is for night-time textures. Each night-time texture is positioned exactly 256 pixels to the right of the day-time texture. Here is an example taken from the shared model German village house - grey roof:

day-time textures
night-time textures

Germanvillagehouse1.png

When you have made that texture map, you apply the day-time textures as default textures to the model in your favourite modeling software (e.g. Blender or SketchUp).

Finally you have to add two bits of code to the XML file:

  1. Code that tells FG to move the texture to the left during night-time
  2. Code that illuminates the model during night-time

The following code tells FlightGear to translate the texture halfway across horizontally at nightfall (setting y instead would translate it vertically):

  <animation>
    <type>textranslate</type> 
    <object-name>germanvillagehouse1</object-name> 
    <property>/sim/time/sun-angle-rad</property>
    <step> 1.57 </step>
    <factor>0.318471338</factor>
    <axis> 
      <x> -1 </x> 
      <y>  0 </y> 
    </axis> 
  </animation>

The 3d object (the house) which "wears" the texture is called germanvillagehouse1 here. This name refers to the name given to the respective object in the AC file. For more information on object names, see AC files: identifying an object.

In order to illuminate the object during dark, add the block of code introduced above: Illuminate during dark. Finally you will have two blocks of code: One that moves the texture at dusk and one that illuminates the object at dusk. Make sure both of them use the right object name. The light will be switched off and the texture will be switched back to day-time texture when the sun rises above an angle of 1.57. Two essential tags here are <step> and <factor>.

  • <step> indicates that the texture should be translated in a single step only when the value passes 1.57 or a multiple thereof; without it the texture would be translated continuously.
  • <factor> is equal to 0.5/1.57, which normalizes the sun angle in radians to a value between 0 and 1 for translating the texture.

Flashing light

To make a flashing light we need to create two objects. One containing the (emitted) light and one containing the light as it would be shown when disabled/turned off. Then we add the following code to our .xml file:

<animation>
 <type>timed</type>
 <object-name>LightsOn</object-name>
 <object-name>LightsOff</object-name>
 <use-personality type="bool">true</use-personality>
 <branch-duration-sec>
  <random>
   <min>2.9</min>
   <max>3.1</max>
  </random>
 </branch-duration-sec>
 <branch-duration-sec>
  <random>
   <min>1.9</min>
   <max>2.1</max>
  </random>
 </branch-duration-sec>
</animation>

You can set the values (time in seconds that a certain object is shown) to your needs. The upper ones are for the LightsOn object, the lower ones for the LightsOff object.

Related content

  • Lightmap effect, allows for easy and nice looking lighting, without switching textures.