ALS technical notes: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(Separated glass and interior effects)
Line 124: Line 124:
== ALS glass effect ==
== ALS glass effect ==


As of version 3.5, ALS supports a glass effect with dynamical response to the environment which can render for instance the splashes of raindrops on the canopy, frost or fogging.  
As of FlightGear version 3.5, ALS supports a glass effect with dynamic response to the environment which can render, for instance, the splashes of raindrops on the canopy, frost or fogging.


[[File:Glass01.jpg|400px|Frost effect]]
[[File:Glass01.jpg|400px|Frost effect]]
Line 156: Line 156:
               <reflection-strength type="float">1.0</reflection-strength>
               <reflection-strength type="float">1.0</reflection-strength>
</syntaxhighlight>
</syntaxhighlight>
This is typically created in an effect file such as
c172-interior.eff
which is called by inheritance in the model.xml file.
ie:
<syntaxhighlight lang="xml">
<effect>
  <inherits-from>Aircraft/c172p/Models/Effects/c172p-interior</inherits-from>
  <object-name>Plane.010_0</object-name>
  <object-name>Plane.010_1</object-name>
  <object-name>PilotSeat</object-name>
  <object-name>CopilotSeat</object-name>
  <object-name>panel_1_1</object-name>
  <object-name>InstrumentCover.001</object-name>
  <object-name>doorint_right</object-name>
  <object-name>doorint_left</object-name>
  <object-name>doorhandleint_right</object-name>
  <object-name>doorhandleint_left</object-name>
  <object-name>Panel_0</object-name>
  <object-name>Throttle</object-name>
  <object-name>Mixture</object-name>
  <object-name>Pedestal</object-name>
  <object-name>TrimWheel</object-name>
  <object-name>ParkingBrake</object-name>
  <object-name>BackSeat</object-name>
  <object-name>FuelSelectorFace</object-name>
</effect>
</syntaxhighlight>
Each object that you want the shadow effect to fall on must be included in the inheritance.
Unless you supply a path, the cube_.png's need to reside in the same directory as the model.xml where you added the <effect> tag pair that calls c172-interior.eff, not where you put the aircraft_interior.eff.
The orientation of the faces of each cube have to be adjusted based on the positive and negative axis of the model.
For example, using the c172p model as a reference.
The tail, right wing and top on the model are positive inside Blender. So the cube faces are laid out as follows.
Note: depending on the image's orientation when photographed the rotation direction will vary. Using compass headings to describe how to rotate the images.
px (tail) rotate 90 deg from N or S to W
nx (nose) rotate 90 deg from N or S to E
py (starboard/right) from N do not rotate
ny (port/left) from N rotate 180 deg to S
pz (top) rotate 90 deg from N or S to W
nz (bottom) Aircraft with solid bottom n/a. Aircraft with light penetrating bottoms, tbd.
[[File:C172p-cube.jpg|640px|Cube map layout of the c172p]]
With Blender, it's pretty easy to create the cubemap.
1. Add a camera where the cubemap will be. Set the FOV to 90 degrees.
2. Set the resolution to 1024x1024 (or any other square, power-of-two size).
3. Hide all lights and windows; disable ambient lighting (set it to black) and turn off ambient occlusion.
4. Set the world color to white.
5. Enable the compositor and add an invert node.
6. Render and save the six views as you would normally.
This process depends on the model setup but it should work for most aircraft with a few tweaks.


=== Rain ===
=== Rain ===
Line 306: Line 234:
Examples for the result of a fog mask and a damage mask are shown below:
Examples for the result of a fog mask and a damage mask are shown below:


[[File:Glass12.jpg|400px|Crack pattern using a damage mask]]
[[File:Glass11.jpg|400px|Partial fogging using a mask texture]]
[[File:Glass11.jpg|400px|Partial fogging using a mask texture]]
[[File:Glass12.jpg|400px|Crack pattern using a damage mask]]


=== Mie scattering ===
=== Mie scattering ===
Line 315: Line 243:
[[File:Glass08.jpg|400px|Mie scattering of low light on frost]]
[[File:Glass08.jpg|400px|Mie scattering of low light on frost]]
[[File:Glass13.jpg|400px|Morning sun Mie scattering on fog]]
[[File:Glass13.jpg|400px|Morning sun Mie scattering on fog]]
== Interior shading ==
With FlightGear version 3.5 and above, ALS now supports interior shading; i.e. the sun shining through the windows and casting shadows on the panel.
This is typically created in an effect file such as
c172-interior.eff
which is called by inheritance in the model.xml file.
ie:
<syntaxhighlight lang="xml">
<effect>
  <inherits-from>Aircraft/c172p/Models/Effects/c172p-interior</inherits-from>
  <object-name>Plane.010_0</object-name>
  <object-name>Plane.010_1</object-name>
  <object-name>PilotSeat</object-name>
  <object-name>CopilotSeat</object-name>
  <object-name>panel_1_1</object-name>
  <object-name>InstrumentCover.001</object-name>
  <object-name>doorint_right</object-name>
  <object-name>doorint_left</object-name>
  <object-name>doorhandleint_right</object-name>
  <object-name>doorhandleint_left</object-name>
  <object-name>Panel_0</object-name>
  <object-name>Throttle</object-name>
  <object-name>Mixture</object-name>
  <object-name>Pedestal</object-name>
  <object-name>TrimWheel</object-name>
  <object-name>ParkingBrake</object-name>
  <object-name>BackSeat</object-name>
  <object-name>FuelSelectorFace</object-name>
</effect>
</syntaxhighlight>
Each object that you want the shadow effect to fall on must be included in the inheritance.
Unless you supply a path, the cube_.png's need to reside in the same directory as the model.xml where you added the <effect> tag pair that calls c172-interior.eff, not where you put the aircraft_interior.eff.
The orientation of the faces of each cube have to be adjusted based on the positive and negative axis of the model.
For example, using the c172p model as a reference.
The tail, right wing and top on the model are positive inside Blender. So the cube faces are laid out as follows.
Note: depending on the image's orientation when photographed the rotation direction will vary. Using compass headings to describe how to rotate the images.
px (tail) rotate 90 deg from N or S to W
nx (nose) rotate 90 deg from N or S to E
py (starboard/right) from N do not rotate
ny (port/left) from N rotate 180 deg to S
pz (top) rotate 90 deg from N or S to W
nz (bottom) Aircraft with solid bottom n/a. Aircraft with light penetrating bottoms, tbd.
[[File:C172p-cube.jpg|640px|Cube map layout of the c172p]]
With Blender, it's pretty easy to create the cubemap.
1. Add a camera where the cubemap will be. Set the FOV to 90 degrees.
2. Set the resolution to 1024x1024 (or any other square, power-of-two size).
3. Hide all lights and windows; disable ambient lighting (set it to black) and turn off ambient occlusion.
4. Set the world color to white.
5. Enable the compositor and add an invert node.
6. Render and save the six views as you would normally.
This process depends on the model setup but it should work for most aircraft with a few tweaks.


== ALS fuselage shadow effect ==
== ALS fuselage shadow effect ==

Revision as of 04:35, 18 March 2015

Quality level mapping

The rendering quality of ALS effects is controlled by two main sliders, landmass effects and transition effects. Transition effects regulate overlay texturing quality whereas landmass effects regulate all other aspects of procedural texturing like pixel color postprocessing (dust, snow or wet terrain effects) and apparent terrain roughness (bump and parallax mapping).

In addition, specific effects for certain terrain types (water, urban, forest, agriculture...) and models in the scene can be switched on separately. In some cases this may be needed for a consistent visual impression: If a dust effect is used on the terrain, water needs to be rendered using a separate water shader, otherwise it will appear dusty as well. Likewise, if the Rayleigh haze is used in the highest quality terrain effect, then the highest quality water effect needs to be used to see the same Rayleigh scattering effect on the water.

For technical reasons (landmass and transition control the same shader code) the settings are sometimes mutually dependent, i.e. transition quality level 6 won't have any effect unless landmass quality is also level 6.

Transition

The mapping of quality to visuals of the transition slider is

1:

  • Base texture scheme

2:

  • Alternative hires airport keep effect

3:

  • Base and overlay texture, runway effect (if landmass > 4)
  • Supports secondary lights on runway and airport keep

4:

  • Base, overlay and hires texture

6:

  • Base, overlay, hires, detail, grain, dot and rock texture (if landmass > 6)

Landmass

(Quality levels 1 and 2 are reserved to represent fixed pipeline rendering and the classic FG default renderer in an eventually merged rendering GUI, currently however ALS is switched on per checkbox and not by quality level, so they do not have a function).

3:

  • ALS-rendered position-differential haze and light, moonlight

4:

  • Procedural snow cover on terrain
  • Procedural dust and vegetation effects
  • Wet terrain effect with approximate reflection half vector
  • Patchy fog distribution

5:

  • Noise bump-mapping and parallax mapping of terrain

6: (requires transition 6 as well)

  • Wet terrain effect with correct reflection half vector
  • Hires bump mapping and snow patchiness
  • Variable upper haze layer surface
  • Rayleigh haze
  • Secondary lights on all terrain types
  • Slope line and strata effects

ALS secondary lights

The ALS framework supports a generic implementation of landing lights and a searchlight which are based on a framerate friendly computation in screen coordinates, i.e. the lights project correctly only if the light is close to the viewer (typically, that'd be from cockpit view). In other words, this is not a full (rather expensive) computation of light volumes as Rembrandt does it but a much faster test of illuminated screen areas.

Cessna 172 p using generic ALS landing lights

Two landing lights and a searchlight are supported. The landing lights have a fixed position with respect to the aircraft axis (technically, with respect to the default view axis as defined in the respective view), whereas the searchlight follows any offset of the view axis in view mode, i.e. when using the mouse to look around, the searchlight will follow the motion, the landing lights will not. The lights require ALS to run above basic quality level and work on runway and airport keep above transition setting 3 and everywhere else only at highest quality setting. All lights are controlled via properties in /sim/rendering/als-secondary-lights/.

The names of the properties should be self-explanatory, if for instance if use-searchlight=true then the searchlight (which always follows the current view axis) is used.

The properties landing-light1-offset-deg and landing-light2-offset-deg allow to specify angular offsets for the landing light which are then not centered on the view axis. This can be used to simulate one or two landing lights set in the wings.

The lights can be switched on and off from the property browser for any aircraft without any modifications to the aircraft definition. Implementing them correctly aircraft side thus just involves linking the landing light switches to the ALS control properties and setting the correct angular offsets. Additionally, it is recommended to switch the lights off unless in a cockpit view, as they don't project correctly for any external view.

Range, color, light cone opening angle or intensity of the lights can currently not be configured, and there are no plans to support such a feature in the near future.

All three lights will illuminate fog (if dense enough) and precipitation.

ALS generic lights illuminating dense fog

The grain texture and the rain effect

ALS supports a grain texture for models. This is a semi-transparent overlay texture that works just as its equivalent for terrain texturing and provides the option of generating cm-scale details such as rust or discoloration on a surface without having to use huge textures. An example of a surface rendered with grain texture is the Vinson flightdeck below:

Grain and rain effects on Vinson's flightdeck

This is done using the following effect declaration inheriting from model-combined-deferred.eff as

<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
    <name>flightdeck</name>
    <inherits-from>Effects/model-combined-deferred</inherits-from>
    <parameters>
        <grain-texture-enabled type="int">2</grain-texture-enabled>
        <grain-magnification type="float">0.1</grain-magnification>
        <rain-enabled type="int">2</rain-enabled>
        <texture n="7">
            <image>Models/Geometry/Nimitz/rust_texture.png</image>
            <type>2d</type>
            <filter>linear-mipmap-linear</filter> 
            <wrap-s>repeat</wrap-s>
            <wrap-t>repeat</wrap-t>
            <internal-format>normalized</internal-format>
        </texture>
    </parameters>
</PropertyList>

The grain texture has the number 7 and needs to be enabled by

<grain-texture-enabled type="int">2</grain-texture-enabled>

If the value is set to 1, the grain texture uses the uv-mapping of the underlying surface. If that is very irregular (as in the case of the Vinson flightdeck), alternatively the grain can be mapped in xy-model coordinates if the parameter is set to 2, the uv-mapping of the base texture layer is then discarded.

The resolution of the grain texture with respect to the base coordinate layer is specified by

<grain-magnification type="float">0.1</grain-magnification>

If the number is < 0, the grain resolution is lower than the base layer, if the parameter is > 0, it is higher (note that in the above case, the grain is mapped to (xy) rather than (uv), hence the base size is 1 m, so the grain texture is mapped on a 10x10 m patch on the flightdeck), for which a 1024x1024 pixel texture provides ~1 cm sized details).

Finally, any number greater than 0 passed to

<rain-enabled type="int">2</rain-enabled>

enables the splash effect of raindrops on the surface if it points upward. The surface does not have to be flat for this to work, the effect checks for the surface normal automatically, see the rain enabled for the Citation Bravo.

Thorsten noted about rain splashes: "Works fine here - runway needs to get really wet though before you see them (put the environment slider to max to achieve this quickly, it will take some waiting with just rain on)."

Rain effect on the Citation Bravo


ALS glass effect

As of FlightGear version 3.5, ALS supports a glass effect with dynamic response to the environment which can render, for instance, the splashes of raindrops on the canopy, frost or fogging.

Frost effect Raindrop splashes

The base effect properties are controlled via inheritance and the environment response run-time via properties residing in Environment/aircraft-effects. Derived effects should inherit from Effects/glass.

The glass effect is primarily intended for interior views. In particular, no external fog or haze is rendered for the glass, i.e. if the effect is used in an outside view, it is the responsibility of the aircraft modeler to take care (e.g. with LOD settings or range animations) that no problems in bad visibility occur.


Internal cockpit reflection

There is support for a reflection of the cockpit interior. This needs to be provided as a cubemap specific for the airplane and switched on via the flag <use-reflection> set to 1. The relative strength of the reflection can be optionally via <reflection-strength>. The strength of the reflection in the cockpit is dynamically adjusted for a number of factors, among them balance of direct to indirect light, the approximate amount of light falling on the surface seen in the reflection and the amount of direct sunlight falling into the eye.

If the six cubemap faces are called my_cube_map_??.png, then the xml to use for the inheritance looks like this:

	<texture n="3">
		<type>cubemap</type>
		<images>
			<positive-x>my_cube_map_px.png</positive-x>
			<negative-x>my_cube_map_nx.png</negative-x>
			<positive-y>my_cube_map_py.png</positive-y>
			<negative-y>my_cube_map_ny.png</negative-y>
			<positive-z>my_cube_map_pz.png</positive-z>
			<negative-z>my_cube_map_nz.png</negative-z>
		</images>
		</texture>
               <use-reflection type="int">1</use-reflection>
               <reflection-strength type="float">1.0</reflection-strength>

Rain

Rain splashes will render automatically when the weather system reports rain via environment/rain-norm. In addition, the user can set rain splashes to render via environment/aircraft-effects/ground-splash-norm (this is intended to allow splashes to be rendered e.g. for water landings of aircraft equipped with floats).

By default, the rain splashes impact from above (more precisely the +z direction in model coordinates). This may be inadequate if the aircraft is moving. However, the shader can not know what the airstream at the glass will be, so the impact vector of rain splashes has to be modeled aircraft-side and set via environment/aircraft-effects/splash-vector-x (splash-vector-y, splash-vector-z). These are likewise in model coordinates.

As long as the length of the splash vector is <1, just the impact angle will change, as the length of the vector increases to 2, droplets will also be visibly moving. This allows fine control of the visuals dependent on any number of factors desired. A simple Nasal snipped varying the splash vector with airspeed for the F-16 is given below (do not mindlessly copy and expect to work for any aircraft - it won't!)

var splash_vec_loop = func {

var airspeed = getprop("/velocities/airspeed-kt");

# f16
var airspeed_max = 120;

if (airspeed > airspeed_max) {airspeed = airspeed_max;}

airspeed = math.sqrt(airspeed/airspeed_max);

var splash_x = -0.1 - 2.0 * airspeed;
var splash_y = 0.0;
var splash_z = 1.0 - 1.35 * airspeed;



setprop("/environment/aircraft-effects/splash-vector-x", splash_x);
setprop("/environment/aircraft-effects/splash-vector-y", splash_y);
setprop("/environment/aircraft-effects/splash-vector-z", splash_z);

settimer( func {splash_vec_loop() },1.0);
}

Note the timing constant of the loop - running the update per-frame leads to a spurious movement of the coordinate system in which rain is rendered and spoils the effect.

Frost and fogging

Frost on the canopy is rendered when environment/aircraft-effects/frost-level is set in the range from 0 to 1. Again, it is up to the aircraft developer to decide at what exterior conditions frosting should happen and whether the aircraft is equipped with heating to remove the frost again.

Fogging is controlled by environment/aircraft-effects/fog-level in the range 0 to 1. Unless a mask is used, fogging is homogeneous across the whole surface (it is really intended to be used with a mask).

Tint

Tinted glass can be easily created by changing

<glass-tint type="vec4d" n="0"> 1.0 1.0 1.0 1.0</glass-tint>

to any value desired. This will affect all effects assumed outside of the glass layer (frost and rain splashes) but not fogging inside the glass. Use primarily for development and quick tests, don't misuse the alpha value available here, it has odd side effects.

Functional masks

If the glass surface is uv-mapped and textured, it is possible to switch on a mask functionality in the inheritance via

<texture n="2">
	<image>my_mask.png</image>
	<type>2d</type>
	<filter>linear-mipmap-linear</filter>
	<wrap-s>clamp</wrap-s>
	<wrap-t>clamp</wrap-t>
	<internal-format>normalized</internal-format>
</texture>
<use-mask type="int">1</use-mask>
<overlay-color type="vec3d" n="0">1.0 1.0 1.0</overlay-color>

The red channel in my_mask.png controls the strength of fogging, full red corresponds to maximal fogging, no red to zero fogging. This allows to selectively model the position of heaters in the cockpit.

The green channel of my_mask.png is the amount of reduction of rain in an area. This is intended for airplanes equipped with windshield wipers to partially clear the wiped area of the rain. Whether the windshield wiper is actually on or not is controlled runtime via /environent/aircraft-effects/use-wipers.

The blue channel of my_mask.png is reserved for an overlay pattern which will be drawn in an optionally specified <overlay-color> vector (white in the example xml above) - the primary function is to render damage on the glass, but with a different color, also dirt or an alternative more finely controlled frost pattern can be used. The strength of the pattern can be adjusted runtime via /environment/aircraft-effects/overlay-alpha, allowing dynamical accumulation of dirt or sudden appearance of damage.

Examples for the result of a fog mask and a damage mask are shown below:

Crack pattern using a damage mask Partial fogging using a mask texture

Mie scattering

Most glass effects show prominent Mie forward scattering as in reality, i.e. frost patterns or fogging will appear much more prominent when looking almost towards the sun than under any other angle. While the frost pattern is normally not very prominent and one is able to look through unhindered, this changes substantially when looking into the sun, at which point it almost obscures the view.

Mie scattering of low light on frost Morning sun Mie scattering on fog

Interior shading

With FlightGear version 3.5 and above, ALS now supports interior shading; i.e. the sun shining through the windows and casting shadows on the panel. This is typically created in an effect file such as

c172-interior.eff

which is called by inheritance in the model.xml file.

ie:

<effect>
   <inherits-from>Aircraft/c172p/Models/Effects/c172p-interior</inherits-from>
   <object-name>Plane.010_0</object-name>
   <object-name>Plane.010_1</object-name>
   <object-name>PilotSeat</object-name>
   <object-name>CopilotSeat</object-name>
   <object-name>panel_1_1</object-name>
   <object-name>InstrumentCover.001</object-name>
   <object-name>doorint_right</object-name>
   <object-name>doorint_left</object-name>
   <object-name>doorhandleint_right</object-name>
   <object-name>doorhandleint_left</object-name>
   <object-name>Panel_0</object-name>
   <object-name>Throttle</object-name>
   <object-name>Mixture</object-name>
   <object-name>Pedestal</object-name>
   <object-name>TrimWheel</object-name>
   <object-name>ParkingBrake</object-name>
   <object-name>BackSeat</object-name>
   <object-name>FuelSelectorFace</object-name>
 </effect>

Each object that you want the shadow effect to fall on must be included in the inheritance.

Unless you supply a path, the cube_.png's need to reside in the same directory as the model.xml where you added the <effect> tag pair that calls c172-interior.eff, not where you put the aircraft_interior.eff.


The orientation of the faces of each cube have to be adjusted based on the positive and negative axis of the model.

For example, using the c172p model as a reference.

The tail, right wing and top on the model are positive inside Blender. So the cube faces are laid out as follows.

Note: depending on the image's orientation when photographed the rotation direction will vary. Using compass headings to describe how to rotate the images.

px (tail) rotate 90 deg from N or S to W

nx (nose) rotate 90 deg from N or S to E

py (starboard/right) from N do not rotate

ny (port/left) from N rotate 180 deg to S

pz (top) rotate 90 deg from N or S to W

nz (bottom) Aircraft with solid bottom n/a. Aircraft with light penetrating bottoms, tbd.


Cube map layout of the c172p


With Blender, it's pretty easy to create the cubemap.

1. Add a camera where the cubemap will be. Set the FOV to 90 degrees. 2. Set the resolution to 1024x1024 (or any other square, power-of-two size). 3. Hide all lights and windows; disable ambient lighting (set it to black) and turn off ambient occlusion. 4. Set the world color to white. 5. Enable the compositor and add an invert node. 6. Render and save the six views as you would normally.

This process depends on the model setup but it should work for most aircraft with a few tweaks.

ALS fuselage shadow effect

ALS supports the manipulation of a (simplified) ground shadow. This effect uses an existing simplified shadow animation configuration and by default uses the gear-agl-m property to calculate the ground placement of that simplified shadow.

ALS Shadow

The effect can be applied easily in any aircraft that report the gear-agl-m property by simply adding a declaration inheriting from shadow.eff.

If the aircraft does not support the gear-agl-m property, (notably JSBSim), you need to create a Property Rule to pass a supported AGL data to the gear-agl-m property. In this case we use altitude-agl-ft converted to meters using a property rule configuration file.

For the first example we'll use the "supported gear-agl-m" method for aircraft that don't require a property rule.

Simply add the following inheritance declaration after you declare your shadow animation statement.

<effect>
    <inherits-from>Effects/shadow</inherits-from>
    <object-name>name_of_the_shadow_object</object-name>
</effect>

In the non-ALS simplified shadow code you normally use a "translate" animation to position the shadow on the ground. When using the ALS method you must either remove, comment out, or apply a condition to restrict its use to non ALS shadow applications, because ALS is responsible for computing the shadows ground position.

Here is how we apply a condition to the translation to limit it effect to non-ALS application only.

<!--Translate to ground level  -->
  <animation>
   <type>translate</type>
   <object-name>shadow</object-name>
   <condition>
    <not>
      <property>/sim/rendering/shaders/skydome</property>
    </not>
   </condition>
   <property>/position/altitude-agl-ft</property>
   <factor>-0.3048</factor>
   <center>
     <x-m>0</x-m>
     <y-m>0</y-m>
     <z-m>0</z-m>
   </center>
   <axis>
     <x>0</x>
     <y>0</y>
     <z>1</z>
   </axis>
 </animation>

A complete shadow animation block looks like this.

<PropertyList>

  <animation>
    <!-- opaque objects -->
    <!-- transparent objects -->
    <object-name>shadow</object-name>
    <type>select</type>
    <condition>
      <not>
        <property>/sim/rendering/rembrandt/enabled</property>
      </not>
    </condition>
  </animation>
  
  <effect>
    <inherits-from>Effects/shadow</inherits-from>
    <object-name>shadow</object-name>
  </effect>

  <animation>
    <type>noshadow</type>
    <object-name>shadow</object-name>
  </animation>

  <!-- pitch -->
  <animation>
    <type>rotate</type>
    <object-name>shadow</object-name>
    <property>/orientation/pitch-deg</property>
    <factor>-1.0</factor>
    <center>
      <x-m>0</x-m>
      <y-m>0</y-m>
      <z-m>0</z-m>
    </center>
    <axis>
      <x>0</x>
      <y>1</y>
      <z>0</z>
    </axis>
  </animation>

  <!-- roll -->
  <animation>
    <type>rotate</type>
    <object-name>shadow</object-name>
    <property>/orientation/roll-deg</property>
    <factor>1.0</factor>
    <center>
      <x-m>0</x-m>
      <y-m>0</y-m>
      <z-m>0</z-m>
    </center>
    <axis>
      <x>1</x>
      <y>0</y>
      <z>0</z>
    </axis>
  </animation>

  <!--Translate to ground level  -->
  <animation>
   <type>translate</type>
   <object-name>shadow</object-name>
   <condition>
    <not>
      <property>/sim/rendering/shaders/skydome</property>
    </not>
   </condition>
   <property>/position/altitude-agl-ft</property>
   <factor>-0.3048</factor>
   <center>
     <x-m>0</x-m>
     <y-m>0</y-m>
     <z-m>0</z-m>
   </center>
   <axis>
     <x>0</x>
     <y>0</y>
     <z>1</z>
   </axis>
  </animation>

</PropertyList>

For aircraft requiring a Property Rule there are a couple extra steps.

In aircraft-set.xml you add the property rule call to the "configuration file" in between the PropertyList/sim/systems tag pairs.

	
<property-rule n="101">
  <name>gear_agl-m</name>
  <path>Aircraft/c172p/Systems/gearAGL.xml</path>
</property-rule>

Note: the n="101" needs to be =+100 as -100 is reserved for system wide property rules. In the above example 101 was used because 100 was already being used by a previous property rule definition.

The "configuration file" normally goes in /Systems. In this example we named the configuration file /Systems/gearAGL.xml.

Here is the complete /Systems/gearAGL.xml configuration file.

<?xml version="1.0"?>

<PropertyList>
  <filter>
    <type>gain</type>
    <gain>0.3048</gain>
    <input>/position/altitude-agl-ft</input>
    <reference>6</reference>
    <output>/position/gear-agl-m</output>
  </filter>
</PropertyList>

What the configuration file does is convert the input of altitude-agl-ft to the output of (((altitude-agl-ft)-6)*0.3048) or (convert ft-6 to m) and pass it to /position/gear-agl-m.

See Input and reference properties or values <input> and <reference>.


General comments from forum discussion

Cquote1.png A few aircraft have a fake shadow, in essence a flat silhouette of the aircraft floating maybe a feet above ground. The silhouette get there using a few properties, possibly driving some calculations and basically the same kind of animations as is used to for example animate the control surfaces. I do not remember having seen a list with aircraft using a fake shadow, but I think that for example Helijah's Diamond twin has one. The big drawback with a fake shadow is that it has to float to not get broken through by even the slightest undulations in the ground, while still will not work as soon as there is a slope.
— Johan G (Mon Dec 15). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png As the tree shadow code has shown, it's near-trivial to do the projective geometry not by an animation but in the vertex shader, i.e. fake shadows can be placed where the sun casts them, stretched by the projection, depth adjusted to weather condition and if the current terrain normal is passed, they can even be put co-planar with the local triangle, i.e. they'd project correctly even on sloped runways and terrain. At a computational cost of almost zero, because you just process the four vertices of the shadow quad, and four is a number which isn't even a warm-up exercise for a GPU used to crunch millions of vertices. But of course, it wouldn't be a real shadow, in particular it wouldn't project correctly onto trees and buildings as a stencil buffer or shadow map solution would.
— Thorsten (Mon Dec 15). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png Having said that, it is fairly simple to do. Here's an implementation for the EC-130 which comes with an animation based fake shadow out of the box, switching the shadow projection to a GLSL shader:

The animation just puts the shadow onto the ground. The GLSL code can do some projection of the shadow, i.e. it magnifies a bit for low sun and changes position: The shader can do a full light calculation of the surrounding scene, so the depth of the shadow can be varied according to the ambient to diffuse light balance: Also, once the aircraft is in the air, it projects the shadow along the light ray rather than underneath the aircraft: And of course, all that means shadow depth adjusts to weather conditions - no shadows in overcast skies:

Implementation (using current git) - make the quads displaying the fake shadow inherit from Effects/shadow.eff, don't translate the shadow (the shader expects it to be correctly positioned for the sun in the zenith for an aircraft standing on the runway), don't try to correct for low sun or to adjust shadow texture transparency, the shader just uses the texture alpha channel.
— Thorsten (Tue Dec 16). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png
Where should I put this? Into one of the *.eff files of any aircraft?

-you need the shadow itself as a model (a textured quad). In ac3d (blender,...) that has an object name - in my example shadow_fuselage. You can give it any you want.

-in the aircraft-set.xml (or files included there), animations, effects, sounds,... are declared and models included. In the scope where your shadow quad is included, you declare shadow.eff as your effect. What wlbragg has has done (inheriting a copy of the shadow effect under the aircraft effect directory) is probably more by the book, but not strictly necessary unless you want to pass parameters to the effect.
— Thorsten (Sat Jan 17). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png It works with anything that sets a property how far the gear is off the ground - it works with your home-made Nasal FDM if you like...
— Thorsten (Sat Feb 14). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png
wlbragg wrote in Sat Feb 14, 2015 1:14 am:
 After looking at how slow altitude-agl-ft update is, I don't think it would work very well anyway.
 I'll try the "property rule".
 But now I am curious why I couldn't get altitude-agl-ft to work at all?

If altitude-agl-ft seems to update slowly in the property browser it might be a tied property that can't be listened to so instead it is polled at a lower rate - but the property will actually be updated for each frame or FDM iteration.

This might also explain why you have problems getting its value into the effect - the effect system might also rely on listeners to get updates (I don't know).
— AndersG (Sat Feb 14). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png Yes - you can't pass tied properties to effects. Learned that one the hard way (took me a while to figure out...) That's probably the problem here as well. Okay, then we need an aircraft-side property rule in any case. It doesn't need to be AP (they're updated at FDM rate), we only need it at framerate. I vaguely remember there was a catch that you had to give an index to airplane-side property rules to avoid overriding the system-wide which do e.g. weather - there's documentation on the wiki somewhere, I think in the AP howto.
— Thorsten (Sat Feb 14). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png After setting up two separate aircraft with the simplified shadow effect, here is what I found to work best.

Simply put I used a property rule for for both YSim and JSBSim aircraft and override gear-agl-m with a filter passing altitude-agl-ft to gear-agl-m in both aircraft. The reason for this is to accommodate all the shadow AGL adjustment needed for both ASL-shadows and non-ALS-shadows.

My Cub has two configurations for tire size and thus two different altitude-agl-ft starting points. The c172p also has its own altitude-agl-ft starting point. I guess they would be dependent upon where and how the model designer created the center point of the aircraft.

To accommodate this variability you need to do an offset in the shadow.xml to place the shadow's AGL where you want it. But when using ALS-shadow method it has a tendency to put it where it thinks it needs to go based on the hard code. So you use the offset to position the initial shadow. Then you use the property rule configuration to position the shadow when ALS method takes control of the shadow's AGL.
— wlbragg (Sun Feb 15). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png

ALS 3d shadow volume effect

What might be considered the next level of realism using a relatively "cheap" shadow effect is to use a 3d volume shadow.

ALS 3d Shadow Volume

The procedure to implement the ALS shadow volume is similar to the ALS-shadow above with a few modifications.

First you have to have a 3d shadow volume model of the aircraft you are applying the effect to. This model should be a low poly model that is optimized to be as little of a footprint as possible.

A property rule is required, same as above. This is used to generate the above ground altitude in meters, (altitude-agl-m). The "altitude-agl-m" is used to place the shadow close to the ground in real time at an FDM rate of execution. NOTE: Do not confuse "altitude-agl-m" with the other type of non-3d ALS-shadow property of "gear-agl-m". The shaders involved use these two different properties respectively for the two different effect. They are not interchangeable.

<?xml version="1.0"?>
<PropertyList>
   <filter>
      <type>gain</type>
      <gain>0.3048</gain>
      <input>/position/altitude-agl-ft</input>
      <reference>1.0</reference>
      <output>/position/altitude-agl-m</output>
   </filter>
</PropertyList>

The other difference from the ALS-shadow above is that it uses a different inherited effect. Instead of

<effect>
    <inherits-from>Effects/shadow</inherits-from>
    <object-name>shadow</object-name>
 </effect>

you use

<effect>
    <inherits-from>Effects/shadow-vol</inherits-from>
    <object-name>shadow</object-name>
  </effect>


General comments from forum discussion

Cquote1.png In real-time 3d rendering in general. To be very fast, all tasks are parallelized, so the GPU can crunch every vertex and every pixel independent of what the others do. The price for that to work is that you track only the ray from light (L) to object (O) to eye(E), so if that's the relevant geometry, you don't need to know anything else of the scene, you can get all the reflection angles at the object in one go.

To place a shadow, you want to know whether the ray L-O intersects somewhere else before it illuminates, i.e. evaluate L-O-O-E - and that's no longer factorizable - now at one vertex, you need to know all the others. I.e. a GPU can't evaluate this (raytracing still can easily, but that doesn't run in real time...) - which is where we need various tricks. Which range from very cheap (fake shadows) to very expensive (additional shadow camera or shadow volume creation and stencil buffer passes over the whole scene).


— Thorsten (Tue Feb 17). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png Not an issue - shadow alpha is set by the fragment shader anyway based on time of the day and cloud cover (if there's lots of clouds, you get very faint shadows).

I think the issue is simple - multiple layers are visible where only one should be, so I need to do a first pass over just the shadow to fill the depth buffer and then draw the uppermost layer of the shadow in the second pass. If the shadow volume really is a low poly version of the model, that should be really cheap (on the other hand, if it's a full multi-million poly replica, then... let's say you will notice...). Anyway, I didn't touch fragment work at all yesterday, I just wanted to sort out the geometry.


— Thorsten (Thu Mar 05). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png It's not a shadow, it's a squished volume flat on the ground. Don't fall into the trap of thinking of it as a shadow while developing.

Don't need it. Volume and texture shadow are only different at the vertex stage only - to determine the pixel color, we can follow precisely the same steps.


— Thorsten (Thu Mar 05). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png You have to make it.

It is the same thing as the 3d model of the aircraft except it is (hopefully) low poly. Meaning it has only what is needed to make a 3 dimensional shadow that looks like the original model without all the details (no interior, etc). This is something that really should have been considered back at the beginning of the FG project. Modelers should have by default make LOD versions of their aircraft for various reasons. You can't use the effect without it.


— wlbragg (Thu Mar 05). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png "I guess the effect cannot handle moving gear or tilting nacelles?"

I suspect right now no - animations seem to all go into the gl_ModelViewMatrix and currently the projection generating the shadow is applied before the matrix is multiplied. In principle, it's just a question of sorting the math out to do the projection in eye space, i.e. after applying gl_ModeViewMatrix - then the shadow reflects the state of the model after all animation have been carried out - and then do the projection transformation to screen space separately. I suspect it's ugly though, since the up-direction along which we determine where the ground is needs to be rotated as well, then we may have to do the roll/pitch transformations which make the shadow flat by hand,...

I have a suspicion it's more trouble than it's worth - it's the sort of thing you'll only notice if you go looking for it.


"IIRC in OpenGL it's not that necessary to create low poly LODs for your 3D model, someone correct me if I'm wrong here, but I recall this being mentioned more than once."

I think the definition of 'low poly' depends on your hardware. My current graphics card will happily crunch six million scenery vertices at a decent framerate, so it won't even notice whether you add a model with 1000 or 10.000 polygons. However, I assure you that you will feel the effect of adding a 3 million polygon shadow model to the scene.

So you shouldn't waste a lot of time in desperately driving polygon count down, but you should strip down the shadow model from the original where this is feasible, especially if the original has excessive polygon count.

It actually requires a depth buffer fill followed by a depth equality test, that renders one layer only.


— Thorsten (Thu Mar 06). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png
Cquote1.png Let me re-iterate that the shader does not use the transparency you set for the material - the rasterizer and z-buffer however may, leading to unexpected and difficult to track behavior. For the texture shadow, you should use texture alpha only to draw the outline of the shadow, and for the shadow volume you should for the moment not use material or texture alpha at all (at a later stage, I can add support for texture alpha). The shader should determine the correct alpha of the shadow output pixel on its own.
— Thorsten (Thu Mar 08). Re: 2D shadow on ground?.
(powered by Instant-Cquotes)
Cquote2.png

Related content