<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Icecode</id>
	<title>FlightGear wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Icecode"/>
	<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/Special:Contributions/Icecode"/>
	<updated>2026-05-29T23:53:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Changelog_2024.1&amp;diff=141053</id>
		<title>Changelog 2024.1</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Changelog_2024.1&amp;diff=141053"/>
		<updated>2024-11-29T18:54:10Z</updated>

		<summary type="html">&lt;p&gt;Icecode: ShaderVG removed from 2024.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
* Many crashes and memory leaks fixed.&lt;br /&gt;
* Preview of World Scenery 3.0.  This is a new scenery system that uses multiple levels of detail to provide higher frame-rates and lower memory occupancy at bigger visibility ranges.&lt;br /&gt;
* Many improvements to the FlightGear launcher.&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
&lt;br /&gt;
* Compositor multi-pass rendering.&lt;br /&gt;
* Real-time shadows and lights.&lt;br /&gt;
* Improved photoscenery support.&lt;br /&gt;
* Improved scenery object support, including defining and rendering large numbers of scenery lights in STG files, and support for generic instantiation of objects (e.g. windmills, pylons).&lt;br /&gt;
* Add the Milky Way to the night sky.&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
* Flight data can now be saved to file as a continuous uncompressed file stream.&lt;br /&gt;
* Compressed video encoding is now supported.&lt;br /&gt;
* IO channels can be re-initialized and are exposed on the property tree under /io/channels/.&lt;br /&gt;
&lt;br /&gt;
== FDM ==&lt;br /&gt;
&lt;br /&gt;
* Synchronization with JSBSim v1.1.11.&lt;br /&gt;
* Better support for frozen lakes.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
&lt;br /&gt;
* Update for world magnetic model data set from WMM2015 to WMM2020.&lt;br /&gt;
* Replace season selection (--season) with improved climate modeling, including seasonal variation, ocean temperatures, dew point, snow line and other environmental factors.&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
* Localization support for add-ons as well as aircraft&lt;br /&gt;
* Improve translations for the following languages:&lt;br /&gt;
** French&lt;br /&gt;
** Spanish&lt;br /&gt;
** Polish&lt;br /&gt;
** Italian&lt;br /&gt;
** German&lt;br /&gt;
** Dutch&lt;br /&gt;
** Slovak&lt;br /&gt;
** Georgian&lt;br /&gt;
** Russian&lt;br /&gt;
** Chinese&lt;br /&gt;
&lt;br /&gt;
== Hardware Device Support ==&lt;br /&gt;
Support for the following hardware devices has been added or updated:&lt;br /&gt;
&lt;br /&gt;
* Honeycomb Alpha Flight Controls&lt;br /&gt;
* Honeycomb Bravo Throttle Quadrant&lt;br /&gt;
* Saitek Pro Flight Rudder Pedals &lt;br /&gt;
* Saitek Pro Flight Switch Panel&lt;br /&gt;
* CH Combatstick&lt;br /&gt;
* Logitech G25 Racing Wheel&lt;br /&gt;
* Thrustmaster T-Flight Rudder Pedals&lt;br /&gt;
&lt;br /&gt;
== AI Traffic &amp;amp; Liveries ==&lt;br /&gt;
&lt;br /&gt;
* Many improvements to make AI aircraft behavior more realistic.&lt;br /&gt;
&lt;br /&gt;
Traffic and/or liveries have been added for the following airlines:&lt;br /&gt;
&lt;br /&gt;
* Delta Airlines&lt;br /&gt;
* United Airlines&lt;br /&gt;
* AeroUnion Mexico&lt;br /&gt;
* AeroMexico&lt;br /&gt;
* AeroMexicoConnect&lt;br /&gt;
* Amerijet Cargo&lt;br /&gt;
* Airest Cargo&lt;br /&gt;
* Air Caraibes&lt;br /&gt;
* DHL&lt;br /&gt;
* Amazon Air&lt;br /&gt;
* EuroWings&lt;br /&gt;
* Polar Air Cargo&lt;br /&gt;
* Northern Air Cargo&lt;br /&gt;
* Eastern Airways UK&lt;br /&gt;
* ANA Wings&lt;br /&gt;
* Ibex Japan&lt;br /&gt;
* Solaseed Japan&lt;br /&gt;
* AirHongKong &lt;br /&gt;
* AirHongKong Cargo&lt;br /&gt;
* AirChina&lt;br /&gt;
* UNI Air Japan&lt;br /&gt;
* Southern Air Cargo&lt;br /&gt;
* SATA Air Acores&lt;br /&gt;
* Azores Airlines&lt;br /&gt;
* European Air Transport Leipzig&lt;br /&gt;
* SkyLeaseCargo&lt;br /&gt;
* Blue Air&lt;br /&gt;
* Cyprus Airways&lt;br /&gt;
* DirectFlight Airtask Shetland&lt;br /&gt;
*&lt;br /&gt;
* Corsair&lt;br /&gt;
* LOT Polish Airlines&lt;br /&gt;
* Braethens&lt;br /&gt;
* Transavia NL&lt;br /&gt;
* Transavia France&lt;br /&gt;
* Tunisair Group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Traffic and/or liveries have been removed for the following airlines:&lt;br /&gt;
&lt;br /&gt;
* GermanWings (defunct)&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
fc16b827a Fix OSM imagery in the canvas map (fixes #2912)**&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;**&amp;lt;/nowiki&amp;gt;f0a740333 Remove OpenAIP map support from Canvas Map (see #2913)**&lt;br /&gt;
&lt;br /&gt;
== Nasal ==&lt;br /&gt;
&lt;br /&gt;
== Phi ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;**&amp;lt;/nowiki&amp;gt;7b36d498f Fix a variety of broken or unsupported maps in Phi&lt;br /&gt;
&lt;br /&gt;
725ce7d3f Phi: Add map option to disable repositioning own aircraft by dragging&lt;br /&gt;
&lt;br /&gt;
fc3b7b8b5 Phi: Highlight &amp;quot;follow aircraft&amp;quot; button if enabled&lt;br /&gt;
&lt;br /&gt;
5626dc51f Phi: Remove unused css rule&lt;br /&gt;
&lt;br /&gt;
88788dc6a Fix attributes for multiplayer and AI airplanes in Phi (fix #2274)&lt;br /&gt;
&lt;br /&gt;
660fda829 Phi: automatically use latest AIRAC cycle for OpenFlightMaps&lt;br /&gt;
&lt;br /&gt;
57483a999 Phi: fix midnight time offset&lt;br /&gt;
&lt;br /&gt;
== Aircraft Carriers ==&lt;br /&gt;
The following [[Aircraft carrier|Aircraft carriers]] have been added:&lt;br /&gt;
&lt;br /&gt;
* Admiral Kuznetsov&lt;br /&gt;
* Liaoning&lt;br /&gt;
&lt;br /&gt;
== Misc. ==&lt;br /&gt;
f9ad4124f Route manager add total dist, dist remaining, ete, flight time&lt;br /&gt;
&lt;br /&gt;
* Highlighting tool enabled by setting /sim/highlighting/enabled=true which highlights any animated objects under the pointed along with any other objects animated by the same or related properties.&lt;br /&gt;
&lt;br /&gt;
== Legacy ==&lt;br /&gt;
* Remove [[Rembrandt]] command-line options&lt;br /&gt;
&lt;br /&gt;
== User Interface ==&lt;br /&gt;
* Improved property browser dialog&lt;br /&gt;
* Standardized dialog title bars&lt;br /&gt;
* Improved input device interface&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Changelog_2024.1&amp;diff=140921</id>
		<title>Changelog 2024.1</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Changelog_2024.1&amp;diff=140921"/>
		<updated>2024-11-09T16:38:00Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
* Many crashes and memory leaks fixed.&lt;br /&gt;
* Preview of World Scenery 3.0.  This is a new scenery system that uses multiple levels of detail to provide higher frame-rates and lower memory occupancy at bigger visibility ranges.&lt;br /&gt;
* Many improvements to the FlightGear launcher.&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
&lt;br /&gt;
* Compositor multi-pass rendering.&lt;br /&gt;
* Real-time shadows and lights.&lt;br /&gt;
* Improved photoscenery support.&lt;br /&gt;
* Improved scenery object support, including defining and rendering large numbers of scenery lights in STG files, and support for generic instantiation of objects (e.g. windmills, pylons).&lt;br /&gt;
* Add the Milky Way to the night sky.&lt;br /&gt;
* Optional ShaderVG, a shader based version if ShivaVG.&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
* Flight data can now be saved to file as a continuous uncompressed file stream.&lt;br /&gt;
* Compressed video encoding is now supported.&lt;br /&gt;
* IO channels can be re-initialized and are exposed on the property tree under /io/channels/.&lt;br /&gt;
&lt;br /&gt;
== FDM ==&lt;br /&gt;
&lt;br /&gt;
* Synchronization with JSBSim v1.1.11.&lt;br /&gt;
* Better support for frozen lakes.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
&lt;br /&gt;
* Update for world magnetic model data set from WMM2015 to WMM2020.&lt;br /&gt;
* Replace season selection (--season) with improved climate modeling, including seasonal variation, ocean temperatures, dew point, snow line and other environmental factors.&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
* Localization support for add-ons as well as aircraft&lt;br /&gt;
* Improve translations for the following languages:&lt;br /&gt;
** French&lt;br /&gt;
** Spanish&lt;br /&gt;
** Polish&lt;br /&gt;
** Italian&lt;br /&gt;
** German&lt;br /&gt;
** Dutch&lt;br /&gt;
** Slovak&lt;br /&gt;
** Georgian&lt;br /&gt;
** Russian&lt;br /&gt;
&lt;br /&gt;
== Hardware Device Support ==&lt;br /&gt;
Support for the following hardware devices has been added or updated:&lt;br /&gt;
&lt;br /&gt;
* Honeycomb Alpha Flight Controls&lt;br /&gt;
* Honeycomb Bravo Throttle Quadrant&lt;br /&gt;
* Saitek Pro Flight Rudder Pedals &lt;br /&gt;
* Saitek Pro Flight Switch Panel&lt;br /&gt;
* CH Combatstick&lt;br /&gt;
* Logitech G25 Racing Wheel&lt;br /&gt;
* Thrustmaster T-Flight Rudder Pedals&lt;br /&gt;
&lt;br /&gt;
== AI Traffic &amp;amp; Liveries ==&lt;br /&gt;
&lt;br /&gt;
* Many improvements to make AI aircraft behavior more realistic.&lt;br /&gt;
&lt;br /&gt;
Traffic and/or liveries have been added for the following airlines:&lt;br /&gt;
&lt;br /&gt;
* Delta Airlines&lt;br /&gt;
* United Airlines&lt;br /&gt;
* AeroUnion Mexico&lt;br /&gt;
* AeroMexico&lt;br /&gt;
* AeroMexicoConnect&lt;br /&gt;
* Amerijet Cargo&lt;br /&gt;
* Airest Cargo&lt;br /&gt;
* Air Caraibes&lt;br /&gt;
* DHL&lt;br /&gt;
* Amazon Air&lt;br /&gt;
* EuroWings&lt;br /&gt;
* Polar Air Cargo&lt;br /&gt;
* Northern Air Cargo&lt;br /&gt;
* Eastern Airways UK&lt;br /&gt;
* ANA Wings&lt;br /&gt;
* Ibex Japan&lt;br /&gt;
* Solaseed Japan&lt;br /&gt;
* AirHongKong &lt;br /&gt;
* AirHongKong Cargo&lt;br /&gt;
* AirChina&lt;br /&gt;
* UNI Air Japan&lt;br /&gt;
* Southern Air Cargo&lt;br /&gt;
* SATA Air Acores&lt;br /&gt;
* Azores Airlines&lt;br /&gt;
* European Air Transport Leipzig&lt;br /&gt;
* SykyLeaseCargo&lt;br /&gt;
* Blue Air&lt;br /&gt;
* Cyprus Airways&lt;br /&gt;
* DirectFlight Airtask Shetland&lt;br /&gt;
*&lt;br /&gt;
* Corsair&lt;br /&gt;
* LOT Polish Airlines&lt;br /&gt;
* Braethens&lt;br /&gt;
* Transavia NL&lt;br /&gt;
* Transavia France&lt;br /&gt;
* Tunisair Group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Traffic and/or liveries have been removed for the following airlines:&lt;br /&gt;
&lt;br /&gt;
* GermanWings (defunct)&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
fc16b827a Fix OSM imagery in the canvas map (fixes #2912)**&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;**&amp;lt;/nowiki&amp;gt;f0a740333 Remove OpenAIP map support from Canvas Map (see #2913)**&lt;br /&gt;
&lt;br /&gt;
== Nasal ==&lt;br /&gt;
&lt;br /&gt;
== Phi ==&lt;br /&gt;
&amp;lt;nowiki&amp;gt;**&amp;lt;/nowiki&amp;gt;7b36d498f Fix a variety of broken or unsupported maps in Phi&lt;br /&gt;
&lt;br /&gt;
725ce7d3f Phi: Add map option to disable repositioning own aircraft by dragging&lt;br /&gt;
&lt;br /&gt;
fc3b7b8b5 Phi: Highlight &amp;quot;follow aircraft&amp;quot; button if enabled&lt;br /&gt;
&lt;br /&gt;
5626dc51f Phi: Remove unused css rule&lt;br /&gt;
&lt;br /&gt;
88788dc6a Fix attributes for multiplayer and AI airplanes in Phi (fix #2274)&lt;br /&gt;
&lt;br /&gt;
660fda829 Phi: automatically use latest AIRAC cycle for OpenFlightMaps&lt;br /&gt;
&lt;br /&gt;
57483a999 Phi: fix midnight time offset&lt;br /&gt;
&lt;br /&gt;
== Aircraft Carriers ==&lt;br /&gt;
The following [[Aircraft carrier|Aircraft carriers]] have been added:&lt;br /&gt;
&lt;br /&gt;
* Admiral Kuznetsov&lt;br /&gt;
* Liaoning&lt;br /&gt;
&lt;br /&gt;
== Misc. ==&lt;br /&gt;
f9ad4124f Route manager add total dist, dist remaining, ete, flight time&lt;br /&gt;
&lt;br /&gt;
* Highlighting tool enabled by setting /sim/highlighting/enabled=true which highlights any animated objects under the pointed along with any other objects animated by the same or related properties.&lt;br /&gt;
&lt;br /&gt;
== Legacy ==&lt;br /&gt;
&lt;br /&gt;
* Remove [[Rembrandt]] command-line options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140824</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140824"/>
		<updated>2024-10-25T09:36:39Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Remove unnecessary includes&lt;br /&gt;
** osg/AlphaFunc&lt;br /&gt;
** osg/Material&lt;br /&gt;
** osg/ShadeModel&lt;br /&gt;
** osg/TexEnv&lt;br /&gt;
** osg/TexEnvCombine&lt;br /&gt;
** osg/TexGen&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Remove the one in SGPickAnimation&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
* Check if we still need the ATI viewport hack&lt;br /&gt;
* Revisit the Canvas placement code. Do we need the replacing by texture name anymore?&lt;br /&gt;
&lt;br /&gt;
* Node masks and cull masks are a complete mess. Derive a proper scheme and apply it everywhere. (Will greping for &amp;quot;setNodeMask&amp;quot; be enough?)&lt;br /&gt;
&lt;br /&gt;
== Post core profile checklist ==&lt;br /&gt;
&lt;br /&gt;
* Check if some Effects need porting from ALS&lt;br /&gt;
** bowwave&lt;br /&gt;
** birdswarm&lt;br /&gt;
** Terrain related ones (agriculture, airfield)&lt;br /&gt;
* Port marker pin Effect (probably inheriting from model-pbr).&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140823</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140823"/>
		<updated>2024-10-25T09:21:49Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Remove unnecessary includes&lt;br /&gt;
** osg/AlphaFunc&lt;br /&gt;
** osg/Material&lt;br /&gt;
** osg/ShadeModel&lt;br /&gt;
** osg/TexEnv&lt;br /&gt;
** osg/TexEnvCombine&lt;br /&gt;
** osg/TexGen&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Remove the one in SGPickAnimation&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
* Check if we still need the ATI viewport hack&lt;br /&gt;
* Revisit the Canvas placement code. Do we need the replacing by texture name anymore?&lt;br /&gt;
&lt;br /&gt;
* Node masks and cull masks are a complete mess. Derive a proper scheme and apply it everywhere. (Will greping for &amp;quot;setNodeMask&amp;quot; be enough?)&lt;br /&gt;
&lt;br /&gt;
== Post core profile checklist ==&lt;br /&gt;
&lt;br /&gt;
* Check if some Effects need porting from ALS&lt;br /&gt;
** bowwave&lt;br /&gt;
** birdswarm&lt;br /&gt;
** Terrain related ones (agriculture, airfield)&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140809</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140809"/>
		<updated>2024-10-20T12:42:51Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Remove unnecessary includes&lt;br /&gt;
** osg/AlphaFunc&lt;br /&gt;
** osg/Material&lt;br /&gt;
** osg/ShadeModel&lt;br /&gt;
** osg/TexEnv&lt;br /&gt;
** osg/TexEnvCombine&lt;br /&gt;
** osg/TexGen&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Remove the one in SGPickAnimation&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
* Check if we still need the ATI viewport hack&lt;br /&gt;
* Revisit the Canvas placement code. Do we need the replacing by texture name anymore?&lt;br /&gt;
&lt;br /&gt;
* Node masks and cull masks are a complete mess. Derive a proper scheme and apply it everywhere. (Will greping for &amp;quot;setNodeMask&amp;quot; be enough?)&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140658</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140658"/>
		<updated>2024-10-02T17:18:41Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Remove the one in SGPickAnimation&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
* Check if we still need the ATI viewport hack&lt;br /&gt;
* Revisit the Canvas placement code. Do we need the replacing by texture name anymore?&lt;br /&gt;
&lt;br /&gt;
* Node masks and cull masks are a complete mess. Derive a proper scheme and apply it everywhere. (Will greping for &amp;quot;setNodeMask&amp;quot; be enough?)&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140657</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=140657"/>
		<updated>2024-10-02T17:16:45Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Remove the one in SGPickAnimation&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
* Check if we still need the ATI viewport hack&lt;br /&gt;
* Revisit the Canvas placement code. Do we need the replacing by texture name anymore?&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=140656</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=140656"/>
		<updated>2024-10-02T00:46:32Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders and is only available on 'next' branch or nightly builds (2020.4). The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it. Version 2024.1 will not support HDR.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Animate_models&amp;diff=140504</id>
		<title>Howto:Animate models</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Animate_models&amp;diff=140504"/>
		<updated>2024-09-21T18:41:56Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The real world is full of motion. To simulate this in [[FlightGear]], '''models must be animated'''.&lt;br /&gt;
&lt;br /&gt;
FlightGear allows you to animate models in response to property changes: for example, the propellers can spin when the engine is on and the elevators can move up and down with your controller. There is no fixed limit on what parts can be animated: the only requirements are that the part is named in the 3D model file, and that there is a property in the main tree that you can use to get the positioning information. &lt;br /&gt;
&lt;br /&gt;
This document provides basic information for all kind of animations. When animating your model, it is very helpful to find an aircraft with parts similar to yours and use it as an example. Cut and paste the code into your wrapper file and then edit to suit.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
=== File name of main model and animation XML file ===&lt;br /&gt;
{{main article|Aircraft-set.xml#Not used for loading multiplayer aircraft}}&lt;br /&gt;
The file name of the main model and animation XML file, or the .ac file if there is no XML file, (in essence the property &amp;lt;code&amp;gt;/sim/model/path&amp;lt;/code&amp;gt;) will be the name of the aircraft that is transmitted when using [[multiplayer]] and will also be used for loading multiplayer aircraft.&lt;br /&gt;
&lt;br /&gt;
There is also a mechanism to substitute a full aircraft model with a simpler AI aircraft model if one is available at the same file path (including for example &amp;lt;code&amp;gt;Models/Boeing-797-800.xml&amp;lt;/code&amp;gt;), but in &amp;lt;code&amp;gt;[[$FG_ROOT]]/'''AI'''/Aircraft/&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;$FG_ROOT/Aircraft/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== .ac files ===&lt;br /&gt;
{{Main article|AC files: Understanding and changing .ac code#Identifying an object}}&lt;br /&gt;
&lt;br /&gt;
When referring to an .ac file in your xml animation, it is important that the &amp;lt;code&amp;gt;&amp;lt;object-name&amp;gt;&amp;lt;/code&amp;gt; exactly matches the object named in the .ac file (this includes cases!). &lt;br /&gt;
&lt;br /&gt;
'''Note for SketchUp users:''' The spatial reference X/Y/Z used in animation to locate an object or a point are different from the ones in AC3D ie X values are the same in both but Y in animation must be matched to AC3D's -Z (Z value but opposite sign) and Z value in animation must be matched to AC3D's Y value. &lt;br /&gt;
&lt;br /&gt;
'''Note for SketchUp users:''' when exporting to AC3D in Sketchup, the .ac file will name the objects in your model to &amp;quot;blah&amp;quot; by default. You need to amend the relevant object names in your .ac file using text edit, so that the xml will work.&lt;br /&gt;
&lt;br /&gt;
=== Animation order ===&lt;br /&gt;
Animations are executed by FlightGear in the order that they are read in the model's .xml file. Therefore, it is very important to pay attention to the order, especially when multiple animations are applied to the same object(s). Wrong ordering of animations might cause [[Howto:Animate models#Timed|timed]] animations (used to create flashing lights) to not work. For further details see this [https://sourceforge.net/p/flightgear/mailman/message/37090714/ thread] on the development mailing list. Updated [https://scenery.flightgear.org/app.php?c=Models&amp;amp;a=browse&amp;amp;shared=18 shared Effects models] will be available very soon.&lt;br /&gt;
&lt;br /&gt;
Similar problems can be encountered with the dist-scale instead of the timed animation.&lt;br /&gt;
== Tags used in most animations ==&lt;br /&gt;
=== Name ===&lt;br /&gt;
With a name animation, you can group multiple objects. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Collection1&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object1&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object2&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object3&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example above creates a &amp;quot;virtual object&amp;quot; with the name Collection1. In animation, we can animate this group of objects, by using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;object-name&amp;gt;Collection1&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object-name ===&lt;br /&gt;
These names are set in the 3D model. Each single object has a unique name; for easy identification it is advised to use descriptive names (LeftElevator, Rudder etc.). Animations are only applied to those objects that are mentioned in an object-name line (one object per line!). Animations lacking those, will be applied to the entire model.&lt;br /&gt;
&lt;br /&gt;
=== Property ===&lt;br /&gt;
Each animation must be associated with exactly one property from the main FlightGear property tree (remember that the properties in the wrapper file are not part of the main tree), using &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; to provide the property path:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Rudder&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;controls/rudder&amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the omission of the leading slash '/' when referring to the property. This assures that when the model is used for AI or multiplayer traffic the animations will follow that of the AI controller instead of that of the user.&lt;br /&gt;
&lt;br /&gt;
=== Axis ===&lt;br /&gt;
An axis part is required in every animation that involves a rotating or moving thing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The axis are similar to the ones of the 3D model. There is a difference between rotation and translation:&lt;br /&gt;
* In rotation animations, the axis part defines around what axis the object rotates. Negative/positive values make the difference between counterclockwise and clockwise rotations.&lt;br /&gt;
* In translate animations, the part defines along what axis the object moves. If the x-axis is poiting backwards, an x-value of -1 will result in forward motion.&lt;br /&gt;
&lt;br /&gt;
You could also define two points, between which FlightGear will calculate the correct axis. This makes the use of a [[#Center|&amp;lt;nowiki&amp;gt;&amp;lt;center&amp;gt;&amp;lt;/nowiki&amp;gt;]] tag redundant! Such coordinates are extremely useful for animating control surfaces (rudder, elevators etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;   &lt;br /&gt;
   &amp;lt;x1-m&amp;gt; 4.9&amp;lt;/x1-m&amp;gt;&lt;br /&gt;
   &amp;lt;y1-m&amp;gt; 7.1&amp;lt;/y1-m&amp;gt;&lt;br /&gt;
   &amp;lt;z1-m&amp;gt;-1.0&amp;lt;/z1-m&amp;gt;&lt;br /&gt;
   &amp;lt;x2-m&amp;gt; 5.9&amp;lt;/x2-m&amp;gt;&lt;br /&gt;
   &amp;lt;y2-m&amp;gt;11.2&amp;lt;/y2-m&amp;gt;&lt;br /&gt;
   &amp;lt;z2-m&amp;gt;-0.5&amp;lt;/z2-m&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Center ===&lt;br /&gt;
Various animations ([[#Rotate|rotate]], [[#Spin|spin]], [[#Scale|scale]]) move around a center point.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The axis are similar to the ones of the 3D model, so finding coordinates is easily done in 3D modeling software.&lt;br /&gt;
&lt;br /&gt;
=== Using a geometry object for axis and centre (2017.2) ===&lt;br /&gt;
&lt;br /&gt;
Added in V2017.2 is support to allow a geometry object (a line segment with two vertices) that is used to define both the centre and the axis for an animation. This will work with rotate, spin, translate and knob animations.&lt;br /&gt;
&lt;br /&gt;
{{Note|Since SimGear commit 6ca9141083e62be1161d0ca2d1e3b918494dd6ad on next, this feature can also be used for slider (usage equivalent to that for a translate animation) and for any of the &amp;lt;*-center&amp;gt; / &amp;lt;*-axis&amp;gt; tags of a locked-track animation.}}&lt;br /&gt;
&lt;br /&gt;
When used for translate animations, the axis line should be normalized (i.e. be 1 meter long) as its length acts as a factor for the translation distance.&lt;br /&gt;
&lt;br /&gt;
The XML syntax for this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;axis&amp;gt;&lt;br /&gt;
    &amp;lt;object-name&amp;gt;some-object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;&amp;lt;axis&amp;gt;...&amp;lt;/axis&amp;gt;&amp;lt;/code&amp;gt; section is omitted entirely, &amp;lt;code&amp;gt;{object-name}-axis&amp;lt;/code&amp;gt; will be used by default, where &amp;lt;code&amp;gt;{object-name}&amp;lt;/code&amp;gt; is the name of the object being animated (if we are animating more than one object, the first object is used). In the earlier example this would be &amp;lt;code&amp;gt;Rudder-axis&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Vertex Ordering ==== &lt;br /&gt;
&lt;br /&gt;
With FG &amp;lt;= 2020.3 the order of the points in the vertex will be sorted based on their X coordinate and when the X coordinate is equal the order will be that of the vertices in the model. &lt;br /&gt;
&lt;br /&gt;
This has been improved in 2020.4 by adding some new tags that can be used in the &amp;lt;axis&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;order-by-xyz/&amp;gt; - use the new sorting rules&lt;br /&gt;
# &amp;lt;order-by-x/&amp;gt; - use the 2020.3 sorting rules&lt;br /&gt;
# &amp;lt;swap-axis-direction/&amp;gt; - when the animation goes the wrong way this is an elegant way to fix it.&lt;br /&gt;
&lt;br /&gt;
There is also a new top level tag &amp;lt;defaults&amp;gt; that can have either &amp;lt;axis-animation-vertex-order-xyz/&amp;gt; or &amp;lt;axis-animation-vertex-order-x/&amp;gt;. These defaults will affect all animations in the .xml and also any included models unless the included model also has a &amp;lt;defaults&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
So for modelers that want to use the new definitive vertex sorting rules adding the following to the main model is sufficient.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
    &amp;lt;defaults&amp;gt;&lt;br /&gt;
        &amp;lt;axis-animation-vertex-order-xyz/&amp;gt;&lt;br /&gt;
    &amp;lt;/defaults&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Adding the axis animation 3d object to a model ==== &lt;br /&gt;
&lt;br /&gt;
In the '''.ac''' file, specify a SURF with type (bottom 4 bits, 0=polygon, 1=closedline, 2=line) set to 2, and two vertices that define the axis. For example:&lt;br /&gt;
&lt;br /&gt;
    OBJECT poly&lt;br /&gt;
    name &amp;quot;aileron.l-axis&amp;quot;&lt;br /&gt;
    numvert 2&lt;br /&gt;
    3.2077502191170844 0.18160835055097943 4.055616960642423&lt;br /&gt;
    2.6758650763079 0.28024033462188946 6.477876098622225&lt;br /&gt;
    numsurf 1&lt;br /&gt;
    SURF 0x12&lt;br /&gt;
    mat 0&lt;br /&gt;
    refs 2&lt;br /&gt;
    0 0 0&lt;br /&gt;
    1 0 0&lt;br /&gt;
    kids 0&lt;br /&gt;
&lt;br /&gt;
Once the object-name used for the axis has been processed the geometry object will be hidden. This also allows a visual check for any axis objects that are not yet assigned.&lt;br /&gt;
&lt;br /&gt;
It is possible to reuse the same object definition multiple times within a single XML file. &lt;br /&gt;
&lt;br /&gt;
[[File:Canopy-animation-axis-object.png|small|Illustration of where an axis object (2017.2) can be placed for a canopy]]&lt;br /&gt;
&lt;br /&gt;
[[File:Gauges-knobs-animation-axis-object.png|small|Illustration of where an axis object (2017.2) can be placed for cockpit elements]]&lt;br /&gt;
&lt;br /&gt;
== Additional tags that can be used in most animations ==&lt;br /&gt;
=== Conditions ===&lt;br /&gt;
Multiple animations can make use of a conditional. Check &amp;lt;tt&amp;gt;$FGDATA/Docs/README.conditions&amp;lt;/tt&amp;gt; for some more details.&lt;br /&gt;
&lt;br /&gt;
* '''equals:''' property value (or second property) is equal to value/(first)property.&lt;br /&gt;
* '''greater-than:''' property value (or second property) is larger than value/(first)property.&lt;br /&gt;
* '''greater-than-equals:''' property value (or second property) is greater than or equal to value/(first)property.&lt;br /&gt;
* '''less-than:''' property value (or second property) is smaller than value/(first)property.&lt;br /&gt;
* '''less-than-equals:''' property value (or second property) is smaller than or equal to value/(first)property.&lt;br /&gt;
&lt;br /&gt;
The example below is true when n1 has a value greater than 25.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then there are some special tags:&lt;br /&gt;
&lt;br /&gt;
* '''and:'''&lt;br /&gt;
* '''not:'''&lt;br /&gt;
* '''or:'''&lt;br /&gt;
&lt;br /&gt;
In the example below, the condition is true when either n1 is greater than 25% or equal to 0%.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;or&amp;gt;&lt;br /&gt;
    &amp;lt;greater-than&amp;gt;&lt;br /&gt;
     &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
     &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
    &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;equals&amp;gt;&lt;br /&gt;
     &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
     &amp;lt;value&amp;gt;0&amp;lt;/value&amp;gt;&lt;br /&gt;
    &amp;lt;/equals&amp;gt;&lt;br /&gt;
   &amp;lt;/or&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of implementation into an animation looks as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;suface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;suface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;10&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interpolation ===&lt;br /&gt;
For non-fixed factors, an interpolation &amp;quot;table&amp;quot; can be created. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;interpolation&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 0.0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.0&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 0.667&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.0&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 1.0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.5&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
  &amp;lt;/interpolation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The lines above represent the following table:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Input&lt;br /&gt;
!Output&lt;br /&gt;
|-&lt;br /&gt;
|0.0&lt;br /&gt;
|0.0&lt;br /&gt;
|-&lt;br /&gt;
|0.667&lt;br /&gt;
|0.0&lt;br /&gt;
|-&lt;br /&gt;
|1.0&lt;br /&gt;
|0.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can add as many entries as you need. Interpolation tables are often used for gear animations (eg. to open doors during gear-movements and close them again once the gear is either retracted or fully extended).&lt;br /&gt;
&lt;br /&gt;
=== Expressions ===&lt;br /&gt;
For some animations it is possible to define complex animations by using [[Expressions|Expressions]]. This even allows to drive the animation from multiple properties without the need for additional Nasal scripts. Here is an example for a translate animation depending on two properties and the cosine function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
     &amp;lt;type&amp;gt;translate&amp;lt;/type&amp;gt;&lt;br /&gt;
     &amp;lt;expression&amp;gt;&lt;br /&gt;
       &amp;lt;product&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/my/factor-property&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;cos&amp;gt;&lt;br /&gt;
           &amp;lt;deg2rad&amp;gt;&lt;br /&gt;
             &amp;lt;property&amp;gt;/my/angular-property&amp;lt;/property&amp;gt;&lt;br /&gt;
           &amp;lt;/deg2rad&amp;gt;&lt;br /&gt;
         &amp;lt;/cos&amp;gt;&lt;br /&gt;
       &amp;lt;/product&amp;gt;&lt;br /&gt;
     &amp;lt;/expression&amp;gt;&lt;br /&gt;
     [..]more elements[..]&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Animations which can utilize [[Expressions|Expressions]] are: &lt;br /&gt;
* [[Howto:Animate_models#Translate|Translate]]&lt;br /&gt;
* [[Howto:Animate_models#Rotate|Rotate]]&lt;br /&gt;
* [[Howto:Animate_models#Scale|Scale]]&lt;br /&gt;
* [[Howto:Animate_models#Range|Range]]&lt;br /&gt;
* [[Howto:Animate_models#Blend|Blend]]&lt;br /&gt;
* [[Howto:Animate_models#Material animation|Material]]&lt;br /&gt;
* [[Howto:Animate_models#PBR animation|PBR]]&lt;br /&gt;
&lt;br /&gt;
See more detailed info at [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
== Lights ==&lt;br /&gt;
As of January 2021 FlightGear supports multiple light sources just like Project Rembrandt has always done.&lt;br /&gt;
[[Compositor#Lights|Adding lights to a model]]&lt;br /&gt;
&lt;br /&gt;
== Object animations ==&lt;br /&gt;
=== Alpha-test ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;alpha-test&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;alpha-factor&amp;gt;0.01&amp;lt;/alpha-factor&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This &amp;quot;animation&amp;quot; is a way to set an alpha test on a model branch. The effect is to avoid depth buffer writing of pixel that are not seen because they are transparent. This is particulary useful when modeling a metallic structure or a tree with a billboard. The threshold of transparency is set with the &amp;lt;alpha-factor&amp;gt; element.  See also [[Pixel testing in effects]].&lt;br /&gt;
&lt;br /&gt;
=== Blend ===&lt;br /&gt;
Blends an object with the surrounding. Comparable to a translucency animation. A value of 0 corresponds to no transparency, i.e. and ordinary solid object, and a value of 1 makes the object fully transparent, i.e., not visible at all.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;blend&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;/velocities/airspeed-kt&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;0.00025&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;min&amp;gt;0.2&amp;lt;/min&amp;gt;&lt;br /&gt;
  &amp;lt;max&amp;gt;0.7&amp;lt;/max&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''property:'''&lt;br /&gt;
* '''factor:'''&lt;br /&gt;
* '''min:'''&lt;br /&gt;
* '''max:'''&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
Note that when using the Project Rembrandt renderer, all transparent and translucent objects must be registered to display properly.  [[Project_Rembrandt#Registering_all_translucent_surfaces|More information here.]]&lt;br /&gt;
&lt;br /&gt;
=== Billboard ===&lt;br /&gt;
This faces an object towards the viewer. Often used on 2D objects, like clouds, trees and lights.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;billboard&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;spherical type=&amp;quot;bool&amp;quot;&amp;gt;true&amp;lt;/spherical&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''spherical:'''&lt;br /&gt;
&lt;br /&gt;
=== Dist-scale ===&lt;br /&gt;
Used to scale an object, based on the distance to the viewer. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;ind&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;dep&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (independent and dependent) are the distance in meters and the scale at that distance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;dist-scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;interpolation&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;1&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;300&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;4&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;1500&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;8&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
  &amp;lt;/interpolation&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can optionally add [[#Center|&amp;amp;lt;center&amp;amp;gt;]] coordinates, to scale the object around that point.&lt;br /&gt;
&lt;br /&gt;
=== Flash ===&lt;br /&gt;
&lt;br /&gt;
Used to scale an object based on the cosine of the angle between the axis provided in the animation and the view vector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;flash&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;offset&amp;gt;0.0&amp;lt;/offset&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;1.0&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;power&amp;gt;2&amp;lt;/power&amp;gt;&lt;br /&gt;
  &amp;lt;two-sides type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/two-sides&amp;gt;&lt;br /&gt;
  &amp;lt;min&amp;gt;0.0&amp;lt;/min&amp;gt;&lt;br /&gt;
  &amp;lt;max&amp;gt;1.0&amp;lt;/max&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;0.0&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt;0.0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt;0.0&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0.0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;-1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0.1&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''offset:'''&lt;br /&gt;
* '''factor:'''&lt;br /&gt;
* '''power:'''&lt;br /&gt;
* '''two-sides:''' if false, nothing is drawn if the cosine is negative.&lt;br /&gt;
* '''min:'''&lt;br /&gt;
* '''max:'''&lt;br /&gt;
&lt;br /&gt;
scale = factor * pow( cosine, power ) + offset&lt;br /&gt;
&lt;br /&gt;
scale is then clamped between min and max.&lt;br /&gt;
&lt;br /&gt;
and this scale factor is applied to the object, from the center specified. It works best if scale is less than 1. Otherwise, there will be clipping issues.&lt;br /&gt;
&lt;br /&gt;
=== Noshadow ===&lt;br /&gt;
This animation is used to make sure an object will cast no shadow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;noshadow&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
: ''See also [[Modeling - Getting Started#Level of Detail (LOD)]].''&lt;br /&gt;
&lt;br /&gt;
To prevent objects -like instruments- being drawn when the aircraft is actually too far away for them to be seen anyway, a range animation is used. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;range&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;min-m&amp;gt;0&amp;lt;/min-m&amp;gt;&lt;br /&gt;
  &amp;lt;max-m&amp;gt;30&amp;lt;/max-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''min-m:''' the shortest distance (in meters) from the object center at which it is visible.&lt;br /&gt;
* '''max-m:''' the largest distance (in meters) from the object center at which it is visible.&lt;br /&gt;
&lt;br /&gt;
You could also use the generic level of detail (LOD) properties, which can be set by the user through View &amp;gt; Adjust LOD rangers: &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Property&lt;br /&gt;
! Description&lt;br /&gt;
! Default value&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/bare&amp;lt;/tt&amp;gt;&lt;br /&gt;
| only a rough exterior model&lt;br /&gt;
| 30,000 m&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/rough&amp;lt;/tt&amp;gt; &lt;br /&gt;
| most should be visible&lt;br /&gt;
| 9,000 m&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/detailed&amp;lt;/tt&amp;gt; &lt;br /&gt;
| all details should be visible&lt;br /&gt;
| 1,500 m&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The animation code will look like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;range&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;min-m&amp;gt;0&amp;lt;/min-m&amp;gt;&lt;br /&gt;
  &amp;lt;max-property&amp;gt;sim/rendering/static-lod/bare&amp;lt;/max-property&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can have both ranges (max and min) bound to a property, or just one of them.&lt;br /&gt;
* '''min-property:''' &lt;br /&gt;
* '''max-property:'''&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Rotate ===&lt;br /&gt;
One of the most important and frequently used animations of all. It rotates an object to an absolute position in degrees, as provided by the property-value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;surface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-deg&amp;gt;25&amp;lt;/offset-deg&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
* '''offset-deg:''' is optional. Offset in degrees.&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Scale ===&lt;br /&gt;
A scale animation scales (resizes) an object. This can be either property-value dependant (first example) or a fixed scale (second example).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;sim/time/sun-angle-rad&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;x-min&amp;gt;1.0&amp;lt;/x-min&amp;gt;&lt;br /&gt;
  &amp;lt;y-min&amp;gt;1.0&amp;lt;/y-min&amp;gt;&lt;br /&gt;
  &amp;lt;z-min&amp;gt;1.0&amp;lt;/z-min&amp;gt;&lt;br /&gt;
  &amp;lt;x-factor&amp;gt;1.4&amp;lt;/x-factor&amp;gt;&lt;br /&gt;
  &amp;lt;y-factor&amp;gt;1.4&amp;lt;/y-factor&amp;gt;&lt;br /&gt;
  &amp;lt;z-factor&amp;gt;2.0&amp;lt;/z-factor&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ?-min: the mimimum scale factor for each axis. If the property value would result in a smaller factor than this setting, the scale animation will hold.&lt;br /&gt;
* ?-factor: the scale factor for each axis (factor*property=scale factor).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;x-offset&amp;gt;0.5&amp;lt;/x-offset&amp;gt;&lt;br /&gt;
  &amp;lt;y-offset&amp;gt;0.5&amp;lt;/y-offset&amp;gt;&lt;br /&gt;
  &amp;lt;z-offset&amp;gt;0.5&amp;lt;/z-offset&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* x.offset: the scale factor.&lt;br /&gt;
* Add [[#Center|&amp;amp;lt;center&amp;amp;gt;]] coordinates, to scale the object around that point.&lt;br /&gt;
* '''You can optionally use an [[Howto:Animate_models#Expressions|expression]] in the &amp;lt;factor&amp;gt; or &amp;lt;offset&amp;gt; inputs.''' For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Select ===&lt;br /&gt;
This animation selects (or unselects) objects when certain conditions are true (or false). The example below shows the object when the n1 of engine[1] is higher than 25%.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;engines/engine[0]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Shader ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;shader&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;shader&amp;gt;chrome&amp;lt;/shader&amp;gt;&lt;br /&gt;
  &amp;lt;texture&amp;gt;chrome2.png&amp;lt;/texture&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''shader:''' &lt;br /&gt;
* '''texture:''' path to the texture used by the shader.&lt;br /&gt;
&lt;br /&gt;
=== Spin ===&lt;br /&gt;
Very similar to [[#Rotate|rotate]], but the property provides a value in revolutions per minute (RPM) rather than an absolute position in degrees, and offset cannot be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spin&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;engines/engine[0]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
&lt;br /&gt;
=== Timed ===&lt;br /&gt;
Swtiches between objects at specified intervals. This example switches between a lights-on model and a lights-off model. Lights on are shown 0.2 seconds, while lights off are displayed for 0.8 seconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;timed&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;BacklightOn&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;BacklightOff&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;use-personality type=&amp;quot;bool&amp;quot;&amp;gt;true&amp;lt;/use-personality&amp;gt;&lt;br /&gt;
  &amp;lt;branch-duration-sec&amp;gt;0.8&amp;lt;/branch-duration-sec&amp;gt;&lt;br /&gt;
  &amp;lt;branch-duration-sec&amp;gt;0.2&amp;lt;/branch-duration-sec&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tracking ===&lt;br /&gt;
A ''locked-track animation'' can do exactly the same thing as the [https://docs.blender.org/manual/en/latest/animation/constraints/tracking/locked_track.html Locked Track constraint] available in Blender and can also be used to simulate simple inverse kinematic systems consisting of two bones connected with a revolute joint (aka hinge). For details see: [[Howto:Animate gear scissors using the tracking animation]]&lt;br /&gt;
&lt;br /&gt;
=== Translate ===&lt;br /&gt;
This animation moves an object along an axis (not to be confused with the &amp;lt;code&amp;gt;textranslate&amp;lt;/code&amp;gt; animation which only moves the texture on the UV map, not the geometry). The example below will move an object in the Y direction:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; &lt;br /&gt;
!Property value&lt;br /&gt;
!Output&lt;br /&gt;
|-&lt;br /&gt;
| -1&lt;br /&gt;
| -2.5&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 2.5&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 7.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;translate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;controls/seat/pilot/position-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;5&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-m&amp;gt;2.5&amp;lt;/offset-m&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using interpolation tables such as:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;interpolation&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;0.0&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt; 0&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;0.666&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt;0.18&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;1.0&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt;0.27&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
&amp;lt;/interpolation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The first figure (&amp;lt;code&amp;gt;&amp;lt;ind&amp;gt;&amp;lt;/code&amp;gt;) refers to the value of the property associated with the object and the second figure (&amp;lt;code&amp;gt;&amp;lt;dep&amp;gt;&amp;lt;/code&amp;gt;) refers to the amount that the object moves in metres. For example, in this case, the object moves 18cm when the value reads 0.66 and 27cm when the value is 1.&lt;br /&gt;
&lt;br /&gt;
'''IF used WTIHOUT property''' : The object is placed at some (Value of Offset) meters away from its original position, along the virtual axis formed by said original position and the point with coordinates x/y/z defined in the &amp;lt;axis&amp;gt; tag.&lt;br /&gt;
Mathematically, assuming the Object to translate is (in the model space) placed at point A (x1, y1, z1) and you want to relocate it to point B (x2, y2, z2) then x2,y2,z2 are the values in the &amp;lt;axis&amp;gt; tag of the Translate animation and &amp;lt;offset&amp;gt; can be computed as SQRT((x2-x1)^2+(y2-y1)^2+(z2-z1)^2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
* '''offset-m:''' is optional. Offset in meters.&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
== PBR animation ==&lt;br /&gt;
&lt;br /&gt;
Animate the PBR (Physically-Based Rendering) materials. Keep in mind that your model must use the model-pbr.eff Effect or be a [[glTF]] model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;pbr&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/c172p/material/&amp;lt;/property-base&amp;gt;&lt;br /&gt;
  &amp;lt;base-color-factor&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.3&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.1&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1.0&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/base-color-factor&amp;gt;&lt;br /&gt;
  &amp;lt;metallic-factor&amp;gt;0.0&amp;lt;/metallic-factor&amp;gt;&lt;br /&gt;
  &amp;lt;roughness-factor&amp;gt;0.3&amp;lt;/roughness-factor&amp;gt;&lt;br /&gt;
  &amp;lt;emissive-factor&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/emissive-factor&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;property-base&amp;lt;/tt&amp;gt;: All other properties of this animation will be relative to this property node.&lt;br /&gt;
* &amp;lt;tt&amp;gt;base-color-factor&amp;lt;/tt&amp;gt;: The base color texture will be multiplied by this value. Should be an RGBA color.&lt;br /&gt;
* &amp;lt;tt&amp;gt;metallic-factor&amp;lt;/tt&amp;gt;: The metallic texture will be multiplied by this value. Should be a single floating point value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;roughness-factor&amp;lt;/tt&amp;gt;: The roughness texture will be multiplied by this value. Should be a single floating point value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;emissive-factor&amp;lt;/tt&amp;gt;: The emissive texture will be multiplied by this value. Should be an RGB color.&lt;br /&gt;
&lt;br /&gt;
For each of the color components you can use an [[expression]]. Every parameter is '''optional'''.&lt;br /&gt;
&lt;br /&gt;
== Material animation ==&lt;br /&gt;
Animate the material properties of an object, such as it's texture, shininess or color.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt; &lt;br /&gt;
  &amp;lt;type&amp;gt;material&amp;lt;/type&amp;gt; &lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/c172p/material&amp;lt;/property-base&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  lines as mentioned below&lt;br /&gt;
  ...&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Optional:'''&lt;br /&gt;
* '''property-base:''' All other properties of this animation will be relative to this property node.&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Numbers are clamped to 0.0 - 1.0, except &amp;lt;code&amp;gt;shininess&amp;lt;/code&amp;gt;, which is clamped to 0 - 128.&lt;br /&gt;
* By appending &amp;lt;tt&amp;gt;-prop&amp;lt;/tt&amp;gt; each of the material properties can read its value from another property.&lt;br /&gt;
* '''New since SimGear commit &amp;lt;code&amp;gt;51149bf&amp;lt;/code&amp;gt;''': For each of the color components (&amp;lt;code&amp;gt;ambient&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;diffuse&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;emission&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;specular&amp;lt;/code&amp;gt;), the &amp;lt;code&amp;gt;red&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;green&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;blue&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;factor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; tags can each contain an [[Expressions|expression]] instead of a value.&lt;br /&gt;
&lt;br /&gt;
=== Ambient ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/ambient&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Diffuse ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/diffuse&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Emission ===&lt;br /&gt;
{{Main article|Howto: Illuminate faces}}&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;emission&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
   &amp;lt;factor-prop&amp;gt;controls/lighting/panel-norm&amp;lt;/factor-prop&amp;gt;&lt;br /&gt;
  &amp;lt;/emission&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Emission colors are multiplied by the factor-prop value. 1 is maximum color intensity, while 0 is the minimum. Colors are calculated according to the [http://en.wikipedia.org/wiki/RGB_color_model RGB color model].&lt;br /&gt;
&lt;br /&gt;
=== Specular ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;specular&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/specular&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Transparency ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;transparency&amp;gt;&lt;br /&gt;
   &amp;lt;alpha-prop&amp;gt;rotors/tail/rpm&amp;lt;/alpha-prop&amp;gt;&lt;br /&gt;
   &amp;lt;factor&amp;gt;-0.0015&amp;lt;/factor&amp;gt;&lt;br /&gt;
   &amp;lt;offset&amp;gt;1&amp;lt;/offset&amp;gt;&lt;br /&gt;
  &amp;lt;/transparency&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Shininess ===&lt;br /&gt;
Shininess is clamped to 0-128.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;shininess&amp;gt;105&amp;lt;/shininess&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threshold ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;threshold&amp;gt;0.001&amp;lt;/threshold&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Texture ===&lt;br /&gt;
Used for the [[Livery over MP]] system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/livery&amp;lt;/property-base&amp;gt; &lt;br /&gt;
  &amp;lt;texture-prop&amp;gt;engine&amp;lt;/texture-prop&amp;gt; &lt;br /&gt;
  &amp;lt;texture&amp;gt;KLM.png&amp;lt;/texture&amp;gt; &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Texture Animations ==&lt;br /&gt;
Applying different matrix transformations to the textures of an object.&lt;br /&gt;
&lt;br /&gt;
=== Textranslate ===&lt;br /&gt;
A very important animation for cockpits! This animation moves textures over a surface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;textranslate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;autopilot/settings/target-speed-kt&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;bias&amp;gt;0.0001&amp;lt;/bias&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;0.001&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;step&amp;gt;100&amp;lt;/step&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''bias:''' Adds an offset to the property before factor/step. A small value is needed to compensate for [http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems floating point accuracy].&lt;br /&gt;
* '''factor:''' property * factor * texture width/height = the amount of pixels that the texture should be translated. If your texture is 256 pixels, an textranslate of 0.1 will result in the texture moving with 26 pixels, into the direction specified by the axis settings.&lt;br /&gt;
* '''step:''' the step size at which the texture is translated. If this is set to 0.1, the texture will only be translated at 0.1, 0.2, 0.3 etc.&lt;br /&gt;
* '''axis:''' the direction in which the texture is translated. Y is up/down, while X is left/right.&lt;br /&gt;
&lt;br /&gt;
=== Texrotate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;texrotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;some/property/path&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-deg&amp;gt;25&amp;lt;/offset-deg&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;0.5&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0.5&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;1&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Textrapezoid ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;textrapezoid&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;HUD.l.canvas&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;/hud/trapezoid-correction&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;side&amp;gt;bottom&amp;lt;/side&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''side''': side of quad which should be scaled (''top'' (default)/''right''/''bottom''/''left'')&lt;br /&gt;
&lt;br /&gt;
=== Texmultiple ===&lt;br /&gt;
&lt;br /&gt;
Only one texture matrix can be applied to each object. With ''textmultiple'' multiple texture animations can be combined into a single matrix, applied to the specified object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;texmultiple&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;HUD.l.canvas&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textranslate&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/offset-x&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;axis&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;1&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/axis&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textranslate&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/offset-y&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;axis&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/axis&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textrapezoid&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/trapezoid-correction&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object interaction animations ==&lt;br /&gt;
=== Enable-hot ===&lt;br /&gt;
Scenery objects are automatically defined as solid by FlightGear, meaning that an aircraft can taxi on them and/or crash when touching. For certain objects (groundmarkings, beacon light-beams etc.) this might be an unwanted feature. The solidness can be disabled with the following animation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;enable-hot type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/enable-hot&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''enable-hot:''' can be either true or false. Remember that objects are automatically solid, so it should not be necessary to set this at all when wanting solidness.&lt;br /&gt;
&lt;br /&gt;
=== Interactions ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt; &lt;br /&gt;
  &amp;lt;type&amp;gt;interaction&amp;lt;/type&amp;gt; &lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt; &lt;br /&gt;
  &amp;lt;interaction-type&amp;gt;carrier-wire&amp;lt;/interaction-type&amp;gt; &lt;br /&gt;
 &amp;lt;/animation&amp;gt; &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''interaction-type:''' can have the following values:&lt;br /&gt;
**'''carrier-catapult:'''&lt;br /&gt;
** '''carrier-wire:''' makes the object act as an arresting wire, as used on [[aircraft carrier]]s.&lt;br /&gt;
&lt;br /&gt;
== Direct manipulation animations ==&lt;br /&gt;
=== Knob / slider (v. 2.11-) ===&lt;br /&gt;
{{Main article|Knob / slider animation}}&lt;br /&gt;
&lt;br /&gt;
=== Pick ===&lt;br /&gt;
{{Main article|Howto: Make a clickable panel#Pick}}&lt;br /&gt;
&lt;br /&gt;
=== Touch ===&lt;br /&gt;
&lt;br /&gt;
The touch animation provides the normalized coordinates of a touch (or click) event on a 2d surface. The coordinates are passed in the argument and can be accessed using cmdarg() in Nasal.&lt;br /&gt;
&lt;br /&gt;
* Touch animation is designed to work with a quad that is being used as a Canvas placement (display).&lt;br /&gt;
* The touch animation must not be combined with a pick animation on the same object.&lt;br /&gt;
* More info here: [[Touch Animation]]&lt;br /&gt;
&lt;br /&gt;
==== touch example ====&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;animation&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;touch&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;visible&amp;gt;true&amp;lt;/visible&amp;gt;&lt;br /&gt;
        &amp;lt;object-name&amp;gt;CanvasPlacement&amp;lt;/object-name&amp;gt;&lt;br /&gt;
        &amp;lt;action&amp;gt;&lt;br /&gt;
            &amp;lt;touch&amp;gt;0&amp;lt;/touch&amp;gt;&lt;br /&gt;
            &amp;lt;repeatable&amp;gt;false&amp;lt;/repeatable&amp;gt;&lt;br /&gt;
            &amp;lt;binding&amp;gt;&lt;br /&gt;
                &amp;lt;command&amp;gt;nasal&amp;lt;/command&amp;gt;&lt;br /&gt;
                &amp;lt;script&amp;gt;print(&amp;quot;touch input (&amp;quot;,cmdarg().getNode(&amp;quot;x&amp;quot;).getValue(),&amp;quot;,&amp;quot;,cmdarg().getNode(&amp;quot;y&amp;quot;).getValue())&amp;lt;/script&amp;gt;&lt;br /&gt;
            &amp;lt;/binding&amp;gt;&lt;br /&gt;
        &amp;lt;/action&amp;gt;&lt;br /&gt;
    &amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Shadow Handling ==&lt;br /&gt;
There exist several possibilites for handling of shadows. &amp;lt;br /&amp;gt;&lt;br /&gt;
See '''[[ALS_technical_notes|ALS Technical Notes]]''' and more specific '''[[ALS_technical_notes#ALS_fuselage_shadow_effect|Fuselage Shadow Effect with ALS]]''' for a relatively simple shadow handling.&amp;lt;br /&amp;gt;&lt;br /&gt;
See '''[[Project Rembrandt]]''' which - amongst other functionality - implements a very realistic shadow mapping.&lt;br /&gt;
As of January 2021 Project Rembrandt was replaced by the '''[[Compositor]]''' renderer which combines both Project Rembrandt and ALS in a single rendering engine. This also means that the Fuselage Shadow Effect with ALS is now deprecated.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://www.opensubscriber.com/message/flightgear-devel@flightgear.org/958955.html |title=&amp;quot;material&amp;quot; animation (and the bo105 as an example) |first=Melchior |last=Franz |date=22 March 2005 |work=FlightGear-devel mailinglist }}&lt;br /&gt;
* {{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg01546.html |title=flash animation |first=Frederic |last=Bouvier |date=22 Feb 2006 |work=FlightGear-devel mailinglist }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Wiki articles ===&lt;br /&gt;
* [[MP Fallback models]]&lt;br /&gt;
* [[Howto:Animate gear scissors]]&lt;br /&gt;
* [[Howto:Animate helicopters]]&lt;br /&gt;
* [[Howto:Creating 3D instruments]]&lt;br /&gt;
&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=37353|title=3d models, how to produce them in an understandable way}} (April 2020-) - Touches on the subject of not using LOD range animations in scenery models.&lt;br /&gt;
* {{forum link|t=36545|title=speedo Drum settings}} (November 2019) - Animating a mechanical multi-digit drum counter&lt;br /&gt;
&lt;br /&gt;
[[Category:Aircraft enhancement|Animate models]]&lt;br /&gt;
[[Category:Howto|Animate models]]&lt;br /&gt;
[[Category:Modeling|Animate models]]&lt;br /&gt;
[[Category:Scenery enhancement|Animate models]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Animate_models&amp;diff=140503</id>
		<title>Howto:Animate models</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Animate_models&amp;diff=140503"/>
		<updated>2024-09-21T18:40:12Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The real world is full of motion. To simulate this in [[FlightGear]], '''models must be animated'''.&lt;br /&gt;
&lt;br /&gt;
FlightGear allows you to animate models in response to property changes: for example, the propellers can spin when the engine is on and the elevators can move up and down with your controller. There is no fixed limit on what parts can be animated: the only requirements are that the part is named in the 3D model file, and that there is a property in the main tree that you can use to get the positioning information. &lt;br /&gt;
&lt;br /&gt;
This document provides basic information for all kind of animations. When animating your model, it is very helpful to find an aircraft with parts similar to yours and use it as an example. Cut and paste the code into your wrapper file and then edit to suit.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
=== File name of main model and animation XML file ===&lt;br /&gt;
{{main article|Aircraft-set.xml#Not used for loading multiplayer aircraft}}&lt;br /&gt;
The file name of the main model and animation XML file, or the .ac file if there is no XML file, (in essence the property &amp;lt;code&amp;gt;/sim/model/path&amp;lt;/code&amp;gt;) will be the name of the aircraft that is transmitted when using [[multiplayer]] and will also be used for loading multiplayer aircraft.&lt;br /&gt;
&lt;br /&gt;
There is also a mechanism to substitute a full aircraft model with a simpler AI aircraft model if one is available at the same file path (including for example &amp;lt;code&amp;gt;Models/Boeing-797-800.xml&amp;lt;/code&amp;gt;), but in &amp;lt;code&amp;gt;[[$FG_ROOT]]/'''AI'''/Aircraft/&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;$FG_ROOT/Aircraft/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== .ac files ===&lt;br /&gt;
{{Main article|AC files: Understanding and changing .ac code#Identifying an object}}&lt;br /&gt;
&lt;br /&gt;
When referring to an .ac file in your xml animation, it is important that the &amp;lt;code&amp;gt;&amp;lt;object-name&amp;gt;&amp;lt;/code&amp;gt; exactly matches the object named in the .ac file (this includes cases!). &lt;br /&gt;
&lt;br /&gt;
'''Note for SketchUp users:''' The spatial reference X/Y/Z used in animation to locate an object or a point are different from the ones in AC3D ie X values are the same in both but Y in animation must be matched to AC3D's -Z (Z value but opposite sign) and Z value in animation must be matched to AC3D's Y value. &lt;br /&gt;
&lt;br /&gt;
'''Note for SketchUp users:''' when exporting to AC3D in Sketchup, the .ac file will name the objects in your model to &amp;quot;blah&amp;quot; by default. You need to amend the relevant object names in your .ac file using text edit, so that the xml will work.&lt;br /&gt;
&lt;br /&gt;
=== Animation order ===&lt;br /&gt;
Animations are executed by FlightGear in the order that they are read in the model's .xml file. Therefore, it is very important to pay attention to the order, especially when multiple animations are applied to the same object(s). Wrong ordering of animations might cause [[Howto:Animate models#Timed|timed]] animations (used to create flashing lights) to not work. For further details see this [https://sourceforge.net/p/flightgear/mailman/message/37090714/ thread] on the development mailing list. Updated [https://scenery.flightgear.org/app.php?c=Models&amp;amp;a=browse&amp;amp;shared=18 shared Effects models] will be available very soon.&lt;br /&gt;
&lt;br /&gt;
Similar problems can be encountered with the dist-scale instead of the timed animation.&lt;br /&gt;
== Tags used in most animations ==&lt;br /&gt;
=== Name ===&lt;br /&gt;
With a name animation, you can group multiple objects. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Collection1&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object1&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object2&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object3&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example above creates a &amp;quot;virtual object&amp;quot; with the name Collection1. In animation, we can animate this group of objects, by using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;object-name&amp;gt;Collection1&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object-name ===&lt;br /&gt;
These names are set in the 3D model. Each single object has a unique name; for easy identification it is advised to use descriptive names (LeftElevator, Rudder etc.). Animations are only applied to those objects that are mentioned in an object-name line (one object per line!). Animations lacking those, will be applied to the entire model.&lt;br /&gt;
&lt;br /&gt;
=== Property ===&lt;br /&gt;
Each animation must be associated with exactly one property from the main FlightGear property tree (remember that the properties in the wrapper file are not part of the main tree), using &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; to provide the property path:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Rudder&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;controls/rudder&amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the omission of the leading slash '/' when referring to the property. This assures that when the model is used for AI or multiplayer traffic the animations will follow that of the AI controller instead of that of the user.&lt;br /&gt;
&lt;br /&gt;
=== Axis ===&lt;br /&gt;
An axis part is required in every animation that involves a rotating or moving thing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The axis are similar to the ones of the 3D model. There is a difference between rotation and translation:&lt;br /&gt;
* In rotation animations, the axis part defines around what axis the object rotates. Negative/positive values make the difference between counterclockwise and clockwise rotations.&lt;br /&gt;
* In translate animations, the part defines along what axis the object moves. If the x-axis is poiting backwards, an x-value of -1 will result in forward motion.&lt;br /&gt;
&lt;br /&gt;
You could also define two points, between which FlightGear will calculate the correct axis. This makes the use of a [[#Center|&amp;lt;nowiki&amp;gt;&amp;lt;center&amp;gt;&amp;lt;/nowiki&amp;gt;]] tag redundant! Such coordinates are extremely useful for animating control surfaces (rudder, elevators etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;   &lt;br /&gt;
   &amp;lt;x1-m&amp;gt; 4.9&amp;lt;/x1-m&amp;gt;&lt;br /&gt;
   &amp;lt;y1-m&amp;gt; 7.1&amp;lt;/y1-m&amp;gt;&lt;br /&gt;
   &amp;lt;z1-m&amp;gt;-1.0&amp;lt;/z1-m&amp;gt;&lt;br /&gt;
   &amp;lt;x2-m&amp;gt; 5.9&amp;lt;/x2-m&amp;gt;&lt;br /&gt;
   &amp;lt;y2-m&amp;gt;11.2&amp;lt;/y2-m&amp;gt;&lt;br /&gt;
   &amp;lt;z2-m&amp;gt;-0.5&amp;lt;/z2-m&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Center ===&lt;br /&gt;
Various animations ([[#Rotate|rotate]], [[#Spin|spin]], [[#Scale|scale]]) move around a center point.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The axis are similar to the ones of the 3D model, so finding coordinates is easily done in 3D modeling software.&lt;br /&gt;
&lt;br /&gt;
=== Using a geometry object for axis and centre (2017.2) ===&lt;br /&gt;
&lt;br /&gt;
Added in V2017.2 is support to allow a geometry object (a line segment with two vertices) that is used to define both the centre and the axis for an animation. This will work with rotate, spin, translate and knob animations.&lt;br /&gt;
&lt;br /&gt;
{{Note|Since SimGear commit 6ca9141083e62be1161d0ca2d1e3b918494dd6ad on next, this feature can also be used for slider (usage equivalent to that for a translate animation) and for any of the &amp;lt;*-center&amp;gt; / &amp;lt;*-axis&amp;gt; tags of a locked-track animation.}}&lt;br /&gt;
&lt;br /&gt;
When used for translate animations, the axis line should be normalized (i.e. be 1 meter long) as its length acts as a factor for the translation distance.&lt;br /&gt;
&lt;br /&gt;
The XML syntax for this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;axis&amp;gt;&lt;br /&gt;
    &amp;lt;object-name&amp;gt;some-object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;&amp;lt;axis&amp;gt;...&amp;lt;/axis&amp;gt;&amp;lt;/code&amp;gt; section is omitted entirely, &amp;lt;code&amp;gt;{object-name}-axis&amp;lt;/code&amp;gt; will be used by default, where &amp;lt;code&amp;gt;{object-name}&amp;lt;/code&amp;gt; is the name of the object being animated (if we are animating more than one object, the first object is used). In the earlier example this would be &amp;lt;code&amp;gt;Rudder-axis&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Vertex Ordering ==== &lt;br /&gt;
&lt;br /&gt;
With FG &amp;lt;= 2020.3 the order of the points in the vertex will be sorted based on their X coordinate and when the X coordinate is equal the order will be that of the vertices in the model. &lt;br /&gt;
&lt;br /&gt;
This has been improved in 2020.4 by adding some new tags that can be used in the &amp;lt;axis&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;order-by-xyz/&amp;gt; - use the new sorting rules&lt;br /&gt;
# &amp;lt;order-by-x/&amp;gt; - use the 2020.3 sorting rules&lt;br /&gt;
# &amp;lt;swap-axis-direction/&amp;gt; - when the animation goes the wrong way this is an elegant way to fix it.&lt;br /&gt;
&lt;br /&gt;
There is also a new top level tag &amp;lt;defaults&amp;gt; that can have either &amp;lt;axis-animation-vertex-order-xyz/&amp;gt; or &amp;lt;axis-animation-vertex-order-x/&amp;gt;. These defaults will affect all animations in the .xml and also any included models unless the included model also has a &amp;lt;defaults&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
So for modelers that want to use the new definitive vertex sorting rules adding the following to the main model is sufficient.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
    &amp;lt;defaults&amp;gt;&lt;br /&gt;
        &amp;lt;axis-animation-vertex-order-xyz/&amp;gt;&lt;br /&gt;
    &amp;lt;/defaults&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Adding the axis animation 3d object to a model ==== &lt;br /&gt;
&lt;br /&gt;
In the '''.ac''' file, specify a SURF with type (bottom 4 bits, 0=polygon, 1=closedline, 2=line) set to 2, and two vertices that define the axis. For example:&lt;br /&gt;
&lt;br /&gt;
    OBJECT poly&lt;br /&gt;
    name &amp;quot;aileron.l-axis&amp;quot;&lt;br /&gt;
    numvert 2&lt;br /&gt;
    3.2077502191170844 0.18160835055097943 4.055616960642423&lt;br /&gt;
    2.6758650763079 0.28024033462188946 6.477876098622225&lt;br /&gt;
    numsurf 1&lt;br /&gt;
    SURF 0x12&lt;br /&gt;
    mat 0&lt;br /&gt;
    refs 2&lt;br /&gt;
    0 0 0&lt;br /&gt;
    1 0 0&lt;br /&gt;
    kids 0&lt;br /&gt;
&lt;br /&gt;
Once the object-name used for the axis has been processed the geometry object will be hidden. This also allows a visual check for any axis objects that are not yet assigned.&lt;br /&gt;
&lt;br /&gt;
It is possible to reuse the same object definition multiple times within a single XML file. &lt;br /&gt;
&lt;br /&gt;
[[File:Canopy-animation-axis-object.png|small|Illustration of where an axis object (2017.2) can be placed for a canopy]]&lt;br /&gt;
&lt;br /&gt;
[[File:Gauges-knobs-animation-axis-object.png|small|Illustration of where an axis object (2017.2) can be placed for cockpit elements]]&lt;br /&gt;
&lt;br /&gt;
== Additional tags that can be used in most animations ==&lt;br /&gt;
=== Conditions ===&lt;br /&gt;
Multiple animations can make use of a conditional. Check &amp;lt;tt&amp;gt;$FGDATA/Docs/README.conditions&amp;lt;/tt&amp;gt; for some more details.&lt;br /&gt;
&lt;br /&gt;
* '''equals:''' property value (or second property) is equal to value/(first)property.&lt;br /&gt;
* '''greater-than:''' property value (or second property) is larger than value/(first)property.&lt;br /&gt;
* '''greater-than-equals:''' property value (or second property) is greater than or equal to value/(first)property.&lt;br /&gt;
* '''less-than:''' property value (or second property) is smaller than value/(first)property.&lt;br /&gt;
* '''less-than-equals:''' property value (or second property) is smaller than or equal to value/(first)property.&lt;br /&gt;
&lt;br /&gt;
The example below is true when n1 has a value greater than 25.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then there are some special tags:&lt;br /&gt;
&lt;br /&gt;
* '''and:'''&lt;br /&gt;
* '''not:'''&lt;br /&gt;
* '''or:'''&lt;br /&gt;
&lt;br /&gt;
In the example below, the condition is true when either n1 is greater than 25% or equal to 0%.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;or&amp;gt;&lt;br /&gt;
    &amp;lt;greater-than&amp;gt;&lt;br /&gt;
     &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
     &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
    &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;equals&amp;gt;&lt;br /&gt;
     &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
     &amp;lt;value&amp;gt;0&amp;lt;/value&amp;gt;&lt;br /&gt;
    &amp;lt;/equals&amp;gt;&lt;br /&gt;
   &amp;lt;/or&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of implementation into an animation looks as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;suface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;suface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;10&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interpolation ===&lt;br /&gt;
For non-fixed factors, an interpolation &amp;quot;table&amp;quot; can be created. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;interpolation&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 0.0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.0&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 0.667&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.0&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 1.0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.5&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
  &amp;lt;/interpolation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The lines above represent the following table:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Input&lt;br /&gt;
!Output&lt;br /&gt;
|-&lt;br /&gt;
|0.0&lt;br /&gt;
|0.0&lt;br /&gt;
|-&lt;br /&gt;
|0.667&lt;br /&gt;
|0.0&lt;br /&gt;
|-&lt;br /&gt;
|1.0&lt;br /&gt;
|0.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can add as many entries as you need. Interpolation tables are often used for gear animations (eg. to open doors during gear-movements and close them again once the gear is either retracted or fully extended).&lt;br /&gt;
&lt;br /&gt;
=== Expressions ===&lt;br /&gt;
For some animations it is possible to define complex animations by using [[Expressions|Expressions]]. This even allows to drive the animation from multiple properties without the need for additional Nasal scripts. Here is an example for a translate animation depending on two properties and the cosine function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
     &amp;lt;type&amp;gt;translate&amp;lt;/type&amp;gt;&lt;br /&gt;
     &amp;lt;expression&amp;gt;&lt;br /&gt;
       &amp;lt;product&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/my/factor-property&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;cos&amp;gt;&lt;br /&gt;
           &amp;lt;deg2rad&amp;gt;&lt;br /&gt;
             &amp;lt;property&amp;gt;/my/angular-property&amp;lt;/property&amp;gt;&lt;br /&gt;
           &amp;lt;/deg2rad&amp;gt;&lt;br /&gt;
         &amp;lt;/cos&amp;gt;&lt;br /&gt;
       &amp;lt;/product&amp;gt;&lt;br /&gt;
     &amp;lt;/expression&amp;gt;&lt;br /&gt;
     [..]more elements[..]&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Animations which can utilize [[Expressions|Expressions]] are: &lt;br /&gt;
* [[Howto:Animate_models#Translate|Translate]]&lt;br /&gt;
* [[Howto:Animate_models#Rotate|Rotate]]&lt;br /&gt;
* [[Howto:Animate_models#Scale|Scale]]&lt;br /&gt;
* [[Howto:Animate_models#Range|Range]]&lt;br /&gt;
* [[Howto:Animate_models#Blend|Blend]]&lt;br /&gt;
* [[Howto:Animate_models#Material animation|Material]]&lt;br /&gt;
* [[Howto:Animate_models#PBR animation|PBR]]&lt;br /&gt;
&lt;br /&gt;
See more detailed info at [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
== Lights ==&lt;br /&gt;
As of January 2021 FlightGear supports multiple light sources just like Project Rembrandt has always done.&lt;br /&gt;
[[Compositor#Lights|Adding lights to a model]]&lt;br /&gt;
&lt;br /&gt;
== Object animations ==&lt;br /&gt;
=== Alpha-test ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;alpha-test&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;alpha-factor&amp;gt;0.01&amp;lt;/alpha-factor&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This &amp;quot;animation&amp;quot; is a way to set an alpha test on a model branch. The effect is to avoid depth buffer writing of pixel that are not seen because they are transparent. This is particulary useful when modeling a metallic structure or a tree with a billboard. The threshold of transparency is set with the &amp;lt;alpha-factor&amp;gt; element.  See also [[Pixel testing in effects]].&lt;br /&gt;
&lt;br /&gt;
=== Blend ===&lt;br /&gt;
Blends an object with the surrounding. Comparable to a translucency animation. A value of 0 corresponds to no transparency, i.e. and ordinary solid object, and a value of 1 makes the object fully transparent, i.e., not visible at all.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;blend&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;/velocities/airspeed-kt&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;0.00025&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;min&amp;gt;0.2&amp;lt;/min&amp;gt;&lt;br /&gt;
  &amp;lt;max&amp;gt;0.7&amp;lt;/max&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''property:'''&lt;br /&gt;
* '''factor:'''&lt;br /&gt;
* '''min:'''&lt;br /&gt;
* '''max:'''&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
Note that when using the Project Rembrandt renderer, all transparent and translucent objects must be registered to display properly.  [[Project_Rembrandt#Registering_all_translucent_surfaces|More information here.]]&lt;br /&gt;
&lt;br /&gt;
=== Billboard ===&lt;br /&gt;
This faces an object towards the viewer. Often used on 2D objects, like clouds, trees and lights.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;billboard&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;spherical type=&amp;quot;bool&amp;quot;&amp;gt;true&amp;lt;/spherical&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''spherical:'''&lt;br /&gt;
&lt;br /&gt;
=== Dist-scale ===&lt;br /&gt;
Used to scale an object, based on the distance to the viewer. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;ind&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;dep&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (independent and dependent) are the distance in meters and the scale at that distance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;dist-scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;interpolation&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;1&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;300&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;4&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;1500&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;8&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
  &amp;lt;/interpolation&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can optionally add [[#Center|&amp;amp;lt;center&amp;amp;gt;]] coordinates, to scale the object around that point.&lt;br /&gt;
&lt;br /&gt;
=== Flash ===&lt;br /&gt;
&lt;br /&gt;
Used to scale an object based on the cosine of the angle between the axis provided in the animation and the view vector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;flash&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;offset&amp;gt;0.0&amp;lt;/offset&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;1.0&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;power&amp;gt;2&amp;lt;/power&amp;gt;&lt;br /&gt;
  &amp;lt;two-sides type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/two-sides&amp;gt;&lt;br /&gt;
  &amp;lt;min&amp;gt;0.0&amp;lt;/min&amp;gt;&lt;br /&gt;
  &amp;lt;max&amp;gt;1.0&amp;lt;/max&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;0.0&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt;0.0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt;0.0&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0.0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;-1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0.1&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''offset:'''&lt;br /&gt;
* '''factor:'''&lt;br /&gt;
* '''power:'''&lt;br /&gt;
* '''two-sides:''' if false, nothing is drawn if the cosine is negative.&lt;br /&gt;
* '''min:'''&lt;br /&gt;
* '''max:'''&lt;br /&gt;
&lt;br /&gt;
scale = factor * pow( cosine, power ) + offset&lt;br /&gt;
&lt;br /&gt;
scale is then clamped between min and max.&lt;br /&gt;
&lt;br /&gt;
and this scale factor is applied to the object, from the center specified. It works best if scale is less than 1. Otherwise, there will be clipping issues.&lt;br /&gt;
&lt;br /&gt;
=== Noshadow ===&lt;br /&gt;
This animation is used to make sure an object will cast no shadow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;noshadow&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
: ''See also [[Modeling - Getting Started#Level of Detail (LOD)]].''&lt;br /&gt;
&lt;br /&gt;
To prevent objects -like instruments- being drawn when the aircraft is actually too far away for them to be seen anyway, a range animation is used. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;range&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;min-m&amp;gt;0&amp;lt;/min-m&amp;gt;&lt;br /&gt;
  &amp;lt;max-m&amp;gt;30&amp;lt;/max-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''min-m:''' the shortest distance (in meters) from the object center at which it is visible.&lt;br /&gt;
* '''max-m:''' the largest distance (in meters) from the object center at which it is visible.&lt;br /&gt;
&lt;br /&gt;
You could also use the generic level of detail (LOD) properties, which can be set by the user through View &amp;gt; Adjust LOD rangers: &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Property&lt;br /&gt;
! Description&lt;br /&gt;
! Default value&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/bare&amp;lt;/tt&amp;gt;&lt;br /&gt;
| only a rough exterior model&lt;br /&gt;
| 30,000 m&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/rough&amp;lt;/tt&amp;gt; &lt;br /&gt;
| most should be visible&lt;br /&gt;
| 9,000 m&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/detailed&amp;lt;/tt&amp;gt; &lt;br /&gt;
| all details should be visible&lt;br /&gt;
| 1,500 m&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The animation code will look like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;range&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;min-m&amp;gt;0&amp;lt;/min-m&amp;gt;&lt;br /&gt;
  &amp;lt;max-property&amp;gt;sim/rendering/static-lod/bare&amp;lt;/max-property&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can have both ranges (max and min) bound to a property, or just one of them.&lt;br /&gt;
* '''min-property:''' &lt;br /&gt;
* '''max-property:'''&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Rotate ===&lt;br /&gt;
One of the most important and frequently used animations of all. It rotates an object to an absolute position in degrees, as provided by the property-value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;surface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-deg&amp;gt;25&amp;lt;/offset-deg&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
* '''offset-deg:''' is optional. Offset in degrees.&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Scale ===&lt;br /&gt;
A scale animation scales (resizes) an object. This can be either property-value dependant (first example) or a fixed scale (second example).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;sim/time/sun-angle-rad&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;x-min&amp;gt;1.0&amp;lt;/x-min&amp;gt;&lt;br /&gt;
  &amp;lt;y-min&amp;gt;1.0&amp;lt;/y-min&amp;gt;&lt;br /&gt;
  &amp;lt;z-min&amp;gt;1.0&amp;lt;/z-min&amp;gt;&lt;br /&gt;
  &amp;lt;x-factor&amp;gt;1.4&amp;lt;/x-factor&amp;gt;&lt;br /&gt;
  &amp;lt;y-factor&amp;gt;1.4&amp;lt;/y-factor&amp;gt;&lt;br /&gt;
  &amp;lt;z-factor&amp;gt;2.0&amp;lt;/z-factor&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ?-min: the mimimum scale factor for each axis. If the property value would result in a smaller factor than this setting, the scale animation will hold.&lt;br /&gt;
* ?-factor: the scale factor for each axis (factor*property=scale factor).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;x-offset&amp;gt;0.5&amp;lt;/x-offset&amp;gt;&lt;br /&gt;
  &amp;lt;y-offset&amp;gt;0.5&amp;lt;/y-offset&amp;gt;&lt;br /&gt;
  &amp;lt;z-offset&amp;gt;0.5&amp;lt;/z-offset&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* x.offset: the scale factor.&lt;br /&gt;
* Add [[#Center|&amp;amp;lt;center&amp;amp;gt;]] coordinates, to scale the object around that point.&lt;br /&gt;
* '''You can optionally use an [[Howto:Animate_models#Expressions|expression]] in the &amp;lt;factor&amp;gt; or &amp;lt;offset&amp;gt; inputs.''' For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Select ===&lt;br /&gt;
This animation selects (or unselects) objects when certain conditions are true (or false). The example below shows the object when the n1 of engine[1] is higher than 25%.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;engines/engine[0]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Shader ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;shader&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;shader&amp;gt;chrome&amp;lt;/shader&amp;gt;&lt;br /&gt;
  &amp;lt;texture&amp;gt;chrome2.png&amp;lt;/texture&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''shader:''' &lt;br /&gt;
* '''texture:''' path to the texture used by the shader.&lt;br /&gt;
&lt;br /&gt;
=== Spin ===&lt;br /&gt;
Very similar to [[#Rotate|rotate]], but the property provides a value in revolutions per minute (RPM) rather than an absolute position in degrees, and offset cannot be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spin&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;engines/engine[0]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
&lt;br /&gt;
=== Timed ===&lt;br /&gt;
Swtiches between objects at specified intervals. This example switches between a lights-on model and a lights-off model. Lights on are shown 0.2 seconds, while lights off are displayed for 0.8 seconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;timed&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;BacklightOn&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;BacklightOff&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;use-personality type=&amp;quot;bool&amp;quot;&amp;gt;true&amp;lt;/use-personality&amp;gt;&lt;br /&gt;
  &amp;lt;branch-duration-sec&amp;gt;0.8&amp;lt;/branch-duration-sec&amp;gt;&lt;br /&gt;
  &amp;lt;branch-duration-sec&amp;gt;0.2&amp;lt;/branch-duration-sec&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tracking ===&lt;br /&gt;
A ''locked-track animation'' can do exactly the same thing as the [https://docs.blender.org/manual/en/latest/animation/constraints/tracking/locked_track.html Locked Track constraint] available in Blender and can also be used to simulate simple inverse kinematic systems consisting of two bones connected with a revolute joint (aka hinge). For details see: [[Howto:Animate gear scissors using the tracking animation]]&lt;br /&gt;
&lt;br /&gt;
=== Translate ===&lt;br /&gt;
This animation moves an object along an axis (not to be confused with the &amp;lt;code&amp;gt;textranslate&amp;lt;/code&amp;gt; animation which only moves the texture on the UV map, not the geometry). The example below will move an object in the Y direction:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; &lt;br /&gt;
!Property value&lt;br /&gt;
!Output&lt;br /&gt;
|-&lt;br /&gt;
| -1&lt;br /&gt;
| -2.5&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 2.5&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 7.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;translate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;controls/seat/pilot/position-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;5&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-m&amp;gt;2.5&amp;lt;/offset-m&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using interpolation tables such as:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;interpolation&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;0.0&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt; 0&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;0.666&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt;0.18&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;1.0&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt;0.27&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
&amp;lt;/interpolation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The first figure (&amp;lt;code&amp;gt;&amp;lt;ind&amp;gt;&amp;lt;/code&amp;gt;) refers to the value of the property associated with the object and the second figure (&amp;lt;code&amp;gt;&amp;lt;dep&amp;gt;&amp;lt;/code&amp;gt;) refers to the amount that the object moves in metres. For example, in this case, the object moves 18cm when the value reads 0.66 and 27cm when the value is 1.&lt;br /&gt;
&lt;br /&gt;
'''IF used WTIHOUT property''' : The object is placed at some (Value of Offset) meters away from its original position, along the virtual axis formed by said original position and the point with coordinates x/y/z defined in the &amp;lt;axis&amp;gt; tag.&lt;br /&gt;
Mathematically, assuming the Object to translate is (in the model space) placed at point A (x1, y1, z1) and you want to relocate it to point B (x2, y2, z2) then x2,y2,z2 are the values in the &amp;lt;axis&amp;gt; tag of the Translate animation and &amp;lt;offset&amp;gt; can be computed as SQRT((x2-x1)^2+(y2-y1)^2+(z2-z1)^2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
* '''offset-m:''' is optional. Offset in meters.&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
== PBR animation ==&lt;br /&gt;
&lt;br /&gt;
Animate the PBR (Physically-Based Rendering) materials. Keep in mind that your model must use the model-pbr.eff Effect or be a [[glTF]] model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;pbr&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/c172p/material/&amp;lt;/property-base&amp;gt;&lt;br /&gt;
  &amp;lt;base-color-factor&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.3&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.1&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1.0&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/base-color-factor&amp;gt;&lt;br /&gt;
  &amp;lt;metallic-factor&amp;gt;0.0&amp;lt;/metallic-factor&amp;gt;&lt;br /&gt;
  &amp;lt;roughness-factor&amp;gt;0.3&amp;lt;/roughness-factor&amp;gt;&lt;br /&gt;
  &amp;lt;emissive-factor&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/emissive-factor&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;property-base&amp;lt;/tt&amp;gt;: All other properties of this animation will be relative to this property node.&lt;br /&gt;
* &amp;lt;tt&amp;gt;base-color-factor&amp;lt;/tt&amp;gt;: The base color texture will be multiplied by this value. Should be an RGBA color.&lt;br /&gt;
* &amp;lt;tt&amp;gt;metallic-factor&amp;lt;/tt&amp;gt;: The metallic texture will be multiplied by this value. Should be a single floating point value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;roughness-factor&amp;lt;/tt&amp;gt;: The roughness texture will be multiplied by this value. Should be a single floating point value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;emissive-factor&amp;lt;/tt&amp;gt;: The emissive texture will be multiplied by this value. Should be an RGB color.&lt;br /&gt;
&lt;br /&gt;
For each of the color components you can use an [[expression]].&lt;br /&gt;
&lt;br /&gt;
== Material animation ==&lt;br /&gt;
Animate the material properties of an object, such as it's texture, shininess or color.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt; &lt;br /&gt;
  &amp;lt;type&amp;gt;material&amp;lt;/type&amp;gt; &lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/c172p/material&amp;lt;/property-base&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  lines as mentioned below&lt;br /&gt;
  ...&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Optional:'''&lt;br /&gt;
* '''property-base:''' All other properties of this animation will be relative to this property node.&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Numbers are clamped to 0.0 - 1.0, except &amp;lt;code&amp;gt;shininess&amp;lt;/code&amp;gt;, which is clamped to 0 - 128.&lt;br /&gt;
* By appending &amp;lt;tt&amp;gt;-prop&amp;lt;/tt&amp;gt; each of the material properties can read its value from another property.&lt;br /&gt;
* '''New since SimGear commit &amp;lt;code&amp;gt;51149bf&amp;lt;/code&amp;gt;''': For each of the color components (&amp;lt;code&amp;gt;ambient&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;diffuse&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;emission&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;specular&amp;lt;/code&amp;gt;), the &amp;lt;code&amp;gt;red&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;green&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;blue&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;factor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; tags can each contain an [[Expressions|expression]] instead of a value.&lt;br /&gt;
&lt;br /&gt;
=== Ambient ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/ambient&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Diffuse ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/diffuse&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Emission ===&lt;br /&gt;
{{Main article|Howto: Illuminate faces}}&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;emission&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
   &amp;lt;factor-prop&amp;gt;controls/lighting/panel-norm&amp;lt;/factor-prop&amp;gt;&lt;br /&gt;
  &amp;lt;/emission&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Emission colors are multiplied by the factor-prop value. 1 is maximum color intensity, while 0 is the minimum. Colors are calculated according to the [http://en.wikipedia.org/wiki/RGB_color_model RGB color model].&lt;br /&gt;
&lt;br /&gt;
=== Specular ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;specular&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/specular&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Transparency ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;transparency&amp;gt;&lt;br /&gt;
   &amp;lt;alpha-prop&amp;gt;rotors/tail/rpm&amp;lt;/alpha-prop&amp;gt;&lt;br /&gt;
   &amp;lt;factor&amp;gt;-0.0015&amp;lt;/factor&amp;gt;&lt;br /&gt;
   &amp;lt;offset&amp;gt;1&amp;lt;/offset&amp;gt;&lt;br /&gt;
  &amp;lt;/transparency&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Shininess ===&lt;br /&gt;
Shininess is clamped to 0-128.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;shininess&amp;gt;105&amp;lt;/shininess&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threshold ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;threshold&amp;gt;0.001&amp;lt;/threshold&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Texture ===&lt;br /&gt;
Used for the [[Livery over MP]] system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/livery&amp;lt;/property-base&amp;gt; &lt;br /&gt;
  &amp;lt;texture-prop&amp;gt;engine&amp;lt;/texture-prop&amp;gt; &lt;br /&gt;
  &amp;lt;texture&amp;gt;KLM.png&amp;lt;/texture&amp;gt; &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Texture Animations ==&lt;br /&gt;
Applying different matrix transformations to the textures of an object.&lt;br /&gt;
&lt;br /&gt;
=== Textranslate ===&lt;br /&gt;
A very important animation for cockpits! This animation moves textures over a surface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;textranslate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;autopilot/settings/target-speed-kt&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;bias&amp;gt;0.0001&amp;lt;/bias&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;0.001&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;step&amp;gt;100&amp;lt;/step&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''bias:''' Adds an offset to the property before factor/step. A small value is needed to compensate for [http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems floating point accuracy].&lt;br /&gt;
* '''factor:''' property * factor * texture width/height = the amount of pixels that the texture should be translated. If your texture is 256 pixels, an textranslate of 0.1 will result in the texture moving with 26 pixels, into the direction specified by the axis settings.&lt;br /&gt;
* '''step:''' the step size at which the texture is translated. If this is set to 0.1, the texture will only be translated at 0.1, 0.2, 0.3 etc.&lt;br /&gt;
* '''axis:''' the direction in which the texture is translated. Y is up/down, while X is left/right.&lt;br /&gt;
&lt;br /&gt;
=== Texrotate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;texrotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;some/property/path&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-deg&amp;gt;25&amp;lt;/offset-deg&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;0.5&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0.5&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;1&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Textrapezoid ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;textrapezoid&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;HUD.l.canvas&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;/hud/trapezoid-correction&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;side&amp;gt;bottom&amp;lt;/side&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''side''': side of quad which should be scaled (''top'' (default)/''right''/''bottom''/''left'')&lt;br /&gt;
&lt;br /&gt;
=== Texmultiple ===&lt;br /&gt;
&lt;br /&gt;
Only one texture matrix can be applied to each object. With ''textmultiple'' multiple texture animations can be combined into a single matrix, applied to the specified object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;texmultiple&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;HUD.l.canvas&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textranslate&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/offset-x&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;axis&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;1&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/axis&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textranslate&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/offset-y&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;axis&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/axis&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textrapezoid&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/trapezoid-correction&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object interaction animations ==&lt;br /&gt;
=== Enable-hot ===&lt;br /&gt;
Scenery objects are automatically defined as solid by FlightGear, meaning that an aircraft can taxi on them and/or crash when touching. For certain objects (groundmarkings, beacon light-beams etc.) this might be an unwanted feature. The solidness can be disabled with the following animation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;enable-hot type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/enable-hot&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''enable-hot:''' can be either true or false. Remember that objects are automatically solid, so it should not be necessary to set this at all when wanting solidness.&lt;br /&gt;
&lt;br /&gt;
=== Interactions ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt; &lt;br /&gt;
  &amp;lt;type&amp;gt;interaction&amp;lt;/type&amp;gt; &lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt; &lt;br /&gt;
  &amp;lt;interaction-type&amp;gt;carrier-wire&amp;lt;/interaction-type&amp;gt; &lt;br /&gt;
 &amp;lt;/animation&amp;gt; &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''interaction-type:''' can have the following values:&lt;br /&gt;
**'''carrier-catapult:'''&lt;br /&gt;
** '''carrier-wire:''' makes the object act as an arresting wire, as used on [[aircraft carrier]]s.&lt;br /&gt;
&lt;br /&gt;
== Direct manipulation animations ==&lt;br /&gt;
=== Knob / slider (v. 2.11-) ===&lt;br /&gt;
{{Main article|Knob / slider animation}}&lt;br /&gt;
&lt;br /&gt;
=== Pick ===&lt;br /&gt;
{{Main article|Howto: Make a clickable panel#Pick}}&lt;br /&gt;
&lt;br /&gt;
=== Touch ===&lt;br /&gt;
&lt;br /&gt;
The touch animation provides the normalized coordinates of a touch (or click) event on a 2d surface. The coordinates are passed in the argument and can be accessed using cmdarg() in Nasal.&lt;br /&gt;
&lt;br /&gt;
* Touch animation is designed to work with a quad that is being used as a Canvas placement (display).&lt;br /&gt;
* The touch animation must not be combined with a pick animation on the same object.&lt;br /&gt;
* More info here: [[Touch Animation]]&lt;br /&gt;
&lt;br /&gt;
==== touch example ====&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;animation&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;touch&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;visible&amp;gt;true&amp;lt;/visible&amp;gt;&lt;br /&gt;
        &amp;lt;object-name&amp;gt;CanvasPlacement&amp;lt;/object-name&amp;gt;&lt;br /&gt;
        &amp;lt;action&amp;gt;&lt;br /&gt;
            &amp;lt;touch&amp;gt;0&amp;lt;/touch&amp;gt;&lt;br /&gt;
            &amp;lt;repeatable&amp;gt;false&amp;lt;/repeatable&amp;gt;&lt;br /&gt;
            &amp;lt;binding&amp;gt;&lt;br /&gt;
                &amp;lt;command&amp;gt;nasal&amp;lt;/command&amp;gt;&lt;br /&gt;
                &amp;lt;script&amp;gt;print(&amp;quot;touch input (&amp;quot;,cmdarg().getNode(&amp;quot;x&amp;quot;).getValue(),&amp;quot;,&amp;quot;,cmdarg().getNode(&amp;quot;y&amp;quot;).getValue())&amp;lt;/script&amp;gt;&lt;br /&gt;
            &amp;lt;/binding&amp;gt;&lt;br /&gt;
        &amp;lt;/action&amp;gt;&lt;br /&gt;
    &amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Shadow Handling ==&lt;br /&gt;
There exist several possibilites for handling of shadows. &amp;lt;br /&amp;gt;&lt;br /&gt;
See '''[[ALS_technical_notes|ALS Technical Notes]]''' and more specific '''[[ALS_technical_notes#ALS_fuselage_shadow_effect|Fuselage Shadow Effect with ALS]]''' for a relatively simple shadow handling.&amp;lt;br /&amp;gt;&lt;br /&gt;
See '''[[Project Rembrandt]]''' which - amongst other functionality - implements a very realistic shadow mapping.&lt;br /&gt;
As of January 2021 Project Rembrandt was replaced by the '''[[Compositor]]''' renderer which combines both Project Rembrandt and ALS in a single rendering engine. This also means that the Fuselage Shadow Effect with ALS is now deprecated.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://www.opensubscriber.com/message/flightgear-devel@flightgear.org/958955.html |title=&amp;quot;material&amp;quot; animation (and the bo105 as an example) |first=Melchior |last=Franz |date=22 March 2005 |work=FlightGear-devel mailinglist }}&lt;br /&gt;
* {{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg01546.html |title=flash animation |first=Frederic |last=Bouvier |date=22 Feb 2006 |work=FlightGear-devel mailinglist }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Wiki articles ===&lt;br /&gt;
* [[MP Fallback models]]&lt;br /&gt;
* [[Howto:Animate gear scissors]]&lt;br /&gt;
* [[Howto:Animate helicopters]]&lt;br /&gt;
* [[Howto:Creating 3D instruments]]&lt;br /&gt;
&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=37353|title=3d models, how to produce them in an understandable way}} (April 2020-) - Touches on the subject of not using LOD range animations in scenery models.&lt;br /&gt;
* {{forum link|t=36545|title=speedo Drum settings}} (November 2019) - Animating a mechanical multi-digit drum counter&lt;br /&gt;
&lt;br /&gt;
[[Category:Aircraft enhancement|Animate models]]&lt;br /&gt;
[[Category:Howto|Animate models]]&lt;br /&gt;
[[Category:Modeling|Animate models]]&lt;br /&gt;
[[Category:Scenery enhancement|Animate models]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Animate_models&amp;diff=140502</id>
		<title>Howto:Animate models</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Animate_models&amp;diff=140502"/>
		<updated>2024-09-21T18:39:10Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The real world is full of motion. To simulate this in [[FlightGear]], '''models must be animated'''.&lt;br /&gt;
&lt;br /&gt;
FlightGear allows you to animate models in response to property changes: for example, the propellers can spin when the engine is on and the elevators can move up and down with your controller. There is no fixed limit on what parts can be animated: the only requirements are that the part is named in the 3D model file, and that there is a property in the main tree that you can use to get the positioning information. &lt;br /&gt;
&lt;br /&gt;
This document provides basic information for all kind of animations. When animating your model, it is very helpful to find an aircraft with parts similar to yours and use it as an example. Cut and paste the code into your wrapper file and then edit to suit.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
=== File name of main model and animation XML file ===&lt;br /&gt;
{{main article|Aircraft-set.xml#Not used for loading multiplayer aircraft}}&lt;br /&gt;
The file name of the main model and animation XML file, or the .ac file if there is no XML file, (in essence the property &amp;lt;code&amp;gt;/sim/model/path&amp;lt;/code&amp;gt;) will be the name of the aircraft that is transmitted when using [[multiplayer]] and will also be used for loading multiplayer aircraft.&lt;br /&gt;
&lt;br /&gt;
There is also a mechanism to substitute a full aircraft model with a simpler AI aircraft model if one is available at the same file path (including for example &amp;lt;code&amp;gt;Models/Boeing-797-800.xml&amp;lt;/code&amp;gt;), but in &amp;lt;code&amp;gt;[[$FG_ROOT]]/'''AI'''/Aircraft/&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;$FG_ROOT/Aircraft/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== .ac files ===&lt;br /&gt;
{{Main article|AC files: Understanding and changing .ac code#Identifying an object}}&lt;br /&gt;
&lt;br /&gt;
When referring to an .ac file in your xml animation, it is important that the &amp;lt;code&amp;gt;&amp;lt;object-name&amp;gt;&amp;lt;/code&amp;gt; exactly matches the object named in the .ac file (this includes cases!). &lt;br /&gt;
&lt;br /&gt;
'''Note for SketchUp users:''' The spatial reference X/Y/Z used in animation to locate an object or a point are different from the ones in AC3D ie X values are the same in both but Y in animation must be matched to AC3D's -Z (Z value but opposite sign) and Z value in animation must be matched to AC3D's Y value. &lt;br /&gt;
&lt;br /&gt;
'''Note for SketchUp users:''' when exporting to AC3D in Sketchup, the .ac file will name the objects in your model to &amp;quot;blah&amp;quot; by default. You need to amend the relevant object names in your .ac file using text edit, so that the xml will work.&lt;br /&gt;
&lt;br /&gt;
=== Animation order ===&lt;br /&gt;
Animations are executed by FlightGear in the order that they are read in the model's .xml file. Therefore, it is very important to pay attention to the order, especially when multiple animations are applied to the same object(s). Wrong ordering of animations might cause [[Howto:Animate models#Timed|timed]] animations (used to create flashing lights) to not work. For further details see this [https://sourceforge.net/p/flightgear/mailman/message/37090714/ thread] on the development mailing list. Updated [https://scenery.flightgear.org/app.php?c=Models&amp;amp;a=browse&amp;amp;shared=18 shared Effects models] will be available very soon.&lt;br /&gt;
&lt;br /&gt;
Similar problems can be encountered with the dist-scale instead of the timed animation.&lt;br /&gt;
== Tags used in most animations ==&lt;br /&gt;
=== Name ===&lt;br /&gt;
With a name animation, you can group multiple objects. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Collection1&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object1&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object2&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object3&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example above creates a &amp;quot;virtual object&amp;quot; with the name Collection1. In animation, we can animate this group of objects, by using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;object-name&amp;gt;Collection1&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object-name ===&lt;br /&gt;
These names are set in the 3D model. Each single object has a unique name; for easy identification it is advised to use descriptive names (LeftElevator, Rudder etc.). Animations are only applied to those objects that are mentioned in an object-name line (one object per line!). Animations lacking those, will be applied to the entire model.&lt;br /&gt;
&lt;br /&gt;
=== Property ===&lt;br /&gt;
Each animation must be associated with exactly one property from the main FlightGear property tree (remember that the properties in the wrapper file are not part of the main tree), using &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; to provide the property path:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Rudder&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;controls/rudder&amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the omission of the leading slash '/' when referring to the property. This assures that when the model is used for AI or multiplayer traffic the animations will follow that of the AI controller instead of that of the user.&lt;br /&gt;
&lt;br /&gt;
=== Axis ===&lt;br /&gt;
An axis part is required in every animation that involves a rotating or moving thing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The axis are similar to the ones of the 3D model. There is a difference between rotation and translation:&lt;br /&gt;
* In rotation animations, the axis part defines around what axis the object rotates. Negative/positive values make the difference between counterclockwise and clockwise rotations.&lt;br /&gt;
* In translate animations, the part defines along what axis the object moves. If the x-axis is poiting backwards, an x-value of -1 will result in forward motion.&lt;br /&gt;
&lt;br /&gt;
You could also define two points, between which FlightGear will calculate the correct axis. This makes the use of a [[#Center|&amp;lt;nowiki&amp;gt;&amp;lt;center&amp;gt;&amp;lt;/nowiki&amp;gt;]] tag redundant! Such coordinates are extremely useful for animating control surfaces (rudder, elevators etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;   &lt;br /&gt;
   &amp;lt;x1-m&amp;gt; 4.9&amp;lt;/x1-m&amp;gt;&lt;br /&gt;
   &amp;lt;y1-m&amp;gt; 7.1&amp;lt;/y1-m&amp;gt;&lt;br /&gt;
   &amp;lt;z1-m&amp;gt;-1.0&amp;lt;/z1-m&amp;gt;&lt;br /&gt;
   &amp;lt;x2-m&amp;gt; 5.9&amp;lt;/x2-m&amp;gt;&lt;br /&gt;
   &amp;lt;y2-m&amp;gt;11.2&amp;lt;/y2-m&amp;gt;&lt;br /&gt;
   &amp;lt;z2-m&amp;gt;-0.5&amp;lt;/z2-m&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Center ===&lt;br /&gt;
Various animations ([[#Rotate|rotate]], [[#Spin|spin]], [[#Scale|scale]]) move around a center point.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The axis are similar to the ones of the 3D model, so finding coordinates is easily done in 3D modeling software.&lt;br /&gt;
&lt;br /&gt;
=== Using a geometry object for axis and centre (2017.2) ===&lt;br /&gt;
&lt;br /&gt;
Added in V2017.2 is support to allow a geometry object (a line segment with two vertices) that is used to define both the centre and the axis for an animation. This will work with rotate, spin, translate and knob animations.&lt;br /&gt;
&lt;br /&gt;
{{Note|Since SimGear commit 6ca9141083e62be1161d0ca2d1e3b918494dd6ad on next, this feature can also be used for slider (usage equivalent to that for a translate animation) and for any of the &amp;lt;*-center&amp;gt; / &amp;lt;*-axis&amp;gt; tags of a locked-track animation.}}&lt;br /&gt;
&lt;br /&gt;
When used for translate animations, the axis line should be normalized (i.e. be 1 meter long) as its length acts as a factor for the translation distance.&lt;br /&gt;
&lt;br /&gt;
The XML syntax for this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;axis&amp;gt;&lt;br /&gt;
    &amp;lt;object-name&amp;gt;some-object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;&amp;lt;axis&amp;gt;...&amp;lt;/axis&amp;gt;&amp;lt;/code&amp;gt; section is omitted entirely, &amp;lt;code&amp;gt;{object-name}-axis&amp;lt;/code&amp;gt; will be used by default, where &amp;lt;code&amp;gt;{object-name}&amp;lt;/code&amp;gt; is the name of the object being animated (if we are animating more than one object, the first object is used). In the earlier example this would be &amp;lt;code&amp;gt;Rudder-axis&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Vertex Ordering ==== &lt;br /&gt;
&lt;br /&gt;
With FG &amp;lt;= 2020.3 the order of the points in the vertex will be sorted based on their X coordinate and when the X coordinate is equal the order will be that of the vertices in the model. &lt;br /&gt;
&lt;br /&gt;
This has been improved in 2020.4 by adding some new tags that can be used in the &amp;lt;axis&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;order-by-xyz/&amp;gt; - use the new sorting rules&lt;br /&gt;
# &amp;lt;order-by-x/&amp;gt; - use the 2020.3 sorting rules&lt;br /&gt;
# &amp;lt;swap-axis-direction/&amp;gt; - when the animation goes the wrong way this is an elegant way to fix it.&lt;br /&gt;
&lt;br /&gt;
There is also a new top level tag &amp;lt;defaults&amp;gt; that can have either &amp;lt;axis-animation-vertex-order-xyz/&amp;gt; or &amp;lt;axis-animation-vertex-order-x/&amp;gt;. These defaults will affect all animations in the .xml and also any included models unless the included model also has a &amp;lt;defaults&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
So for modelers that want to use the new definitive vertex sorting rules adding the following to the main model is sufficient.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
    &amp;lt;defaults&amp;gt;&lt;br /&gt;
        &amp;lt;axis-animation-vertex-order-xyz/&amp;gt;&lt;br /&gt;
    &amp;lt;/defaults&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Adding the axis animation 3d object to a model ==== &lt;br /&gt;
&lt;br /&gt;
In the '''.ac''' file, specify a SURF with type (bottom 4 bits, 0=polygon, 1=closedline, 2=line) set to 2, and two vertices that define the axis. For example:&lt;br /&gt;
&lt;br /&gt;
    OBJECT poly&lt;br /&gt;
    name &amp;quot;aileron.l-axis&amp;quot;&lt;br /&gt;
    numvert 2&lt;br /&gt;
    3.2077502191170844 0.18160835055097943 4.055616960642423&lt;br /&gt;
    2.6758650763079 0.28024033462188946 6.477876098622225&lt;br /&gt;
    numsurf 1&lt;br /&gt;
    SURF 0x12&lt;br /&gt;
    mat 0&lt;br /&gt;
    refs 2&lt;br /&gt;
    0 0 0&lt;br /&gt;
    1 0 0&lt;br /&gt;
    kids 0&lt;br /&gt;
&lt;br /&gt;
Once the object-name used for the axis has been processed the geometry object will be hidden. This also allows a visual check for any axis objects that are not yet assigned.&lt;br /&gt;
&lt;br /&gt;
It is possible to reuse the same object definition multiple times within a single XML file. &lt;br /&gt;
&lt;br /&gt;
[[File:Canopy-animation-axis-object.png|small|Illustration of where an axis object (2017.2) can be placed for a canopy]]&lt;br /&gt;
&lt;br /&gt;
[[File:Gauges-knobs-animation-axis-object.png|small|Illustration of where an axis object (2017.2) can be placed for cockpit elements]]&lt;br /&gt;
&lt;br /&gt;
== Additional tags that can be used in most animations ==&lt;br /&gt;
=== Conditions ===&lt;br /&gt;
Multiple animations can make use of a conditional. Check &amp;lt;tt&amp;gt;$FGDATA/Docs/README.conditions&amp;lt;/tt&amp;gt; for some more details.&lt;br /&gt;
&lt;br /&gt;
* '''equals:''' property value (or second property) is equal to value/(first)property.&lt;br /&gt;
* '''greater-than:''' property value (or second property) is larger than value/(first)property.&lt;br /&gt;
* '''greater-than-equals:''' property value (or second property) is greater than or equal to value/(first)property.&lt;br /&gt;
* '''less-than:''' property value (or second property) is smaller than value/(first)property.&lt;br /&gt;
* '''less-than-equals:''' property value (or second property) is smaller than or equal to value/(first)property.&lt;br /&gt;
&lt;br /&gt;
The example below is true when n1 has a value greater than 25.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then there are some special tags:&lt;br /&gt;
&lt;br /&gt;
* '''and:'''&lt;br /&gt;
* '''not:'''&lt;br /&gt;
* '''or:'''&lt;br /&gt;
&lt;br /&gt;
In the example below, the condition is true when either n1 is greater than 25% or equal to 0%.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;or&amp;gt;&lt;br /&gt;
    &amp;lt;greater-than&amp;gt;&lt;br /&gt;
     &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
     &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
    &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;equals&amp;gt;&lt;br /&gt;
     &amp;lt;property&amp;gt;engines/engine[1]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
     &amp;lt;value&amp;gt;0&amp;lt;/value&amp;gt;&lt;br /&gt;
    &amp;lt;/equals&amp;gt;&lt;br /&gt;
   &amp;lt;/or&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of implementation into an animation looks as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;suface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;suface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;10&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interpolation ===&lt;br /&gt;
For non-fixed factors, an interpolation &amp;quot;table&amp;quot; can be created. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;interpolation&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 0.0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.0&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 0.667&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.0&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt; 1.0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt; 0.5&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
  &amp;lt;/interpolation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The lines above represent the following table:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!Input&lt;br /&gt;
!Output&lt;br /&gt;
|-&lt;br /&gt;
|0.0&lt;br /&gt;
|0.0&lt;br /&gt;
|-&lt;br /&gt;
|0.667&lt;br /&gt;
|0.0&lt;br /&gt;
|-&lt;br /&gt;
|1.0&lt;br /&gt;
|0.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can add as many entries as you need. Interpolation tables are often used for gear animations (eg. to open doors during gear-movements and close them again once the gear is either retracted or fully extended).&lt;br /&gt;
&lt;br /&gt;
=== Expressions ===&lt;br /&gt;
For some animations it is possible to define complex animations by using [[Expressions|Expressions]]. This even allows to drive the animation from multiple properties without the need for additional Nasal scripts. Here is an example for a translate animation depending on two properties and the cosine function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
     &amp;lt;type&amp;gt;translate&amp;lt;/type&amp;gt;&lt;br /&gt;
     &amp;lt;expression&amp;gt;&lt;br /&gt;
       &amp;lt;product&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/my/factor-property&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;cos&amp;gt;&lt;br /&gt;
           &amp;lt;deg2rad&amp;gt;&lt;br /&gt;
             &amp;lt;property&amp;gt;/my/angular-property&amp;lt;/property&amp;gt;&lt;br /&gt;
           &amp;lt;/deg2rad&amp;gt;&lt;br /&gt;
         &amp;lt;/cos&amp;gt;&lt;br /&gt;
       &amp;lt;/product&amp;gt;&lt;br /&gt;
     &amp;lt;/expression&amp;gt;&lt;br /&gt;
     [..]more elements[..]&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Animations which can utilize [[Expressions|Expressions]] are: &lt;br /&gt;
* [[Howto:Animate_models#Translate|Translate]]&lt;br /&gt;
* [[Howto:Animate_models#Rotate|Rotate]]&lt;br /&gt;
* [[Howto:Animate_models#Scale|Scale]]&lt;br /&gt;
* [[Howto:Animate_models#Range|Range]]&lt;br /&gt;
* [[Howto:Animate_models#Blend|Blend]]&lt;br /&gt;
* [[Howto:Animate_models#Material animation|Material]]&lt;br /&gt;
* [[Howto:Animate_models#PBR animation|PBR]]&lt;br /&gt;
&lt;br /&gt;
See more detailed info at [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
== Lights ==&lt;br /&gt;
As of January 2021 FlightGear supports multiple light sources just like Project Rembrandt has always done.&lt;br /&gt;
[[Compositor#Lights|Adding lights to a model]]&lt;br /&gt;
&lt;br /&gt;
== Object animations ==&lt;br /&gt;
=== Alpha-test ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;alpha-test&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;alpha-factor&amp;gt;0.01&amp;lt;/alpha-factor&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This &amp;quot;animation&amp;quot; is a way to set an alpha test on a model branch. The effect is to avoid depth buffer writing of pixel that are not seen because they are transparent. This is particulary useful when modeling a metallic structure or a tree with a billboard. The threshold of transparency is set with the &amp;lt;alpha-factor&amp;gt; element.  See also [[Pixel testing in effects]].&lt;br /&gt;
&lt;br /&gt;
=== Blend ===&lt;br /&gt;
Blends an object with the surrounding. Comparable to a translucency animation. A value of 0 corresponds to no transparency, i.e. and ordinary solid object, and a value of 1 makes the object fully transparent, i.e., not visible at all.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;blend&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;/velocities/airspeed-kt&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;0.00025&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;min&amp;gt;0.2&amp;lt;/min&amp;gt;&lt;br /&gt;
  &amp;lt;max&amp;gt;0.7&amp;lt;/max&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''property:'''&lt;br /&gt;
* '''factor:'''&lt;br /&gt;
* '''min:'''&lt;br /&gt;
* '''max:'''&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
Note that when using the Project Rembrandt renderer, all transparent and translucent objects must be registered to display properly.  [[Project_Rembrandt#Registering_all_translucent_surfaces|More information here.]]&lt;br /&gt;
&lt;br /&gt;
=== Billboard ===&lt;br /&gt;
This faces an object towards the viewer. Often used on 2D objects, like clouds, trees and lights.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;billboard&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;spherical type=&amp;quot;bool&amp;quot;&amp;gt;true&amp;lt;/spherical&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''spherical:'''&lt;br /&gt;
&lt;br /&gt;
=== Dist-scale ===&lt;br /&gt;
Used to scale an object, based on the distance to the viewer. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;ind&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;dep&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (independent and dependent) are the distance in meters and the scale at that distance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;dist-scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;interpolation&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;0&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;1&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;300&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;4&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
   &amp;lt;entry&amp;gt;&lt;br /&gt;
    &amp;lt;ind&amp;gt;1500&amp;lt;/ind&amp;gt;&lt;br /&gt;
    &amp;lt;dep&amp;gt;8&amp;lt;/dep&amp;gt;&lt;br /&gt;
   &amp;lt;/entry&amp;gt;&lt;br /&gt;
  &amp;lt;/interpolation&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can optionally add [[#Center|&amp;amp;lt;center&amp;amp;gt;]] coordinates, to scale the object around that point.&lt;br /&gt;
&lt;br /&gt;
=== Flash ===&lt;br /&gt;
&lt;br /&gt;
Used to scale an object based on the cosine of the angle between the axis provided in the animation and the view vector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;flash&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;offset&amp;gt;0.0&amp;lt;/offset&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;1.0&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;power&amp;gt;2&amp;lt;/power&amp;gt;&lt;br /&gt;
  &amp;lt;two-sides type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/two-sides&amp;gt;&lt;br /&gt;
  &amp;lt;min&amp;gt;0.0&amp;lt;/min&amp;gt;&lt;br /&gt;
  &amp;lt;max&amp;gt;1.0&amp;lt;/max&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;0.0&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt;0.0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt;0.0&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0.0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;-1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0.1&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''offset:'''&lt;br /&gt;
* '''factor:'''&lt;br /&gt;
* '''power:'''&lt;br /&gt;
* '''two-sides:''' if false, nothing is drawn if the cosine is negative.&lt;br /&gt;
* '''min:'''&lt;br /&gt;
* '''max:'''&lt;br /&gt;
&lt;br /&gt;
scale = factor * pow( cosine, power ) + offset&lt;br /&gt;
&lt;br /&gt;
scale is then clamped between min and max.&lt;br /&gt;
&lt;br /&gt;
and this scale factor is applied to the object, from the center specified. It works best if scale is less than 1. Otherwise, there will be clipping issues.&lt;br /&gt;
&lt;br /&gt;
=== Noshadow ===&lt;br /&gt;
This animation is used to make sure an object will cast no shadow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;noshadow&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Range ===&lt;br /&gt;
: ''See also [[Modeling - Getting Started#Level of Detail (LOD)]].''&lt;br /&gt;
&lt;br /&gt;
To prevent objects -like instruments- being drawn when the aircraft is actually too far away for them to be seen anyway, a range animation is used. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;range&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;min-m&amp;gt;0&amp;lt;/min-m&amp;gt;&lt;br /&gt;
  &amp;lt;max-m&amp;gt;30&amp;lt;/max-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''min-m:''' the shortest distance (in meters) from the object center at which it is visible.&lt;br /&gt;
* '''max-m:''' the largest distance (in meters) from the object center at which it is visible.&lt;br /&gt;
&lt;br /&gt;
You could also use the generic level of detail (LOD) properties, which can be set by the user through View &amp;gt; Adjust LOD rangers: &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Property&lt;br /&gt;
! Description&lt;br /&gt;
! Default value&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/bare&amp;lt;/tt&amp;gt;&lt;br /&gt;
| only a rough exterior model&lt;br /&gt;
| 30,000 m&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/rough&amp;lt;/tt&amp;gt; &lt;br /&gt;
| most should be visible&lt;br /&gt;
| 9,000 m&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;/sim/rendering/static-lod/detailed&amp;lt;/tt&amp;gt; &lt;br /&gt;
| all details should be visible&lt;br /&gt;
| 1,500 m&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The animation code will look like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;range&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;min-m&amp;gt;0&amp;lt;/min-m&amp;gt;&lt;br /&gt;
  &amp;lt;max-property&amp;gt;sim/rendering/static-lod/bare&amp;lt;/max-property&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can have both ranges (max and min) bound to a property, or just one of them.&lt;br /&gt;
* '''min-property:''' &lt;br /&gt;
* '''max-property:'''&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Rotate ===&lt;br /&gt;
One of the most important and frequently used animations of all. It rotates an object to an absolute position in degrees, as provided by the property-value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;rotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;surface-positions/left-aileron-pos-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-deg&amp;gt;25&amp;lt;/offset-deg&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
* '''offset-deg:''' is optional. Offset in degrees.&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Scale ===&lt;br /&gt;
A scale animation scales (resizes) an object. This can be either property-value dependant (first example) or a fixed scale (second example).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;sim/time/sun-angle-rad&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;x-min&amp;gt;1.0&amp;lt;/x-min&amp;gt;&lt;br /&gt;
  &amp;lt;y-min&amp;gt;1.0&amp;lt;/y-min&amp;gt;&lt;br /&gt;
  &amp;lt;z-min&amp;gt;1.0&amp;lt;/z-min&amp;gt;&lt;br /&gt;
  &amp;lt;x-factor&amp;gt;1.4&amp;lt;/x-factor&amp;gt;&lt;br /&gt;
  &amp;lt;y-factor&amp;gt;1.4&amp;lt;/y-factor&amp;gt;&lt;br /&gt;
  &amp;lt;z-factor&amp;gt;2.0&amp;lt;/z-factor&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ?-min: the mimimum scale factor for each axis. If the property value would result in a smaller factor than this setting, the scale animation will hold.&lt;br /&gt;
* ?-factor: the scale factor for each axis (factor*property=scale factor).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;scale&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;x-offset&amp;gt;0.5&amp;lt;/x-offset&amp;gt;&lt;br /&gt;
  &amp;lt;y-offset&amp;gt;0.5&amp;lt;/y-offset&amp;gt;&lt;br /&gt;
  &amp;lt;z-offset&amp;gt;0.5&amp;lt;/z-offset&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* x.offset: the scale factor.&lt;br /&gt;
* Add [[#Center|&amp;amp;lt;center&amp;amp;gt;]] coordinates, to scale the object around that point.&lt;br /&gt;
* '''You can optionally use an [[Howto:Animate_models#Expressions|expression]] in the &amp;lt;factor&amp;gt; or &amp;lt;offset&amp;gt; inputs.''' For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
=== Select ===&lt;br /&gt;
This animation selects (or unselects) objects when certain conditions are true (or false). The example below shows the object when the n1 of engine[1] is higher than 25%.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;condition&amp;gt;&lt;br /&gt;
   &amp;lt;greater-than&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;engines/engine[0]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;value&amp;gt;25&amp;lt;/value&amp;gt;&lt;br /&gt;
   &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
  &amp;lt;/condition&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Shader ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;shader&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;shader&amp;gt;chrome&amp;lt;/shader&amp;gt;&lt;br /&gt;
  &amp;lt;texture&amp;gt;chrome2.png&amp;lt;/texture&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''shader:''' &lt;br /&gt;
* '''texture:''' path to the texture used by the shader.&lt;br /&gt;
&lt;br /&gt;
=== Spin ===&lt;br /&gt;
Very similar to [[#Rotate|rotate]], but the property provides a value in revolutions per minute (RPM) rather than an absolute position in degrees, and offset cannot be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spin&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;engines/engine[0]/n1&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
   &amp;lt;x-m&amp;gt;-1.50&amp;lt;/x-m&amp;gt;&lt;br /&gt;
   &amp;lt;y-m&amp;gt; 1   &amp;lt;/y-m&amp;gt;&lt;br /&gt;
   &amp;lt;z-m&amp;gt; 0.25&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
&lt;br /&gt;
=== Timed ===&lt;br /&gt;
Swtiches between objects at specified intervals. This example switches between a lights-on model and a lights-off model. Lights on are shown 0.2 seconds, while lights off are displayed for 0.8 seconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;timed&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;BacklightOn&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;BacklightOff&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;use-personality type=&amp;quot;bool&amp;quot;&amp;gt;true&amp;lt;/use-personality&amp;gt;&lt;br /&gt;
  &amp;lt;branch-duration-sec&amp;gt;0.8&amp;lt;/branch-duration-sec&amp;gt;&lt;br /&gt;
  &amp;lt;branch-duration-sec&amp;gt;0.2&amp;lt;/branch-duration-sec&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tracking ===&lt;br /&gt;
A ''locked-track animation'' can do exactly the same thing as the [https://docs.blender.org/manual/en/latest/animation/constraints/tracking/locked_track.html Locked Track constraint] available in Blender and can also be used to simulate simple inverse kinematic systems consisting of two bones connected with a revolute joint (aka hinge). For details see: [[Howto:Animate gear scissors using the tracking animation]]&lt;br /&gt;
&lt;br /&gt;
=== Translate ===&lt;br /&gt;
This animation moves an object along an axis (not to be confused with the &amp;lt;code&amp;gt;textranslate&amp;lt;/code&amp;gt; animation which only moves the texture on the UV map, not the geometry). The example below will move an object in the Y direction:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; &lt;br /&gt;
!Property value&lt;br /&gt;
!Output&lt;br /&gt;
|-&lt;br /&gt;
| -1&lt;br /&gt;
| -2.5&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 2.5&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 7.5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;translate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;controls/seat/pilot/position-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;5&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-m&amp;gt;2.5&amp;lt;/offset-m&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
   &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using interpolation tables such as:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;interpolation&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;0.0&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt; 0&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;0.666&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt;0.18&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
	&amp;lt;entry&amp;gt;&amp;lt;ind&amp;gt;1.0&amp;lt;/ind&amp;gt;&amp;lt;dep&amp;gt;0.27&amp;lt;/dep&amp;gt;&amp;lt;/entry&amp;gt;&lt;br /&gt;
&amp;lt;/interpolation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The first figure (&amp;lt;code&amp;gt;&amp;lt;ind&amp;gt;&amp;lt;/code&amp;gt;) refers to the value of the property associated with the object and the second figure (&amp;lt;code&amp;gt;&amp;lt;dep&amp;gt;&amp;lt;/code&amp;gt;) refers to the amount that the object moves in metres. For example, in this case, the object moves 18cm when the value reads 0.66 and 27cm when the value is 1.&lt;br /&gt;
&lt;br /&gt;
'''IF used WTIHOUT property''' : The object is placed at some (Value of Offset) meters away from its original position, along the virtual axis formed by said original position and the point with coordinates x/y/z defined in the &amp;lt;axis&amp;gt; tag.&lt;br /&gt;
Mathematically, assuming the Object to translate is (in the model space) placed at point A (x1, y1, z1) and you want to relocate it to point B (x2, y2, z2) then x2,y2,z2 are the values in the &amp;lt;axis&amp;gt; tag of the Translate animation and &amp;lt;offset&amp;gt; can be computed as SQRT((x2-x1)^2+(y2-y1)^2+(z2-z1)^2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''factor:''' is optional.&lt;br /&gt;
* '''offset-m:''' is optional. Offset in meters.&lt;br /&gt;
* '''[[Howto:Animate_models#Expressions|expression]]:''' is optional. For more details see [[Expressions|Expressions]]&lt;br /&gt;
&lt;br /&gt;
== PBR animation ==&lt;br /&gt;
&lt;br /&gt;
Animate the PBR (Physically-Based Rendering) materials. Keep in mind that your model must use the model-pbr.eff Effect or be a [[glTF]] model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;pbr&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/c172p/material/&amp;lt;/property-base&amp;gt;&lt;br /&gt;
  &amp;lt;base-color-factor&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.3&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.1&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1.0&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/base-color-factor&amp;gt;&lt;br /&gt;
  &amp;lt;metallic-factor&amp;gt;0.0&amp;lt;/metallic-factor&amp;gt;&lt;br /&gt;
  &amp;lt;roughness-factor&amp;gt;0.3&amp;lt;/roughness-factor&amp;gt;&lt;br /&gt;
  &amp;lt;emissive-factor&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;property&amp;gt;panel-brightness&amp;lt;/property&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/emissive-factor&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;property-base&amp;lt;/tt&amp;gt;: All other properties of this animation will be relative to this property node.&lt;br /&gt;
* &amp;lt;tt&amp;gt;base-color-factor&amp;lt;/tt&amp;gt;: The base color texture will be multiplied by this value. Should be an RGBA color.&lt;br /&gt;
* &amp;lt;tt&amp;gt;metallic-factor&amp;lt;/tt&amp;gt;: The metallic texture will be multiplied by this value. Should be a single floating point value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;roughness-factor&amp;lt;/tt&amp;gt;: The roughness texture will be multiplied by this value. Should be a single floating point value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;emissive-factor&amp;lt;/tt&amp;gt;: The emissive texture will be multiplied by this value. Should be an RGB color.&lt;br /&gt;
&lt;br /&gt;
For each of the color components you can use an [[SGExpression]].&lt;br /&gt;
&lt;br /&gt;
== Material animation ==&lt;br /&gt;
Animate the material properties of an object, such as it's texture, shininess or color.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt; &lt;br /&gt;
  &amp;lt;type&amp;gt;material&amp;lt;/type&amp;gt; &lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/c172p/material&amp;lt;/property-base&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  lines as mentioned below&lt;br /&gt;
  ...&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Optional:'''&lt;br /&gt;
* '''property-base:''' All other properties of this animation will be relative to this property node.&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
* Numbers are clamped to 0.0 - 1.0, except &amp;lt;code&amp;gt;shininess&amp;lt;/code&amp;gt;, which is clamped to 0 - 128.&lt;br /&gt;
* By appending &amp;lt;tt&amp;gt;-prop&amp;lt;/tt&amp;gt; each of the material properties can read its value from another property.&lt;br /&gt;
* '''New since SimGear commit &amp;lt;code&amp;gt;51149bf&amp;lt;/code&amp;gt;''': For each of the color components (&amp;lt;code&amp;gt;ambient&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;diffuse&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;emission&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;specular&amp;lt;/code&amp;gt;), the &amp;lt;code&amp;gt;red&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;green&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;blue&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;factor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;offset&amp;lt;/code&amp;gt; tags can each contain an [[Expressions|expression]] instead of a value.&lt;br /&gt;
&lt;br /&gt;
=== Ambient ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/ambient&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Diffuse ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/diffuse&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Emission ===&lt;br /&gt;
{{Main article|Howto: Illuminate faces}}&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;emission&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
   &amp;lt;factor-prop&amp;gt;controls/lighting/panel-norm&amp;lt;/factor-prop&amp;gt;&lt;br /&gt;
  &amp;lt;/emission&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Emission colors are multiplied by the factor-prop value. 1 is maximum color intensity, while 0 is the minimum. Colors are calculated according to the [http://en.wikipedia.org/wiki/RGB_color_model RGB color model].&lt;br /&gt;
&lt;br /&gt;
=== Specular ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;specular&amp;gt;&lt;br /&gt;
   &amp;lt;red&amp;gt;1.0&amp;lt;/red&amp;gt;&lt;br /&gt;
   &amp;lt;green&amp;gt;0.2&amp;lt;/green&amp;gt;&lt;br /&gt;
   &amp;lt;blue&amp;gt;0.0&amp;lt;/blue&amp;gt;&lt;br /&gt;
  &amp;lt;/specular&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Transparency ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;transparency&amp;gt;&lt;br /&gt;
   &amp;lt;alpha-prop&amp;gt;rotors/tail/rpm&amp;lt;/alpha-prop&amp;gt;&lt;br /&gt;
   &amp;lt;factor&amp;gt;-0.0015&amp;lt;/factor&amp;gt;&lt;br /&gt;
   &amp;lt;offset&amp;gt;1&amp;lt;/offset&amp;gt;&lt;br /&gt;
  &amp;lt;/transparency&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Shininess ===&lt;br /&gt;
Shininess is clamped to 0-128.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;shininess&amp;gt;105&amp;lt;/shininess&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threshold ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;threshold&amp;gt;0.001&amp;lt;/threshold&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Texture ===&lt;br /&gt;
Used for the [[Livery over MP]] system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  &amp;lt;property-base&amp;gt;sim/model/livery&amp;lt;/property-base&amp;gt; &lt;br /&gt;
  &amp;lt;texture-prop&amp;gt;engine&amp;lt;/texture-prop&amp;gt; &lt;br /&gt;
  &amp;lt;texture&amp;gt;KLM.png&amp;lt;/texture&amp;gt; &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Texture Animations ==&lt;br /&gt;
Applying different matrix transformations to the textures of an object.&lt;br /&gt;
&lt;br /&gt;
=== Textranslate ===&lt;br /&gt;
A very important animation for cockpits! This animation moves textures over a surface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;textranslate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;autopilot/settings/target-speed-kt&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;bias&amp;gt;0.0001&amp;lt;/bias&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;0.001&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;step&amp;gt;100&amp;lt;/step&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
   &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
   &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''bias:''' Adds an offset to the property before factor/step. A small value is needed to compensate for [http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems floating point accuracy].&lt;br /&gt;
* '''factor:''' property * factor * texture width/height = the amount of pixels that the texture should be translated. If your texture is 256 pixels, an textranslate of 0.1 will result in the texture moving with 26 pixels, into the direction specified by the axis settings.&lt;br /&gt;
* '''step:''' the step size at which the texture is translated. If this is set to 0.1, the texture will only be translated at 0.1, 0.2, 0.3 etc.&lt;br /&gt;
* '''axis:''' the direction in which the texture is translated. Y is up/down, while X is left/right.&lt;br /&gt;
&lt;br /&gt;
=== Texrotate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;texrotate&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;some/property/path&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;factor&amp;gt;25&amp;lt;/factor&amp;gt;&lt;br /&gt;
  &amp;lt;offset-deg&amp;gt;25&amp;lt;/offset-deg&amp;gt;&lt;br /&gt;
  &amp;lt;center&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;0.5&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0.5&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/center&amp;gt;&lt;br /&gt;
  &amp;lt;axis&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;1&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/axis&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Textrapezoid ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;textrapezoid&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;HUD.l.canvas&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;property&amp;gt;/hud/trapezoid-correction&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;side&amp;gt;bottom&amp;lt;/side&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''side''': side of quad which should be scaled (''top'' (default)/''right''/''bottom''/''left'')&lt;br /&gt;
&lt;br /&gt;
=== Texmultiple ===&lt;br /&gt;
&lt;br /&gt;
Only one texture matrix can be applied to each object. With ''textmultiple'' multiple texture animations can be combined into a single matrix, applied to the specified object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;texmultiple&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;HUD.l.canvas&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textranslate&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/offset-x&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;axis&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;1&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/axis&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textranslate&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/offset-y&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;axis&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;1&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/axis&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
  &amp;lt;transform&amp;gt;&lt;br /&gt;
    &amp;lt;subtype&amp;gt;textrapezoid&amp;lt;/subtype&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/hud/trapezoid-correction&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/transform&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object interaction animations ==&lt;br /&gt;
=== Enable-hot ===&lt;br /&gt;
Scenery objects are automatically defined as solid by FlightGear, meaning that an aircraft can taxi on them and/or crash when touching. For certain objects (groundmarkings, beacon light-beams etc.) this might be an unwanted feature. The solidness can be disabled with the following animation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt;&lt;br /&gt;
  &amp;lt;enable-hot type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/enable-hot&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''enable-hot:''' can be either true or false. Remember that objects are automatically solid, so it should not be necessary to set this at all when wanting solidness.&lt;br /&gt;
&lt;br /&gt;
=== Interactions ===&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
 &amp;lt;animation&amp;gt; &lt;br /&gt;
  &amp;lt;type&amp;gt;interaction&amp;lt;/type&amp;gt; &lt;br /&gt;
  &amp;lt;object-name&amp;gt;Object&amp;lt;/object-name&amp;gt; &lt;br /&gt;
  &amp;lt;interaction-type&amp;gt;carrier-wire&amp;lt;/interaction-type&amp;gt; &lt;br /&gt;
 &amp;lt;/animation&amp;gt; &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''interaction-type:''' can have the following values:&lt;br /&gt;
**'''carrier-catapult:'''&lt;br /&gt;
** '''carrier-wire:''' makes the object act as an arresting wire, as used on [[aircraft carrier]]s.&lt;br /&gt;
&lt;br /&gt;
== Direct manipulation animations ==&lt;br /&gt;
=== Knob / slider (v. 2.11-) ===&lt;br /&gt;
{{Main article|Knob / slider animation}}&lt;br /&gt;
&lt;br /&gt;
=== Pick ===&lt;br /&gt;
{{Main article|Howto: Make a clickable panel#Pick}}&lt;br /&gt;
&lt;br /&gt;
=== Touch ===&lt;br /&gt;
&lt;br /&gt;
The touch animation provides the normalized coordinates of a touch (or click) event on a 2d surface. The coordinates are passed in the argument and can be accessed using cmdarg() in Nasal.&lt;br /&gt;
&lt;br /&gt;
* Touch animation is designed to work with a quad that is being used as a Canvas placement (display).&lt;br /&gt;
* The touch animation must not be combined with a pick animation on the same object.&lt;br /&gt;
* More info here: [[Touch Animation]]&lt;br /&gt;
&lt;br /&gt;
==== touch example ====&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;animation&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;touch&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;visible&amp;gt;true&amp;lt;/visible&amp;gt;&lt;br /&gt;
        &amp;lt;object-name&amp;gt;CanvasPlacement&amp;lt;/object-name&amp;gt;&lt;br /&gt;
        &amp;lt;action&amp;gt;&lt;br /&gt;
            &amp;lt;touch&amp;gt;0&amp;lt;/touch&amp;gt;&lt;br /&gt;
            &amp;lt;repeatable&amp;gt;false&amp;lt;/repeatable&amp;gt;&lt;br /&gt;
            &amp;lt;binding&amp;gt;&lt;br /&gt;
                &amp;lt;command&amp;gt;nasal&amp;lt;/command&amp;gt;&lt;br /&gt;
                &amp;lt;script&amp;gt;print(&amp;quot;touch input (&amp;quot;,cmdarg().getNode(&amp;quot;x&amp;quot;).getValue(),&amp;quot;,&amp;quot;,cmdarg().getNode(&amp;quot;y&amp;quot;).getValue())&amp;lt;/script&amp;gt;&lt;br /&gt;
            &amp;lt;/binding&amp;gt;&lt;br /&gt;
        &amp;lt;/action&amp;gt;&lt;br /&gt;
    &amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Shadow Handling ==&lt;br /&gt;
There exist several possibilites for handling of shadows. &amp;lt;br /&amp;gt;&lt;br /&gt;
See '''[[ALS_technical_notes|ALS Technical Notes]]''' and more specific '''[[ALS_technical_notes#ALS_fuselage_shadow_effect|Fuselage Shadow Effect with ALS]]''' for a relatively simple shadow handling.&amp;lt;br /&amp;gt;&lt;br /&gt;
See '''[[Project Rembrandt]]''' which - amongst other functionality - implements a very realistic shadow mapping.&lt;br /&gt;
As of January 2021 Project Rembrandt was replaced by the '''[[Compositor]]''' renderer which combines both Project Rembrandt and ALS in a single rendering engine. This also means that the Fuselage Shadow Effect with ALS is now deprecated.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://www.opensubscriber.com/message/flightgear-devel@flightgear.org/958955.html |title=&amp;quot;material&amp;quot; animation (and the bo105 as an example) |first=Melchior |last=Franz |date=22 March 2005 |work=FlightGear-devel mailinglist }}&lt;br /&gt;
* {{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg01546.html |title=flash animation |first=Frederic |last=Bouvier |date=22 Feb 2006 |work=FlightGear-devel mailinglist }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Wiki articles ===&lt;br /&gt;
* [[MP Fallback models]]&lt;br /&gt;
* [[Howto:Animate gear scissors]]&lt;br /&gt;
* [[Howto:Animate helicopters]]&lt;br /&gt;
* [[Howto:Creating 3D instruments]]&lt;br /&gt;
&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=37353|title=3d models, how to produce them in an understandable way}} (April 2020-) - Touches on the subject of not using LOD range animations in scenery models.&lt;br /&gt;
* {{forum link|t=36545|title=speedo Drum settings}} (November 2019) - Animating a mechanical multi-digit drum counter&lt;br /&gt;
&lt;br /&gt;
[[Category:Aircraft enhancement|Animate models]]&lt;br /&gt;
[[Category:Howto|Animate models]]&lt;br /&gt;
[[Category:Modeling|Animate models]]&lt;br /&gt;
[[Category:Scenery enhancement|Animate models]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=139598</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=139598"/>
		<updated>2024-03-31T13:13:45Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders and is only available on 'next' branch or nightly builds (2020.4). The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
* Opacity map for environment map. This would allow for more realistic reflections inside the cockpit. We block light coming from everywhere except the windows.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139148</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139148"/>
		<updated>2024-02-20T18:58:59Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
* Check if we still need the ATI viewport hack&lt;br /&gt;
* Revisit the Canvas placement code. Do we need the replacing by texture name anymore?&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139105</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139105"/>
		<updated>2024-02-09T22:55:03Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
* Check if we still need the ATI viewport hack&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139102</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139102"/>
		<updated>2024-02-08T22:08:53Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001, increase far plane distance to a huge value like 1000km (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139101</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139101"/>
		<updated>2024-02-08T22:07:38Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001 (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
* Update READMEs, namely osgtext, hud, effects. Maybe add a compositor README?&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Compositor&amp;diff=139086</id>
		<title>Compositor</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Compositor&amp;diff=139086"/>
		<updated>2024-02-07T13:46:31Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = Compositor logo.png&lt;br /&gt;
|name        = Compositor Framework&lt;br /&gt;
|started     = 01/2018 (Available since FlightGear 2020.4)&lt;br /&gt;
|description = Dynamic rendering pipeline configured via the [[Property tree]] and [[PropertyList XML File|XML]]&lt;br /&gt;
|status      = Stable (merged and actively maintained)&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{simgear file|simgear/scene/viewer}}&lt;br /&gt;
* {{flightgear file|src/Viewer}}&lt;br /&gt;
* {{fgdata file|Compositor}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''Compositor''' aims to bring multi-pass rendering to FlightGear. It encapsulates a rendering pipeline and exposes its parameters to a [[Property Tree]] interface. At startup, FlightGear reads the pipeline definition file for each physical viewport defined on the [[Howto:Configure camera view windows|CameraGroup settings]]. If no Compositor file is specified for a physical camera, the one given by the &amp;lt;code&amp;gt;--compositor=&amp;lt;/code&amp;gt; startup command will be used. If such startup option is not used either, FlightGear will look for a valid Compositor file in &amp;lt;tt&amp;gt;$FG_ROOT/Compositor/default.xml&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The Compositor introduces a new dedicated fgdata directory for new/custom rendering pipelines: {{Fgdata file|Compositor}}.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
First discussed in 03/2012 during the early [[Rembrandt]] days, Zan (Lauri Peltonen) came up with a set of patches demonstrating how to create an XML-configurable rendering pipeline. Back then, this work was considered to look pretty promising &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28946515/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Mathias Fröhlich &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; and at the time plans were discussed to unify this with the ongoing Rembrandt implementation (no longer maintained).&lt;br /&gt;
&lt;br /&gt;
Adopting Zan's approach would have meant that efforts like [[Rembrandt]] (deferred rendering) could have been implemented without requiring C++ space modifications, i.e. purely in [[Base package]] space. Rembrandt's developer (FredB) suggested to extend the format to avoid duplicating the stages when you have more than one viewport, i.e.  specifying a pipeline as a template, with conditions like in effects, and have the current camera layout refer the pipeline that would be duplicated, resized and positioned for each declared viewport &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944773/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Frederic Bouvier &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zan's original patches can still be found in his newcameras branches which allow the user to define the rendering pipeline in preferences.xml: {{gitorious source|proj=fg|repo=zans-flightgear|branch=newcameras|text=FlightGear}}, {{gitorious source|proj=fg|repo=zans-simgear|branch=newcameras|text=SimGear}}. At that point, it didn't have everything Rembrandt's pipeline needs, but most likely could be easily enhanced to support those things. Basically, the original version added support for multiple camera passes, texture targets, texture formats, passing textures from one pass to another etc, while preserving the standard rendering line if user wants that. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944733/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Lauri Peltonen &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the early days of Zan's groundwork, providing the (hooks) infrastructure to enable base package developers to prototype, test and develop distinct rendering pipelines without requiring C++ space modifications has been a long-standing idea, especially after the [[Canvas]] system became available in early 2012, which demonstrated how RTT-rendering buffers (FBOs) could be set up, created and manipulated procedurally (i.e. at run-time) using XML, the property tree and [[Nasal]] scripting. &amp;lt;ref&amp;gt;{{forum link|type=search|title=Zan's Rembrandt and Canvas work|keywords=zan+rembrandt+canvas}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new '''Compositor''' is an improved re-implementation of Zan's original work using not just XML, but also [[Property Tree|properties]] and a handful of [[Canvas]] concepts.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
* Completely independent of other parts of the simulator, i.e. it's part of [[SimGear]] and can be used in a standalone fashion if needed, ala Canvas.&lt;br /&gt;
* Although independent, its aim is to be fully compatible with the current rendering framework in FG. This includes the [[Effects]] system, [[Howto:Configure camera view windows|CameraGroup]], [[Rembrandt]], [[ALS]] and [[Canvas]].&lt;br /&gt;
* Its functionality overlaps Rembrandt: what can be done with Rembrandt can be done with the Compositor, but not vice versa.&lt;br /&gt;
* Fully configurable via an XML interface without compromising performance (ala Effects, using [[PropertyList XML File|PropertyList files]]).&lt;br /&gt;
* Flexible, expandable and compatible with modern graphics.&lt;br /&gt;
* It doesn't increase the hardware requirements, it expands the hardware range FG can run on. People with integrated GPUs (Intel HD etc) can run a Compositor with a single pass that renders directly to the screen like before, while people with more powerful cards can run a Compositor that implements deferred rendering, for example.&lt;br /&gt;
* Static branching support. Every pipeline element can be enabled/disabled at startup via a [[Conditions|&amp;lt;condition&amp;gt; block]].&lt;br /&gt;
* The entire rendering pipeline can be reloaded via an fgcommand (&amp;lt;tt&amp;gt;reload-compositor&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== How to enable the Compositor ==&lt;br /&gt;
&lt;br /&gt;
The Compositor is now the default renderer framework in FlightGear since 2020/11/17. It will be included as part of version 2020.4 onwards.&lt;br /&gt;
&lt;br /&gt;
If you compile FlightGear from source, you can already try the Compositor. Make sure you are pulling the latest version of the 'next' branch. You can also try out the latest nightly build from the [[FlightGear build server]].&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
The Compositor introduces a new way of defining lights that is renderer agnostic, so every rendering pipeline will be able to access the lights that have been implemented like this. The resulting light volumes can be visualized for debugging purposes by setting the property &amp;lt;tt&amp;gt;/sim/debug/show-light-volumes&amp;lt;/tt&amp;gt; to true.&lt;br /&gt;
&lt;br /&gt;
You can edit existing lights with the '''[[Illuminator addon|Illuminator]]''', but you have to define them first e.g. in your aircraft. The Illuminator add-on is meant for fine-tuning the light parameters.&lt;br /&gt;
&lt;br /&gt;
[[Project Rembrandt]] light definitions are also read by the Compositor for backwards compatibility reasons. However, it is not recommended to use the old syntax for new/updated projects.&lt;br /&gt;
&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top style=&amp;quot;width: 20%;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.03&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.03&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.03&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/ambient&amp;gt;&lt;br /&gt;
  &amp;lt;diffuse&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.95&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.9&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.9&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/diffuse&amp;gt;&lt;br /&gt;
  &amp;lt;specular&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.95&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.9&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.9&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/specular&amp;gt;&lt;br /&gt;
  &amp;lt;attenuation&amp;gt;&lt;br /&gt;
    &amp;lt;c&amp;gt;1.0&amp;lt;/c&amp;gt;&lt;br /&gt;
    &amp;lt;l&amp;gt;0.09&amp;lt;/l&amp;gt;&lt;br /&gt;
    &amp;lt;q&amp;gt;0.032&amp;lt;/q&amp;gt;&lt;br /&gt;
  &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
  &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;controls/lighting/instruments-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/dim-factor&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top style=&amp;quot;width: 80%;&amp;quot;|&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''name'''&amp;lt;/tt&amp;gt;. An {{tag|animation}} will be able to reference the light by this name. Most [[Howto:Animate_models|animations]] will work as expected (rotate, translate, spin etc). Material animations are not supported.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''type'''&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;point&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''position'''&amp;lt;/tt&amp;gt;. The position of the light source in model space and in meters.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''direction'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. It indicates the direction of the spotlight. This parameter can be specified in three different ways:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 1px solid darkgray;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Direction vector&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Look-at point&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Rotation angles&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | A vector in model space that specifies the direction. Doesn't have to be normalized.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
&amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
&amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | The spotlight will calculate its direction by looking at this position from the light position. The point is in model space and in meters.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;lookat-x-m&amp;gt;-8.031&amp;lt;/lookat-x-m&amp;gt;&lt;br /&gt;
&amp;lt;lookat-y-m&amp;gt;0&amp;lt;/lookat-y-m&amp;gt;&lt;br /&gt;
&amp;lt;lookat-z-m&amp;gt;-2&amp;lt;/lookat-z-m&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | A three angle rotation in degrees that rotates the spotlight around the three axes. A 0 degree angle in all axes makes the spotlight point downwards (negative Z).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pitch-deg&amp;gt;90&amp;lt;/pitch-deg&amp;gt;&lt;br /&gt;
&amp;lt;roll-deg&amp;gt;0&amp;lt;/roll-deg&amp;gt;&lt;br /&gt;
&amp;lt;heading-deg&amp;gt;0&amp;lt;/heading-deg&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''ambient'''&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'''diffuse'''&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;'''specular'''&amp;lt;/tt&amp;gt;. Four-component vectors that specify the light color.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''attenuation'''&amp;lt;/tt&amp;gt;. Three-component vector where &amp;lt;code&amp;gt;&amp;lt;c&amp;gt;&amp;lt;/code&amp;gt; specifies the constant factor, &amp;lt;code&amp;gt;&amp;lt;l&amp;gt;&amp;lt;/code&amp;gt; specifies the linear factor and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;q&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; specifies the quadratic factor. These factors are plugged into the OpenGL light attenuation formula [[File:Spotlight_attenuation.png]] where d is the distance of the fragment to the light source. See this [http://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation table] for a list of attenuation values based on the range of the light.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''range-m'''&amp;lt;/tt&amp;gt;. Maximum range from the light source position in meters. This value will be used by the renderers to determine if a fragment is illuminated by this source. Every fragment outside this range isn't guaranteed to be affected by the light, even if the attenuation factor isn't 0 in that particular fragment.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''spot-cutoff'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. It specifies the maximum spread angle of a light source. Only values in the range 0 90 are accepted. If the angle between the direction of the light and the direction from the light to the fragment being lighted is greater than the spot cutoff angle, it won't be lit.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''spot-exponent'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. Higher spot exponents result in a more focused light source, regardless of the spot cutoff angle.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''dim-factor'''&amp;lt;/tt&amp;gt; ('''Optional'''). Controls the dimming of the light source through an [[Expressions|expression]].&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''debug-color'''&amp;lt;/tt&amp;gt; ('''Optional'''). Sets the color of the debug light volume. By default it's red.&lt;br /&gt;
'''&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;Important: &amp;lt;/span&amp;gt;'''The following parameters are '''only''' available in the [[HDR Pipeline]].&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''color'''&amp;lt;/tt&amp;gt;. The color or hue of emitted light. It is expected to be in the sRGB color space.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''intensity'''&amp;lt;/tt&amp;gt;. The brightness of the light. This value can be (and will almost always be) higher than 1.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Shadows ===&lt;br /&gt;
&lt;br /&gt;
The shadow mapping algorithm can be customized entirely by the rendering pipeline. This means that each pipeline will have its own requirements when it comes to shadows. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Use the [[Howto:Animate models#Noshadow|&amp;lt;tt&amp;gt;noshadow&amp;lt;/tt&amp;gt; animation]] to disable shadows on objects that don't need them. An example would be billboarded lights (light sprites) or really small cockpit elements that don't need shadows and would cause degraded performance.&lt;br /&gt;
If the casted aircraft shadow appears blocky then there probably are some objects which need the noshadow animation applied. Most notably are billboarded lights which include [[ALS_technical_notes#ALS procedural lights|ALS procedural lights]].&lt;br /&gt;
* Try to mark as many cockpit objects as possible as &amp;lt;tt&amp;gt;interior&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;model&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;interior&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;usage&amp;gt;interior&amp;lt;/usage&amp;gt;&lt;br /&gt;
  &amp;lt;path&amp;gt;Aircraft/JA37/Models/ja37-interior.xml&amp;lt;/path&amp;gt; &amp;lt;!-- All the objects that should only be seen when inside the cockpit are in this file --&amp;gt;&lt;br /&gt;
&amp;lt;/model&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Unlike in Rembrandt, polygons facing the Sun are the ones used to generate the shadow map, so single sided surfaces and non-closed objects should be rendered correctly.&lt;br /&gt;
&lt;br /&gt;
== Effects and Shaders ==&lt;br /&gt;
&lt;br /&gt;
=== Schemes ===&lt;br /&gt;
&lt;br /&gt;
Effects can have different implementations depending on the Compositor pipeline being used. For example, a grass Effect implemented for a high quality pipeline might have much more detail than one that targets low specification machines. Still, they both implement the &amp;quot;look&amp;quot; of grass, so they share the same Effect file (grass.eff).&lt;br /&gt;
&lt;br /&gt;
The Compositor chooses which implementation of an Effect to render based on the &amp;lt;tt&amp;gt;&amp;lt;scheme&amp;gt;&amp;lt;/tt&amp;gt; of the techniques.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;technique n=&amp;quot;15&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;scheme&amp;gt;test-scheme&amp;lt;/scheme&amp;gt;&lt;br /&gt;
  [...]&lt;br /&gt;
&amp;lt;/technique&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the technique will be chosen if the Compositor pipeline &amp;lt;tt&amp;gt;&amp;lt;scene&amp;gt;&amp;lt;/tt&amp;gt; pass uses the &amp;lt;tt&amp;gt;test-scheme&amp;lt;/tt&amp;gt; Effect scheme. Consequently, porting an Effect to a Compositor pipeline will require knowing which Effect schemes it uses and writing a technique for each one. The only exception to this is the Classic/default pipeline, which uses techniques with no scheme.&lt;br /&gt;
&lt;br /&gt;
=== Built-in uniforms ===&lt;br /&gt;
&lt;br /&gt;
The Compositor provides a set of built-in uniforms that are passed along to every shader. These uniforms must '''not''' be defined in the Effect file, as they are defined and updated in C++.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
!Name&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_TextureMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Texture matrix that replaces the old fixed-function behaviour. If no texture animations are present it corresponds to the identity matrix.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Viewport&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Viewport geometry for the current pass (x, y, width, height).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PixelSize&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the width and height of the viewport.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|View matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the view matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame view matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame inverse of the view matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevProjectionMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame inverse of the projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionCart&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in cartesian coordinates.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionGeod&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraDistanceToEarthCenter&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance from the camera to the center of the Earth in meters.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraWorldUp&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Camera up vector in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraViewUp&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Camera up vector in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_EarthRadius&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Earth radius right below the camera position in meters.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_NearFar&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Near and far clipping planes in meters. x component is the near plane, y component is the far plane.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Fcoef&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used by logarithmic depth.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FOVScale&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used by logarithmic depth.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Sun (directional light) direction in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirectionWorld&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Sun (directional light) direction in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunZenithCosTheta&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dot product between the Sun direction and the up vector at the camera position.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Moon (directional light) direction in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonDirectionWorld&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Moon (directional light) direction in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonZenithCosTheta&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dot product between the Moon direction and the up vector at the camera position.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Creating a custom rendering pipeline ==&lt;br /&gt;
&lt;br /&gt;
Since the Compositor is completely data-driven, new rendering pipelines can be created by writing a custom XML pipeline definition. This section tries to document most of the available parameters, but the best and most up-to-date resource is the Compositor parsing code in SimGear ({{simgear file|simgear/scene/viewer}}). See existing pipelines in {{fgdata file|Compositor}} for practical examples on how to use these parameters.&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that every pipeline element can be enabled/disabled through a [[Conditions|&amp;lt;condition&amp;gt; block]]. This allows for dynamic rendering pipelines that have toggleable features. However, the pipeline can't be updated in real-time: the simulator has to be restarted or the Compositor has to be reloaded through the &amp;lt;tt&amp;gt;reload-compositor&amp;lt;/tt&amp;gt; [[Fgcommands|fgcommand]].&lt;br /&gt;
&lt;br /&gt;
=== Buffers ===&lt;br /&gt;
&lt;br /&gt;
A buffer represents a texture or, more generically, a region of GPU memory.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| string&lt;br /&gt;
|&lt;br /&gt;
| Passes will be able to address the buffer by this name&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;1d, 2d, 2d-array, 2d-multisample, 3d, rect, cubemap&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
| Any texture type allowed by OpenGL&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;width&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer or &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; to use the physical viewport width. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture width&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;screen-width-scale&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| If &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; was used, this controls the width scaling factor&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;height&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer or &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; to use the physical viewport height. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture height&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;screen-height-scale&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| If &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; was used, this controls the height scaling factor&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;depth&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture depth&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| See {{simgear file|simgear/scene/viewer/CompositorBuffer.cxx}} for the latest available values&lt;br /&gt;
| &amp;lt;tt&amp;gt;rgba8&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Specifies the texture format. It corresponds to the ''internalformat'', ''format'' and ''type'' arguments of the OpenGL function ''glTexImage2D''&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;min-filter, mag-filter&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;linear, linear-mipmap-linear, linear-mipmap-nearest, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;linear&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Change the minification and magnification filtering respectively&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;wrap-s, wrap-t, wrap-r&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;clamp, clamp-to-edge, clamp-to-border, repeat, mirror&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;clamp-to-border&amp;lt;/tt&amp;gt;&lt;br /&gt;
| They change the wrap mode for each coordinate&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;anisotropy&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;border-color&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| vec4&lt;br /&gt;
| &amp;lt;tt&amp;gt;(0.0f, 0.0f, 0.0f, 0.0f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-comparison&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-texture-mode&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;luminance, intensity, alpha&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;luminance&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-compare-func&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;never, less, equal, lequal, greater, notequal, gequal, always&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;lequal&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Passes ===&lt;br /&gt;
&lt;br /&gt;
A pass wraps around an [http://public.vrac.iastate.edu/vancegroup/docs/OpenSceneGraphReferenceDocs-3.0/a00089.html osg::Camera]. Passes all have some common parameters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;clear-color, clear-accum, clear-depth and clear-stencil&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| vec4&lt;br /&gt;
| black, black, &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; respectively&lt;br /&gt;
| Pass clear colors&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;clear-mask&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;color, stencil, depth, accum&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;color depth&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Pass clear mask&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;effect-scheme&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid effect scheme name&lt;br /&gt;
| None&lt;br /&gt;
| The pass will try to use the specified effect scheme to draw every object.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Passes can render to a buffer (Render to Texture), to several buffers (Multiple Render Targets) or directly to the framebuffer. This is accomplished by the &amp;lt;code&amp;gt;&amp;lt;attachment&amp;gt;&amp;lt;/code&amp;gt; tag. Possible parameters of an attachment are:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Valid buffer name&lt;br /&gt;
| &lt;br /&gt;
| The name of the buffer to output to&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;component&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;color, color0&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;color15, depth, stencil, depth-stencil&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
| FBO attachment point&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;level&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Mipmap level of the texture that is attached&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;face&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Face of cube map texture or z-level of 3d texture&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;mipmap-generation&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Whether mipmap generation should be done for texture&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;multisample-samples&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Multisample anti-aliasing (MSAA) samples&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;multisample-color-samples&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Multisample anti-aliasing (MSAA) color samples&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Passes can also receive buffers as input and use them in their shaders. This is accomplished by the &amp;lt;code&amp;gt;&amp;lt;binding&amp;gt;&amp;lt;/code&amp;gt; tag, which has the following parameters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Valid buffer name&lt;br /&gt;
| &lt;br /&gt;
| The name of the buffer to bind&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;unit&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| int&lt;br /&gt;
| &lt;br /&gt;
| The texture unit to place the texture on. Effects will be able to access the buffer on this texture unit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are specific pass types, each with their own set of custom parameters.&lt;br /&gt;
&lt;br /&gt;
==== scene ====&lt;br /&gt;
Renders the scene from the point of view given by the CameraGroup.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;cull-mask&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| A 32 bit number. See {{simgear file|simgear/scene/util/RenderConstants.hxx}} to know which bits enable what&lt;br /&gt;
| &amp;lt;tt&amp;gt;0xffffffff&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Specifies the cull mask to be used in the underlying &amp;lt;tt&amp;gt;osg::Camera&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;z-near, z-far&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| 0.0 uses the value given by the CameraGroup&lt;br /&gt;
| Sets a custom near and far values. Useful for implementing depth partition and limiting the depth range on cubemap passes&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;cubemap-face&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; (don't use cubemap)&lt;br /&gt;
| Ignores the given view and projection matrices and uses a custom one that renders the scene as if it was seen from inside a cubemap looking towards the specified face&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;use-shadow-pass&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| string&lt;br /&gt;
| Empty&lt;br /&gt;
| Name of a shadow mapping pass. Exposes shadow mapping related uniforms to the shaders of the current pass&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scene passes can also use the tag &amp;lt;code&amp;gt;&amp;lt;clustered-shading&amp;gt;&amp;lt;/code&amp;gt; to enable clustered shading (lights). The following parameters are available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-pointlights&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1024&lt;br /&gt;
| Maximum amount of point light sources allowed on the entire scene&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-spotlights&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1024&lt;br /&gt;
| Maximum amount of spot light sources allowed on the entire scene&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-light-indices&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 256&lt;br /&gt;
| Size of the light indices texture. Keep in mind that it is a 2D texture, so the total size will be e.g. 256x256&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;tile-size&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 128&lt;br /&gt;
| Size of each clustered shading tile&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;num-threads&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1&lt;br /&gt;
| Number of threads to use during the light culling process. Keep in mind that a high thread count when there aren't many lights will worsen performance due to the thread creation overhead&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;depth-slices&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1&lt;br /&gt;
| Number of slices to partition the view frustum in the Z axis. Higher numbers will cull lights more aggressively, increasing performance if there are many lights further out that don't contribute much to the overall scene's lighting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== quad ====&lt;br /&gt;
Renders a fullscreen quad with an optional [[Effects|effect]] applied. Useful for screen space shaders (like SSAO, Screen Space Reflections or bloom) and deferred rendering.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;geometry&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float values for &amp;lt;code&amp;gt;&amp;lt;x&amp;gt;, &amp;lt;y&amp;gt;, &amp;lt;width&amp;gt;, &amp;lt;height&amp;gt;, &amp;lt;scale&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;0.0, 0.0, 1.0, 1.0, 1.0&amp;lt;/tt&amp;gt; respectively&lt;br /&gt;
| Size of the fullscreen quad inside the viewport using normalized coordinates.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;effect&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid Effect file&lt;br /&gt;
| None&lt;br /&gt;
| This Effect will be applied to the quad geometry&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== csm ====&lt;br /&gt;
Implements Cascaded Shadow Mapping by rendering the scene from a light's point of view (the Sun by default). For now it only supports directional light sources. There has to be one &amp;lt;tt&amp;gt;csm&amp;lt;/tt&amp;gt; pass for each cascade.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;light-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid light name that exists in the scene graph&lt;br /&gt;
| &amp;lt;tt&amp;gt;FGLightSource&amp;lt;/tt&amp;gt; (Sun)&lt;br /&gt;
| The name of the &amp;lt;tt&amp;gt;osg::LightSource&amp;lt;/tt&amp;gt; to use for this shadow map&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;render-at-night&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| true&lt;br /&gt;
| Whether to render the shadows at night or not&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;near-m, far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| float (meters)&lt;br /&gt;
|&lt;br /&gt;
| They specify the range of the shadow map&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Wiki articles ===&lt;br /&gt;
* [[HDR Pipeline]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
* [[Canvas View Camera Element]]&lt;br /&gt;
* [[CompositeViewer Support]]&lt;br /&gt;
* [[Uniform Buffer Objects]]&lt;br /&gt;
* [[FlightGear CIGI Support (Common Image Generator Interface)]]&lt;br /&gt;
&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=36269|text=The Compositor}}&lt;br /&gt;
* {{forum link|t=35095|text=Clustered Forward Rendering}} (12/2018)&lt;br /&gt;
* {{forum link|t=33045|text=Getting started with RTT}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=139085</id>
		<title>Effect framework</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=139085"/>
		<updated>2024-02-07T13:43:34Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
The '''Effect framework''' as per FlightGear version 2020.3&lt;br /&gt;
&lt;br /&gt;
Effects describe the graphical appearance of 3D objects and scenery in&lt;br /&gt;
FlightGear. The main motivation for effects is to support OpenGL&lt;br /&gt;
shaders and to provide different implementations for graphics hardware&lt;br /&gt;
of varying capabilities. Effects are similar to DirectX effects files&lt;br /&gt;
and Ogre3D material scripts.&lt;br /&gt;
&lt;br /&gt;
An effect is a property list. The property list syntax is extended&lt;br /&gt;
with new &amp;quot;vec3d&amp;quot; and &amp;quot;vec4d&amp;quot; types to support common computer graphics&lt;br /&gt;
values. Effects are read from files with a &amp;quot;.eff&amp;quot; extension or can be&lt;br /&gt;
created on-the-fly by FlightGear at runtime.  An effect consists of a&lt;br /&gt;
&amp;quot;parameters&amp;quot; section followed by &amp;quot;technique&amp;quot; descriptions.  The&lt;br /&gt;
&amp;quot;parameters&amp;quot; section is a tree of values that describe, abstractly,&lt;br /&gt;
the graphical characteristics of objects that use the effect. Techniques&lt;br /&gt;
refer to these parameters and use them to set OpenGL state or to set&lt;br /&gt;
parameters for shader programs. The names of properties in the&lt;br /&gt;
parameter section can be whatever the effects author chooses, although&lt;br /&gt;
some standard parameters  are set by FlightGear itself. On the other&lt;br /&gt;
hand, the properties in the techniques section are all defined by the&lt;br /&gt;
FlightGear. &lt;br /&gt;
&lt;br /&gt;
== Default effects in terrain materials and models ==&lt;br /&gt;
Effects for terrain work in this way: for each material type in&lt;br /&gt;
materials.xml an effect is created that inherits from a single default&lt;br /&gt;
terrain effect, Effects/terrain-default.eff. The parameters section of&lt;br /&gt;
the effect is filled in using the ambient, diffuse, specular,&lt;br /&gt;
emissive, shininess, and transparent fields of the material. The&lt;br /&gt;
parameters image, filter, wrap-s, and wrap-t are also initialized from&lt;br /&gt;
the material xml. Seperate effects are created for each texture&lt;br /&gt;
variant of a material.&lt;br /&gt;
&lt;br /&gt;
Model effects are created by walking the OpenSceneGraph scene graph&lt;br /&gt;
for a model and replacing nodes (osg::Geode) that have state sets with&lt;br /&gt;
node that uses an effect instead. Again, a small effect is created&lt;br /&gt;
with parameters extracted from OSG objects; this effect inherits, by&lt;br /&gt;
default, from Effects/model-default.eff. A larger set of parameters is&lt;br /&gt;
created for model effects than for terrain because there is more&lt;br /&gt;
variation possible from the OSG model loaders than from the terrain&lt;br /&gt;
system. The parameters created are: &lt;br /&gt;
&lt;br /&gt;
* material active, ambient, diffuse, specular, emissive, shininess, color mode&lt;br /&gt;
# blend active, source, destination&lt;br /&gt;
# shade-model&lt;br /&gt;
# cull-face&lt;br /&gt;
* rendering-hint&lt;br /&gt;
* texture type, image, filter, wrap-s, wrap-t&lt;br /&gt;
&lt;br /&gt;
== Specifying custom effects ==&lt;br /&gt;
You can specify the effects that will be used by FlightGear as the&lt;br /&gt;
base effect when it creates terrain and model effects.&lt;br /&gt;
&lt;br /&gt;
In the terrain materials.xml, an &amp;quot;effect&amp;quot; property specifies the name&lt;br /&gt;
of the model to use.&lt;br /&gt;
&lt;br /&gt;
Material animations will be implemented by creating a new effect&lt;br /&gt;
that inherits from one in a model, overriding the parameters that&lt;br /&gt;
will be animated.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
The $FGDATA/Effects directory contains the effects definitions; look there for&lt;br /&gt;
examples. Effects/crop.eff is a good example of a complex effect.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
To apply an effect to a model or part of a model use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/light-cone&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Cone&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/effect&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;inherits-from&amp;gt; &amp;lt;/inherits-from&amp;gt; contains the path to the effect you want to apply.&lt;br /&gt;
The effect does not need the file extension.&lt;br /&gt;
&lt;br /&gt;
=== Parameters in model file ===&lt;br /&gt;
&lt;br /&gt;
Parameters can be put into the model files effect application as well. But only bool, int, float, string can be used there.&lt;br /&gt;
&lt;br /&gt;
=== Chrome old usage ===&lt;br /&gt;
&lt;br /&gt;
Chrome, although now implemented as an effect, still retains the old method of application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;shader&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;shader&amp;gt;chrome&amp;lt;/shader&amp;gt;&lt;br /&gt;
  &amp;lt;texture&amp;gt;glass_shader.png&amp;lt;/texture&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;windscreen&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in order to maintain backward compatibility.&lt;br /&gt;
&lt;br /&gt;
== Reload effects at runtime ==&lt;br /&gt;
To reload an effect applied in a model xml file (e.g. some parameters and what it enherits from) just go into debug menu and select Reload Model.&lt;br /&gt;
&lt;br /&gt;
To reload the entire effect framework including eff files, go into menu and debug and configure development extensions and reload shaders. This is broken in 2020.1 though, but works in earlier FG versions.&lt;br /&gt;
&lt;br /&gt;
== The XML tags of an effect ==&lt;br /&gt;
&lt;br /&gt;
=== name ===&lt;br /&gt;
The name of the effect&lt;br /&gt;
&lt;br /&gt;
=== inherits-from ===&lt;br /&gt;
One feature not fully illustrated in the sample below is that&lt;br /&gt;
effects can inherit from each other. The parent effect is listed in&lt;br /&gt;
the &amp;quot;inherits-from&amp;quot; form. The child effect's property tree is&lt;br /&gt;
overlaid over that of the parent. Nodes that have the same name and&lt;br /&gt;
property index -- set by the &amp;quot;n=&amp;quot; attribute in the property tag --&lt;br /&gt;
are recursively merged. Leaf property nodes from the child have&lt;br /&gt;
precedence.  This means that effects that inherit from the example&lt;br /&gt;
effect below could be very short, listing just new&lt;br /&gt;
parameters and adding nothing to the techniques section;&lt;br /&gt;
alternatively, a technique could be altered or customized in a&lt;br /&gt;
child, listing (for example) a different shader program. An example&lt;br /&gt;
showing inheritance Effects/crop.eff, which inherits some if its&lt;br /&gt;
values from Effects/terrain-default.eff.&lt;br /&gt;
&lt;br /&gt;
FlightGear directly uses effects inheritance to assign effects to 3D&lt;br /&gt;
models and terrain. As described below, at runtime small effects are&lt;br /&gt;
created that contain material and texture values in a &amp;quot;parameters&amp;quot;&lt;br /&gt;
section. These effects inherit from another effect which references&lt;br /&gt;
those parameters in its &amp;quot;techniques&amp;quot; section. The derived effect&lt;br /&gt;
overrides any default values that might be in the base effect's&lt;br /&gt;
parameters section.&lt;br /&gt;
&lt;br /&gt;
=== parameters ===&lt;br /&gt;
Custom parameters that controls the effect.&lt;br /&gt;
&lt;br /&gt;
Note that parameters can use the &amp;lt;use&amp;gt; tags to enable properties to specify the values.&lt;br /&gt;
&lt;br /&gt;
=== generate ===&lt;br /&gt;
&lt;br /&gt;
Often shader effects need tangent vectors to work properly. These &lt;br /&gt;
tangent vectors, usually called tangent and binormal, are computed &lt;br /&gt;
on the CPU and given to the shader as vertex attributes. These &lt;br /&gt;
vectors are computed on demand on the geometry using the effect if &lt;br /&gt;
the 'generate' clause is present in the effect file.&lt;br /&gt;
&lt;br /&gt;
Example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;generate&amp;gt;&lt;br /&gt;
  &amp;lt;tangent type=&amp;quot;int&amp;quot;&amp;gt;6&amp;lt;/tangent&amp;gt;&lt;br /&gt;
  &amp;lt;binormal type=&amp;quot;int&amp;quot;&amp;gt;7&amp;lt;/binormal&amp;gt;&lt;br /&gt;
  &amp;lt;normal type=&amp;quot;int&amp;quot;&amp;gt;8&amp;lt;/normal&amp;gt;&lt;br /&gt;
&amp;lt;/generate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valid subnodes of 'generate' are 'tangent', 'binormal' or 'normal'.&lt;br /&gt;
The integer value of these subnode is the index of the attribute &lt;br /&gt;
that will hold the value of the vec3 vector.&lt;br /&gt;
&lt;br /&gt;
Normal is really redundant and should not be used, as that is already generated from loading the mesh.&lt;br /&gt;
&lt;br /&gt;
The generate clause is located under PropertyList in the xml file.&lt;br /&gt;
&lt;br /&gt;
In order to be available for the vertex shader, these data should &lt;br /&gt;
be bound to an attribute in the program clause, like this :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
  &amp;lt;vertex-shader&amp;gt;my_vertex_shader&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
  &amp;lt;attribute&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;my_tangent_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;index&amp;gt;6&amp;lt;/index&amp;gt;&lt;br /&gt;
  &amp;lt;/attribute&amp;gt;&lt;br /&gt;
  &amp;lt;attribute&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;my_binormal_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;index&amp;gt;7&amp;lt;/index&amp;gt;&lt;br /&gt;
  &amp;lt;/attribute&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
attribute names are whatever the shader use. The index is the one &lt;br /&gt;
declared in the 'generate' clause. So because generate/tangent has &lt;br /&gt;
value 6 and my_tangent_attribute has index 6, my_tangent_attribute &lt;br /&gt;
holds the tangent value for the vertex.&lt;br /&gt;
&lt;br /&gt;
=== technique ===&lt;br /&gt;
A certain way of rendering this effect. Different pipelines typically have their own techniques.&lt;br /&gt;
&lt;br /&gt;
==== scheme ====&lt;br /&gt;
Used by the [[Compositor]] to choose which implementation of an Effect to render. For example, if a Compositor scene pass specifies the &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; scheme, all techniques that use &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; will be used to render the pass. If an Effect doesn't contain a technique that implements this scheme, the object will be ignored and not rendered on that pass. Techniques with no scheme are considered ''default'' and will be used by scene passes when no explicit scheme has been provided.&lt;br /&gt;
&lt;br /&gt;
==== predicate ====&lt;br /&gt;
A technique can contain a predicate that describes the OpenGL&lt;br /&gt;
functionality required to support the technique. The first&lt;br /&gt;
technique with a valid predicate in the list of techniques is used&lt;br /&gt;
to set up the graphics state of the effect. A technique with no&lt;br /&gt;
predicate is always assumed to be valid. The predicate is written in a&lt;br /&gt;
little expression language that supports the following primitives:&lt;br /&gt;
&lt;br /&gt;
and, or, equal, less, less-equal&lt;br /&gt;
glversion - returns the version number of OpenGL&lt;br /&gt;
extension-supported - returns true if an OpenGL extension is supported&lt;br /&gt;
property - returns the boolean value of a property&lt;br /&gt;
float-property - returns the float value of a property, useful inside equal, less or less-equal nodes&lt;br /&gt;
shader-language - returns the version of GLSL supported, or 0 if there is none.&lt;br /&gt;
&lt;br /&gt;
The proper way to test whether to enable a shader-based technique is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
  &amp;lt;and&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;less-equal&amp;gt;&lt;br /&gt;
      &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;1.0&amp;lt;/value&amp;gt;&lt;br /&gt;
      &amp;lt;shader-language/&amp;gt;&lt;br /&gt;
    &amp;lt;/less-equal&amp;gt;&lt;br /&gt;
  &amp;lt;/and&amp;gt;&lt;br /&gt;
&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is also a property set by the user to indicate what is the level &lt;br /&gt;
of quality desired. This level of quality can be checked in the predicate&lt;br /&gt;
like this :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
  &amp;lt;and&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;less-equal&amp;gt;&lt;br /&gt;
      &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
      &amp;lt;float-property&amp;gt;/sim/rendering/quality-level&amp;lt;/float-property&amp;gt;&lt;br /&gt;
    &amp;lt;/less-equal&amp;gt;&lt;br /&gt;
    &amp;lt;!-- other predicate conditions --&amp;gt;&lt;br /&gt;
  &amp;lt;/and&amp;gt;&lt;br /&gt;
&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
The range of /sim/rendering/quality-level is [0..5]&lt;br /&gt;
 * 2.0 is the threshold for relief mapping effects,&lt;br /&gt;
 * 4.0 is the threshold for geometry shader usage.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
  &amp;lt;and&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shaders/quality-level&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shaders/model&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;or&amp;gt;&lt;br /&gt;
      &amp;lt;less-equal&amp;gt;&lt;br /&gt;
        &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
        &amp;lt;glversion/&amp;gt;&lt;br /&gt;
      &amp;lt;/less-equal&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_shader_objects&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_shading_language_100&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_vertex_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_fragment_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
    &amp;lt;/or&amp;gt;&lt;br /&gt;
  &amp;lt;/and&amp;gt;&lt;br /&gt;
&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pass ====&lt;br /&gt;
A technique can consist of several passes. A pass is basically an Open&lt;br /&gt;
Scene Graph StateSet. Ultimately all OpenGL and OSG modes and state&lt;br /&gt;
attributes  will be accessable in techniques. State attributes -- that&lt;br /&gt;
is, technique properties that have children and are not just boolean&lt;br /&gt;
modes -- have an &amp;lt;active&amp;gt; parameter which enables or disables the&lt;br /&gt;
attribute. In this way a technique can declare parameters it needs,&lt;br /&gt;
but not enable the attribute at all if it is not needed; the decision&lt;br /&gt;
can be based on a parameter in the parameters section of the&lt;br /&gt;
effect. For example, effects that support transparent and opaque&lt;br /&gt;
geometry could have as part of a technique:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;blend&amp;gt;&lt;br /&gt;
  &amp;lt;active&amp;gt;&amp;lt;use&amp;gt;blend/active&amp;lt;/use&amp;gt;&amp;lt;/active&amp;gt;&lt;br /&gt;
  &amp;lt;source&amp;gt;src-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;destination&amp;gt;one-minus-src-alpha&amp;lt;/destination&amp;gt;&lt;br /&gt;
&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So if the blend/active parameter is true blending will be activated&lt;br /&gt;
using the usual blending equation; otherwise blending is disabled.&lt;br /&gt;
&lt;br /&gt;
Values are assigned to technique properties in several ways:&lt;br /&gt;
&lt;br /&gt;
	* They can appear directly in the techniques section as a&lt;br /&gt;
		constant. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;ColorsTex&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;sampler-1d&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value type=&amp;quot;int&amp;quot;&amp;gt;2&amp;lt;/value&amp;gt;&lt;br /&gt;
&amp;lt;/uniform&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		* The name of a property in the parameters section can be&lt;br /&gt;
		referenced using a &amp;quot;use&amp;quot; clause. For example, in the technique&lt;br /&gt;
		section:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;material&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&amp;lt;use&amp;gt;material/ambient&amp;lt;/use&amp;gt;&amp;lt;/ambient&amp;gt;&lt;br /&gt;
&amp;lt;/material&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		Then, in the parameters section of the effect:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;parameters&amp;gt;&lt;br /&gt;
  &amp;lt;material&amp;gt;&lt;br /&gt;
    &amp;lt;ambient type=&amp;quot;vec4d&amp;quot;&amp;gt;0.2 0.2 0.2 1.0&amp;lt;/ambient&amp;gt;&lt;br /&gt;
  &amp;lt;/material&amp;gt;&lt;br /&gt;
&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		It's worth pointing out that the &amp;quot;material&amp;quot; property in a&lt;br /&gt;
		technique specifies part of OpenGL's state, whereas &amp;quot;material&amp;quot;&lt;br /&gt;
		in the parameters section is just a name, part of a&lt;br /&gt;
		hierarchical namespace.&lt;br /&gt;
&lt;br /&gt;
		* A property in the parameters section doesn't need to contain&lt;br /&gt;
		a constant value; it can also contain a &amp;quot;use&amp;quot; property. Here&lt;br /&gt;
		the value of the use clause is the name of a node in an&lt;br /&gt;
		external property tree which will be used as the source of a&lt;br /&gt;
		value. If the name begins with '/', the node is in&lt;br /&gt;
		FlightGear's global property tree; otherwise, it is in a local&lt;br /&gt;
		property tree, usually belonging to a model [NOT IMPLEMENTED&lt;br /&gt;
		YET]. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;parameters&amp;gt;&lt;br /&gt;
  &amp;lt;chrome-light&amp;gt;&amp;lt;use&amp;gt;/rendering/scene/chrome-light&amp;lt;/use&amp;gt;&amp;lt;/chrome-light&amp;gt;&lt;br /&gt;
&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		The type is determined by what is expected by the technique&lt;br /&gt;
		attribute that will ultimately receive the value. [There is&lt;br /&gt;
		no way to get vector values out of the main property system&lt;br /&gt;
		yet; this will be fixed shortly.] Values that are declared&lt;br /&gt;
		this way are dynamically updated if the property node&lt;br /&gt;
		changes.&lt;br /&gt;
&lt;br /&gt;
===== lighting =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== material =====&lt;br /&gt;
children: active, ambient, ambient-front, ambient-back, diffuse,&lt;br /&gt;
		 diffuse-front, diffuse-back, specular, specular-front,&lt;br /&gt;
		 specular-back, emissive, emissive-front, emissive-back, shininess,&lt;br /&gt;
		 shininess-front, shininess-back, color-mode&lt;br /&gt;
&lt;br /&gt;
===== blend =====&lt;br /&gt;
Children: active, source, destination, source-rgb, source-alpha, destination-rgb, destination-alpha&lt;br /&gt;
&lt;br /&gt;
Children values: dst-alpha, dst-color, one, one-minus-dst-alpha, one-minus-dst-color, one-minus-src-alpha, one-minus-src-color, src-alpha, src-alpha-saturate, src-color, constant-color, one-minus-constant-color, constant-alpha, one-minus-constant-alpha, zero&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;blend&amp;gt;&lt;br /&gt;
  &amp;lt;active&amp;gt;true&amp;lt;/active&amp;gt;&lt;br /&gt;
  &amp;lt;source&amp;gt;one-minus-dst-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;destination&amp;gt;src-alpha-saturate&amp;lt;/destination&amp;gt;&lt;br /&gt;
&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== blend (simple) =====&lt;br /&gt;
A blend tag with 0 will do nothing.&lt;br /&gt;
A blend tag with 1 will do the same as source-alpha: one-minus-dst-alpha, in other words it will enable z transparency using alpha from the fragment shader.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;blend&amp;gt;1&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== shade-model =====&lt;br /&gt;
flat or smooth&lt;br /&gt;
&lt;br /&gt;
===== cull-face =====&lt;br /&gt;
front, back, front-back, off&lt;br /&gt;
&lt;br /&gt;
===== texture-unit =====&lt;br /&gt;
unit: integer denoting which unit it is&lt;br /&gt;
&lt;br /&gt;
image: the texture path&lt;br /&gt;
&lt;br /&gt;
images: multiple texture paths&lt;br /&gt;
&lt;br /&gt;
type: 2d, noise, cubemap, 3d (3d was added in 2020.1 and is used for layers of 2d textures defining a volumetric 3d texture)&lt;br /&gt;
&lt;br /&gt;
filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
mag-filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
wrap: repeat, clamp-to-edge, clamp-to-border, clamp, mirror&lt;br /&gt;
&lt;br /&gt;
internal-format: normalized&lt;br /&gt;
&lt;br /&gt;
environment: mode, color&lt;br /&gt;
:mode: add,blend,decal,modulate,replace&lt;br /&gt;
:color: rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: replace, modulate, add, add-signed, interpolate, subtract, dot3-rgb, dot3-rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: combine-rgb, combine-alpha, source0-rgb, source1-rgb, source2-rgb, source0-alpha, source1-alpha,source2-alpha,operand0-rgb,operand1-rgb,operand2-rgb,operand0-alpha,operand1-alpha,operand2-alpha,scale-rgb,scale-alpha&lt;br /&gt;
&lt;br /&gt;
point-sprite: true, false&lt;br /&gt;
&lt;br /&gt;
mipmap-control functions: auto, average, sum, product, min, max&lt;br /&gt;
&lt;br /&gt;
texgen:&lt;br /&gt;
:mode: object-linear, eye-linear, sphere-map, normal-map, reflection-map&lt;br /&gt;
:planes: s, t, r, q as doubles&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;texture-unit&amp;gt;&lt;br /&gt;
  &amp;lt;unit&amp;gt;3&amp;lt;/unit&amp;gt;&lt;br /&gt;
  &amp;lt;image&amp;gt;Textures/Terrain/void.png&amp;lt;/image&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;2d&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;filter&amp;gt;linear-mipmap-linear&amp;lt;/filter&amp;gt;&lt;br /&gt;
  &amp;lt;mag-filter&amp;gt;linear-mipmap-linear&amp;lt;/mag-filter&amp;gt;&lt;br /&gt;
  &amp;lt;wrap-s&amp;gt;repeat&amp;lt;/wrap-s&amp;gt;&lt;br /&gt;
  &amp;lt;wrap-t&amp;gt;repeat&amp;lt;/wrap-t&amp;gt;&lt;br /&gt;
  &amp;lt;wrap-r&amp;gt;repeat&amp;lt;/wrap-r&amp;gt;&lt;br /&gt;
  &amp;lt;internal-format&amp;gt;normalized&amp;lt;/internal-format&amp;gt;&lt;br /&gt;
  &amp;lt;mipmap-control&amp;gt;&lt;br /&gt;
    &amp;lt;function-r&amp;gt;average&amp;lt;/function-r&amp;gt;&lt;br /&gt;
    &amp;lt;function-g&amp;gt;min&amp;lt;/function-g&amp;gt;&lt;br /&gt;
    &amp;lt;function-b&amp;gt;sum&amp;lt;/function-b&amp;gt;&lt;br /&gt;
    &amp;lt;function-a&amp;gt;product&amp;lt;/function-a&amp;gt;&lt;br /&gt;
  &amp;lt;/mipmap-control&amp;gt;&lt;br /&gt;
  &amp;lt;environment&amp;gt;&lt;br /&gt;
    &amp;lt;mode&amp;gt;decal&amp;lt;/mode&amp;gt;&lt;br /&gt;
    &amp;lt;color&amp;gt;0.0 0.1 0.6 1.0&amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;/environment&amp;gt;&lt;br /&gt;
  &amp;lt;point-sprite&amp;gt;true&amp;lt;/point-sprite&amp;gt;&lt;br /&gt;
  &amp;lt;texenv-combine&amp;gt;operand0-rgb&amp;lt;/texenv-combine&amp;gt;&lt;br /&gt;
  &amp;lt;texgen&amp;gt;&lt;br /&gt;
    &amp;lt;mode&amp;gt;S&amp;lt;/mode&amp;gt;&lt;br /&gt;
    &amp;lt;planes&amp;gt;0.075, 0.0, 0.0, 0.5&amp;lt;/planes&amp;gt;&lt;br /&gt;
  &amp;lt;/texgen&amp;gt;&lt;br /&gt;
&amp;lt;/texture-unit&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Textures of type 3d has to be packed on the x axis. Here is an example: [https://raw.githubusercontent.com/sebh/TileableVolumeNoise/master/Examples/noiseErosionPacked.jpg noiseErosionPacked.jpg]&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-two-side =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== polygon-mode =====&lt;br /&gt;
children: front, back&lt;br /&gt;
&lt;br /&gt;
Valid values:  fill, line, point&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-point-size =====&lt;br /&gt;
true, false&lt;br /&gt;
&lt;br /&gt;
===== uniform =====&lt;br /&gt;
Data accessible by shaders.&lt;br /&gt;
&lt;br /&gt;
name: the name&lt;br /&gt;
&lt;br /&gt;
type: bool, int, float, float-vec3, float-vec4, sampler-1d, sampler-2d, sampler-3d, sampler-1d-shadow, sampler-2d-shadow, sampler-cube&lt;br /&gt;
&lt;br /&gt;
===== alpha-test =====&lt;br /&gt;
&lt;br /&gt;
active: true, false&lt;br /&gt;
&lt;br /&gt;
comparison: never, less, equal, lequal, greater, notequal, gequal, always&lt;br /&gt;
&lt;br /&gt;
reference: 0 to 1&lt;br /&gt;
&lt;br /&gt;
===== render-bin =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
bin-number: This is an integer defining the order stuff will be rendered in, it can be negative also.&lt;br /&gt;
&lt;br /&gt;
bin-name: RenderBin, DepthSortedBin&lt;br /&gt;
&lt;br /&gt;
===== rendering-hint =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
default, opaque, transparent&lt;br /&gt;
&lt;br /&gt;
This basically just sets Renderbin:&lt;br /&gt;
&lt;br /&gt;
opaque = bin 10, depthsortedbin&lt;br /&gt;
&lt;br /&gt;
transparent = bin 0, renderbin&lt;br /&gt;
&lt;br /&gt;
default = inherit renderbin details from parent node&lt;br /&gt;
&lt;br /&gt;
===== depth =====&lt;br /&gt;
&lt;br /&gt;
* function: Specifies the depth comparison function. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthFunc.xhtml &amp;lt;tt&amp;gt;glDepthFunc&amp;lt;/tt&amp;gt;].&lt;br /&gt;
* near, far: Specify the mapping of depth values from normalized device coordinates to window coordinates. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml &amp;lt;tt&amp;gt;glDepthRange&amp;lt;/tt&amp;gt;]&lt;br /&gt;
* write-mask: Whether to write to the depth buffer or not.&lt;br /&gt;
* enabled: Whether depth testing is enabled or not.&lt;br /&gt;
&lt;br /&gt;
===== define =====&lt;br /&gt;
&lt;br /&gt;
Injects a &amp;lt;tt&amp;gt;#define&amp;lt;/tt&amp;gt; preprocessor directive into the shaders used in this pass. It is then possible to create logic around this define using conventional preprocessor directives like &amp;lt;tt&amp;gt;#ifdef&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;#endif&amp;lt;/tt&amp;gt;, etc. Keep in mind that shaders must import the define before being able to use it. For example, for a define named &amp;lt;tt&amp;gt;USE_TEXTUREMAPPING&amp;lt;/tt&amp;gt;, the following GLSL code must be placed right after the &amp;lt;tt&amp;gt;#version&amp;lt;/tt&amp;gt; directive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
#pragma import_defines(USE_TEXTUREMAPPING)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* name: Name of the define.&lt;br /&gt;
* value: Value of the define (optional).&lt;br /&gt;
&lt;br /&gt;
===== program =====&lt;br /&gt;
* vertex-shader&lt;br /&gt;
* geometry-shader&lt;br /&gt;
* fragment-shader&lt;br /&gt;
* attribute&lt;br /&gt;
* geometry-vertices-out: integer, max number of vertices emitted by geometry shader&lt;br /&gt;
* geometry-input-type: points, lines, lines-adjacency, triangles, triangles-adjacency&lt;br /&gt;
* geometry-output-type: points, line-strip, triangle-strip&lt;br /&gt;
* uniform-block-binding: has name and index (since 2020.1)&lt;br /&gt;
&lt;br /&gt;
example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
  &amp;lt;vertex-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
  &amp;lt;fragment-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
  &amp;lt;fragment-shader n=&amp;quot;1&amp;quot;&amp;gt;Shaders/noise.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
  &amp;lt;fragment-shader n=&amp;quot;2&amp;quot;&amp;gt;Shaders/filters-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See this page for more about shaders: [[Howto:Shader programming in FlightGear]]&lt;br /&gt;
&lt;br /&gt;
== Uniforms passed to shaders outside the XML effect framework ==&lt;br /&gt;
&lt;br /&gt;
Some uniforms are passed from C++ directly by the [[Compositor]], [[WS 3.0]], and others. See [[Compositor#Built-in uniforms|Compositor built-in uniforms]].&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=37364|title=Application of effects}} - Testing which kind of groups an effect can be applied to and when&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Compositor&amp;diff=139084</id>
		<title>Compositor</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Compositor&amp;diff=139084"/>
		<updated>2024-02-07T13:40:33Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = Compositor logo.png&lt;br /&gt;
|name        = Compositor Framework&lt;br /&gt;
|started     = 01/2018 (Available since FlightGear 2020.4)&lt;br /&gt;
|description = Dynamic rendering pipeline configured via the [[Property tree]] and [[PropertyList XML File|XML]]&lt;br /&gt;
|status      = Stable (merged and actively maintained)&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{simgear file|simgear/scene/viewer}}&lt;br /&gt;
* {{flightgear file|src/Viewer}}&lt;br /&gt;
* {{fgdata file|Compositor}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''Compositor''' aims to bring multi-pass rendering to FlightGear. It encapsulates a rendering pipeline and exposes its parameters to a [[Property Tree]] interface. At startup, FlightGear reads the pipeline definition file for each physical viewport defined on the [[Howto:Configure camera view windows|CameraGroup settings]]. If no Compositor file is specified for a physical camera, the one given by the &amp;lt;code&amp;gt;--compositor=&amp;lt;/code&amp;gt; startup command will be used. If such startup option is not used either, FlightGear will look for a valid Compositor file in &amp;lt;tt&amp;gt;$FG_ROOT/Compositor/default.xml&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The Compositor introduces a new dedicated fgdata directory for new/custom rendering pipelines: {{Fgdata file|Compositor}}.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
First discussed in 03/2012 during the early [[Rembrandt]] days, Zan (Lauri Peltonen) came up with a set of patches demonstrating how to create an XML-configurable rendering pipeline. Back then, this work was considered to look pretty promising &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28946515/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Mathias Fröhlich &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; and at the time plans were discussed to unify this with the ongoing Rembrandt implementation (no longer maintained).&lt;br /&gt;
&lt;br /&gt;
Adopting Zan's approach would have meant that efforts like [[Rembrandt]] (deferred rendering) could have been implemented without requiring C++ space modifications, i.e. purely in [[Base package]] space. Rembrandt's developer (FredB) suggested to extend the format to avoid duplicating the stages when you have more than one viewport, i.e.  specifying a pipeline as a template, with conditions like in effects, and have the current camera layout refer the pipeline that would be duplicated, resized and positioned for each declared viewport &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944773/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Frederic Bouvier &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zan's original patches can still be found in his newcameras branches which allow the user to define the rendering pipeline in preferences.xml: {{gitorious source|proj=fg|repo=zans-flightgear|branch=newcameras|text=FlightGear}}, {{gitorious source|proj=fg|repo=zans-simgear|branch=newcameras|text=SimGear}}. At that point, it didn't have everything Rembrandt's pipeline needs, but most likely could be easily enhanced to support those things. Basically, the original version added support for multiple camera passes, texture targets, texture formats, passing textures from one pass to another etc, while preserving the standard rendering line if user wants that. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944733/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Lauri Peltonen &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the early days of Zan's groundwork, providing the (hooks) infrastructure to enable base package developers to prototype, test and develop distinct rendering pipelines without requiring C++ space modifications has been a long-standing idea, especially after the [[Canvas]] system became available in early 2012, which demonstrated how RTT-rendering buffers (FBOs) could be set up, created and manipulated procedurally (i.e. at run-time) using XML, the property tree and [[Nasal]] scripting. &amp;lt;ref&amp;gt;{{forum link|type=search|title=Zan's Rembrandt and Canvas work|keywords=zan+rembrandt+canvas}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new '''Compositor''' is an improved re-implementation of Zan's original work using not just XML, but also [[Property Tree|properties]] and a handful of [[Canvas]] concepts.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
* Completely independent of other parts of the simulator, i.e. it's part of [[SimGear]] and can be used in a standalone fashion if needed, ala Canvas.&lt;br /&gt;
* Although independent, its aim is to be fully compatible with the current rendering framework in FG. This includes the [[Effects]] system, [[Howto:Configure camera view windows|CameraGroup]], [[Rembrandt]], [[ALS]] and [[Canvas]].&lt;br /&gt;
* Its functionality overlaps Rembrandt: what can be done with Rembrandt can be done with the Compositor, but not vice versa.&lt;br /&gt;
* Fully configurable via an XML interface without compromising performance (ala Effects, using [[PropertyList XML File|PropertyList files]]).&lt;br /&gt;
* Flexible, expandable and compatible with modern graphics.&lt;br /&gt;
* It doesn't increase the hardware requirements, it expands the hardware range FG can run on. People with integrated GPUs (Intel HD etc) can run a Compositor with a single pass that renders directly to the screen like before, while people with more powerful cards can run a Compositor that implements deferred rendering, for example.&lt;br /&gt;
* Static branching support. Every pipeline element can be enabled/disabled at startup via a [[Conditions|&amp;lt;condition&amp;gt; block]].&lt;br /&gt;
* The entire rendering pipeline can be reloaded via an fgcommand (&amp;lt;tt&amp;gt;reload-compositor&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== How to enable the Compositor ==&lt;br /&gt;
&lt;br /&gt;
The Compositor is now the default renderer framework in FlightGear since 2020/11/17. It will be included as part of version 2020.4 onwards.&lt;br /&gt;
&lt;br /&gt;
If you compile FlightGear from source, you can already try the Compositor. Make sure you are pulling the latest version of the 'next' branch. You can also try out the latest nightly build from the [[FlightGear build server]].&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
The Compositor introduces a new way of defining lights that is renderer agnostic, so every rendering pipeline will be able to access the lights that have been implemented like this. The resulting light volumes can be visualized for debugging purposes by setting the property &amp;lt;tt&amp;gt;/sim/debug/show-light-volumes&amp;lt;/tt&amp;gt; to true.&lt;br /&gt;
&lt;br /&gt;
You can edit existing lights with the '''[[Illuminator addon|Illuminator]]''', but you have to define them first e.g. in your aircraft. The Illuminator add-on is meant for fine-tuning the light parameters.&lt;br /&gt;
&lt;br /&gt;
[[Project Rembrandt]] light definitions are also read by the Compositor for backwards compatibility reasons. However, it is not recommended to use the old syntax for new/updated projects.&lt;br /&gt;
&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top style=&amp;quot;width: 20%;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.03&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.03&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.03&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/ambient&amp;gt;&lt;br /&gt;
  &amp;lt;diffuse&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.95&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.9&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.9&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/diffuse&amp;gt;&lt;br /&gt;
  &amp;lt;specular&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.95&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.9&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.9&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/specular&amp;gt;&lt;br /&gt;
  &amp;lt;attenuation&amp;gt;&lt;br /&gt;
    &amp;lt;c&amp;gt;1.0&amp;lt;/c&amp;gt;&lt;br /&gt;
    &amp;lt;l&amp;gt;0.09&amp;lt;/l&amp;gt;&lt;br /&gt;
    &amp;lt;q&amp;gt;0.032&amp;lt;/q&amp;gt;&lt;br /&gt;
  &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
  &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;controls/lighting/instruments-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/dim-factor&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top style=&amp;quot;width: 80%;&amp;quot;|&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''name'''&amp;lt;/tt&amp;gt;. An {{tag|animation}} will be able to reference the light by this name. Most [[Howto:Animate_models|animations]] will work as expected (rotate, translate, spin etc). Material animations are not supported.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''type'''&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;point&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''position'''&amp;lt;/tt&amp;gt;. The position of the light source in model space and in meters.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''direction'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. It indicates the direction of the spotlight. This parameter can be specified in three different ways:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 1px solid darkgray;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Direction vector&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Look-at point&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Rotation angles&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | A vector in model space that specifies the direction. Doesn't have to be normalized.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
&amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
&amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | The spotlight will calculate its direction by looking at this position from the light position. The point is in model space and in meters.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;lookat-x-m&amp;gt;-8.031&amp;lt;/lookat-x-m&amp;gt;&lt;br /&gt;
&amp;lt;lookat-y-m&amp;gt;0&amp;lt;/lookat-y-m&amp;gt;&lt;br /&gt;
&amp;lt;lookat-z-m&amp;gt;-2&amp;lt;/lookat-z-m&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | A three angle rotation in degrees that rotates the spotlight around the three axes. A 0 degree angle in all axes makes the spotlight point downwards (negative Z).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pitch-deg&amp;gt;90&amp;lt;/pitch-deg&amp;gt;&lt;br /&gt;
&amp;lt;roll-deg&amp;gt;0&amp;lt;/roll-deg&amp;gt;&lt;br /&gt;
&amp;lt;heading-deg&amp;gt;0&amp;lt;/heading-deg&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''ambient'''&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'''diffuse'''&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;'''specular'''&amp;lt;/tt&amp;gt;. Four-component vectors that specify the light color.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''attenuation'''&amp;lt;/tt&amp;gt;. Three-component vector where &amp;lt;code&amp;gt;&amp;lt;c&amp;gt;&amp;lt;/code&amp;gt; specifies the constant factor, &amp;lt;code&amp;gt;&amp;lt;l&amp;gt;&amp;lt;/code&amp;gt; specifies the linear factor and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;q&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; specifies the quadratic factor. These factors are plugged into the OpenGL light attenuation formula [[File:Spotlight_attenuation.png]] where d is the distance of the fragment to the light source. See this [http://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation table] for a list of attenuation values based on the range of the light.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''range-m'''&amp;lt;/tt&amp;gt;. Maximum range from the light source position in meters. This value will be used by the renderers to determine if a fragment is illuminated by this source. Every fragment outside this range isn't guaranteed to be affected by the light, even if the attenuation factor isn't 0 in that particular fragment.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''spot-cutoff'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. It specifies the maximum spread angle of a light source. Only values in the range 0 90 are accepted. If the angle between the direction of the light and the direction from the light to the fragment being lighted is greater than the spot cutoff angle, it won't be lit.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''spot-exponent'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. Higher spot exponents result in a more focused light source, regardless of the spot cutoff angle.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''dim-factor'''&amp;lt;/tt&amp;gt; ('''Optional'''). Controls the dimming of the light source through an [[Expressions|expression]].&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''debug-color'''&amp;lt;/tt&amp;gt; ('''Optional'''). Sets the color of the debug light volume. By default it's red.&lt;br /&gt;
'''&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;Important: &amp;lt;/span&amp;gt;'''The following parameters are '''only''' available in the [[HDR Pipeline]].&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''color'''&amp;lt;/tt&amp;gt;. The color or hue of emitted light. It is expected to be in the sRGB color space.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''intensity'''&amp;lt;/tt&amp;gt;. The brightness of the light. This value can be (and will almost always be) higher than 1.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Shadows ===&lt;br /&gt;
&lt;br /&gt;
The shadow mapping algorithm can be customized entirely by the rendering pipeline. This means that each pipeline will have its own requirements when it comes to shadows. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Use the [[Howto:Animate models#Noshadow|&amp;lt;tt&amp;gt;noshadow&amp;lt;/tt&amp;gt; animation]] to disable shadows on objects that don't need them. An example would be billboarded lights (light sprites) or really small cockpit elements that don't need shadows and would cause degraded performance.&lt;br /&gt;
If the casted aircraft shadow appears blocky then there probably are some objects which need the noshadow animation applied. Most notably are billboarded lights which include [[ALS_technical_notes#ALS procedural lights|ALS procedural lights]].&lt;br /&gt;
* Try to mark as many cockpit objects as possible as &amp;lt;tt&amp;gt;interior&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;model&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;interior&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;usage&amp;gt;interior&amp;lt;/usage&amp;gt;&lt;br /&gt;
  &amp;lt;path&amp;gt;Aircraft/JA37/Models/ja37-interior.xml&amp;lt;/path&amp;gt; &amp;lt;!-- All the objects that should only be seen when inside the cockpit are in this file --&amp;gt;&lt;br /&gt;
&amp;lt;/model&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Unlike in Rembrandt, polygons facing the Sun are the ones used to generate the shadow map, so single sided surfaces and non-closed objects should be rendered correctly.&lt;br /&gt;
&lt;br /&gt;
== Effects and Shaders ==&lt;br /&gt;
&lt;br /&gt;
=== Schemes ===&lt;br /&gt;
&lt;br /&gt;
Effects can have different implementations depending on the Compositor pipeline being used. For example, a grass Effect implemented for a high quality pipeline might have much more detail than one that targets low specification machines. Still, they both implement the &amp;quot;look&amp;quot; of grass, so they share the same Effect file (grass.eff).&lt;br /&gt;
&lt;br /&gt;
The Compositor chooses which implementation of an Effect to render based on the &amp;lt;tt&amp;gt;&amp;lt;scheme&amp;gt;&amp;lt;/tt&amp;gt; of the techniques.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;technique n=&amp;quot;15&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;scheme&amp;gt;test-scheme&amp;lt;/scheme&amp;gt;&lt;br /&gt;
  [...]&lt;br /&gt;
&amp;lt;/technique&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the technique will be chosen if the Compositor pipeline &amp;lt;tt&amp;gt;&amp;lt;scene&amp;gt;&amp;lt;/tt&amp;gt; pass uses the &amp;lt;tt&amp;gt;test-scheme&amp;lt;/tt&amp;gt; Effect scheme. Consequently, porting an Effect to a Compositor pipeline will require knowing which Effect schemes it uses and writing a technique for each one. The only exception to this is the Classic/default pipeline, which uses techniques with no scheme.&lt;br /&gt;
&lt;br /&gt;
=== Built-in uniforms ===&lt;br /&gt;
&lt;br /&gt;
The Compositor provides a set of built-in uniforms that are passed along to every shader. These uniforms must '''not''' be defined in the Effect file, as they are defined and updated in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Type&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_TextureMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Texture matrix that replaces the old fixed-function behaviour. If no texture animations are present it corresponds to the identity matrix.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Viewport&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Viewport geometry for the current pass (x, y, width, height).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PixelSize&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the width and height of the viewport.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|View matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the view matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame view matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame inverse of the view matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevProjectionMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PrevProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Previous frame inverse of the projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionCart&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in cartesian coordinates.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionGeod&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraDistanceToEarthCenter&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance from the camera to the center of the Earth in meters.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraWorldUp&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Camera up vector in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraViewUp&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Camera up vector in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_EarthRadius&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Earth radius right below the camera position in meters.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_NearFar&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Near and far clipping planes in meters. x component is the near plane, y component is the far plane.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Fcoef&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used by logarithmic depth.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FOVScale&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used by logarithmic depth.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Sun (directional light) direction in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirectionWorld&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Sun (directional light) direction in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunZenithCosTheta&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dot product between the Sun direction and the up vector at the camera position.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Moon (directional light) direction in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonDirectionWorld&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Moon (directional light) direction in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonZenithCosTheta&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dot product between the Moon direction and the up vector at the camera position.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Creating a custom rendering pipeline ==&lt;br /&gt;
&lt;br /&gt;
Since the Compositor is completely data-driven, new rendering pipelines can be created by writing a custom XML pipeline definition. This section tries to document most of the available parameters, but the best and most up-to-date resource is the Compositor parsing code in SimGear ({{simgear file|simgear/scene/viewer}}). See existing pipelines in {{fgdata file|Compositor}} for practical examples on how to use these parameters.&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that every pipeline element can be enabled/disabled through a [[Conditions|&amp;lt;condition&amp;gt; block]]. This allows for dynamic rendering pipelines that have toggleable features. However, the pipeline can't be updated in real-time: the simulator has to be restarted or the Compositor has to be reloaded through the &amp;lt;tt&amp;gt;reload-compositor&amp;lt;/tt&amp;gt; [[Fgcommands|fgcommand]].&lt;br /&gt;
&lt;br /&gt;
=== Buffers ===&lt;br /&gt;
&lt;br /&gt;
A buffer represents a texture or, more generically, a region of GPU memory.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| string&lt;br /&gt;
|&lt;br /&gt;
| Passes will be able to address the buffer by this name&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;1d, 2d, 2d-array, 2d-multisample, 3d, rect, cubemap&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
| Any texture type allowed by OpenGL&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;width&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer or &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; to use the physical viewport width. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture width&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;screen-width-scale&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| If &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; was used, this controls the width scaling factor&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;height&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer or &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; to use the physical viewport height. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture height&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;screen-height-scale&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| If &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; was used, this controls the height scaling factor&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;depth&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture depth&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| See {{simgear file|simgear/scene/viewer/CompositorBuffer.cxx}} for the latest available values&lt;br /&gt;
| &amp;lt;tt&amp;gt;rgba8&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Specifies the texture format. It corresponds to the ''internalformat'', ''format'' and ''type'' arguments of the OpenGL function ''glTexImage2D''&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;min-filter, mag-filter&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;linear, linear-mipmap-linear, linear-mipmap-nearest, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;linear&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Change the minification and magnification filtering respectively&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;wrap-s, wrap-t, wrap-r&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;clamp, clamp-to-edge, clamp-to-border, repeat, mirror&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;clamp-to-border&amp;lt;/tt&amp;gt;&lt;br /&gt;
| They change the wrap mode for each coordinate&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;anisotropy&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;border-color&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| vec4&lt;br /&gt;
| &amp;lt;tt&amp;gt;(0.0f, 0.0f, 0.0f, 0.0f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-comparison&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-texture-mode&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;luminance, intensity, alpha&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;luminance&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-compare-func&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;never, less, equal, lequal, greater, notequal, gequal, always&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;lequal&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Passes ===&lt;br /&gt;
&lt;br /&gt;
A pass wraps around an [http://public.vrac.iastate.edu/vancegroup/docs/OpenSceneGraphReferenceDocs-3.0/a00089.html osg::Camera]. Passes all have some common parameters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;clear-color, clear-accum, clear-depth and clear-stencil&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| vec4&lt;br /&gt;
| black, black, &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; respectively&lt;br /&gt;
| Pass clear colors&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;clear-mask&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;color, stencil, depth, accum&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;color depth&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Pass clear mask&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;effect-scheme&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid effect scheme name&lt;br /&gt;
| None&lt;br /&gt;
| The pass will try to use the specified effect scheme to draw every object.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Passes can render to a buffer (Render to Texture), to several buffers (Multiple Render Targets) or directly to the framebuffer. This is accomplished by the &amp;lt;code&amp;gt;&amp;lt;attachment&amp;gt;&amp;lt;/code&amp;gt; tag. Possible parameters of an attachment are:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Valid buffer name&lt;br /&gt;
| &lt;br /&gt;
| The name of the buffer to output to&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;component&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;color, color0&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;color15, depth, stencil, depth-stencil&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
| FBO attachment point&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;level&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Mipmap level of the texture that is attached&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;face&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Face of cube map texture or z-level of 3d texture&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;mipmap-generation&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Whether mipmap generation should be done for texture&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;multisample-samples&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Multisample anti-aliasing (MSAA) samples&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;multisample-color-samples&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Multisample anti-aliasing (MSAA) color samples&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Passes can also receive buffers as input and use them in their shaders. This is accomplished by the &amp;lt;code&amp;gt;&amp;lt;binding&amp;gt;&amp;lt;/code&amp;gt; tag, which has the following parameters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Valid buffer name&lt;br /&gt;
| &lt;br /&gt;
| The name of the buffer to bind&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;unit&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| int&lt;br /&gt;
| &lt;br /&gt;
| The texture unit to place the texture on. Effects will be able to access the buffer on this texture unit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are specific pass types, each with their own set of custom parameters.&lt;br /&gt;
&lt;br /&gt;
==== scene ====&lt;br /&gt;
Renders the scene from the point of view given by the CameraGroup.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;cull-mask&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| A 32 bit number. See {{simgear file|simgear/scene/util/RenderConstants.hxx}} to know which bits enable what&lt;br /&gt;
| &amp;lt;tt&amp;gt;0xffffffff&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Specifies the cull mask to be used in the underlying &amp;lt;tt&amp;gt;osg::Camera&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;z-near, z-far&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| 0.0 uses the value given by the CameraGroup&lt;br /&gt;
| Sets a custom near and far values. Useful for implementing depth partition and limiting the depth range on cubemap passes&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;cubemap-face&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; (don't use cubemap)&lt;br /&gt;
| Ignores the given view and projection matrices and uses a custom one that renders the scene as if it was seen from inside a cubemap looking towards the specified face&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;use-shadow-pass&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| string&lt;br /&gt;
| Empty&lt;br /&gt;
| Name of a shadow mapping pass. Exposes shadow mapping related uniforms to the shaders of the current pass&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scene passes can also use the tag &amp;lt;code&amp;gt;&amp;lt;clustered-shading&amp;gt;&amp;lt;/code&amp;gt; to enable clustered shading (lights). The following parameters are available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-pointlights&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1024&lt;br /&gt;
| Maximum amount of point light sources allowed on the entire scene&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-spotlights&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1024&lt;br /&gt;
| Maximum amount of spot light sources allowed on the entire scene&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-light-indices&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 256&lt;br /&gt;
| Size of the light indices texture. Keep in mind that it is a 2D texture, so the total size will be e.g. 256x256&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;tile-size&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 128&lt;br /&gt;
| Size of each clustered shading tile&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;num-threads&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1&lt;br /&gt;
| Number of threads to use during the light culling process. Keep in mind that a high thread count when there aren't many lights will worsen performance due to the thread creation overhead&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;depth-slices&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1&lt;br /&gt;
| Number of slices to partition the view frustum in the Z axis. Higher numbers will cull lights more aggressively, increasing performance if there are many lights further out that don't contribute much to the overall scene's lighting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== quad ====&lt;br /&gt;
Renders a fullscreen quad with an optional [[Effects|effect]] applied. Useful for screen space shaders (like SSAO, Screen Space Reflections or bloom) and deferred rendering.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;geometry&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float values for &amp;lt;code&amp;gt;&amp;lt;x&amp;gt;, &amp;lt;y&amp;gt;, &amp;lt;width&amp;gt;, &amp;lt;height&amp;gt;, &amp;lt;scale&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;0.0, 0.0, 1.0, 1.0, 1.0&amp;lt;/tt&amp;gt; respectively&lt;br /&gt;
| Size of the fullscreen quad inside the viewport using normalized coordinates.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;effect&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid Effect file&lt;br /&gt;
| None&lt;br /&gt;
| This Effect will be applied to the quad geometry&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== csm ====&lt;br /&gt;
Implements Cascaded Shadow Mapping by rendering the scene from a light's point of view (the Sun by default). For now it only supports directional light sources. There has to be one &amp;lt;tt&amp;gt;csm&amp;lt;/tt&amp;gt; pass for each cascade.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;light-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid light name that exists in the scene graph&lt;br /&gt;
| &amp;lt;tt&amp;gt;FGLightSource&amp;lt;/tt&amp;gt; (Sun)&lt;br /&gt;
| The name of the &amp;lt;tt&amp;gt;osg::LightSource&amp;lt;/tt&amp;gt; to use for this shadow map&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;render-at-night&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| true&lt;br /&gt;
| Whether to render the shadows at night or not&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;near-m, far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| float (meters)&lt;br /&gt;
|&lt;br /&gt;
| They specify the range of the shadow map&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Wiki articles ===&lt;br /&gt;
* [[HDR Pipeline]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
* [[Canvas View Camera Element]]&lt;br /&gt;
* [[CompositeViewer Support]]&lt;br /&gt;
* [[Uniform Buffer Objects]]&lt;br /&gt;
* [[FlightGear CIGI Support (Common Image Generator Interface)]]&lt;br /&gt;
&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=36269|text=The Compositor}}&lt;br /&gt;
* {{forum link|t=35095|text=Clustered Forward Rendering}} (12/2018)&lt;br /&gt;
* {{forum link|t=33045|text=Getting started with RTT}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Compositor&amp;diff=139083</id>
		<title>Compositor</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Compositor&amp;diff=139083"/>
		<updated>2024-02-07T13:38:36Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = Compositor logo.png&lt;br /&gt;
|name        = Compositor Framework&lt;br /&gt;
|started     = 01/2018 (Available since FlightGear 2020.4)&lt;br /&gt;
|description = Dynamic rendering pipeline configured via the [[Property tree]] and [[PropertyList XML File|XML]]&lt;br /&gt;
|status      = Stable (merged and actively maintained)&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{simgear file|simgear/scene/viewer}}&lt;br /&gt;
* {{flightgear file|src/Viewer}}&lt;br /&gt;
* {{fgdata file|Compositor}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''Compositor''' aims to bring multi-pass rendering to FlightGear. It encapsulates a rendering pipeline and exposes its parameters to a [[Property Tree]] interface. At startup, FlightGear reads the pipeline definition file for each physical viewport defined on the [[Howto:Configure camera view windows|CameraGroup settings]]. If no Compositor file is specified for a physical camera, the one given by the &amp;lt;code&amp;gt;--compositor=&amp;lt;/code&amp;gt; startup command will be used. If such startup option is not used either, FlightGear will look for a valid Compositor file in &amp;lt;tt&amp;gt;$FG_ROOT/Compositor/default.xml&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The Compositor introduces a new dedicated fgdata directory for new/custom rendering pipelines: {{Fgdata file|Compositor}}.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
First discussed in 03/2012 during the early [[Rembrandt]] days, Zan (Lauri Peltonen) came up with a set of patches demonstrating how to create an XML-configurable rendering pipeline. Back then, this work was considered to look pretty promising &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28946515/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Mathias Fröhlich &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt; and at the time plans were discussed to unify this with the ongoing Rembrandt implementation (no longer maintained).&lt;br /&gt;
&lt;br /&gt;
Adopting Zan's approach would have meant that efforts like [[Rembrandt]] (deferred rendering) could have been implemented without requiring C++ space modifications, i.e. purely in [[Base package]] space. Rembrandt's developer (FredB) suggested to extend the format to avoid duplicating the stages when you have more than one viewport, i.e.  specifying a pipeline as a template, with conditions like in effects, and have the current camera layout refer the pipeline that would be duplicated, resized and positioned for each declared viewport &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944773/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Frederic Bouvier &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zan's original patches can still be found in his newcameras branches which allow the user to define the rendering pipeline in preferences.xml: {{gitorious source|proj=fg|repo=zans-flightgear|branch=newcameras|text=FlightGear}}, {{gitorious source|proj=fg|repo=zans-simgear|branch=newcameras|text=SimGear}}. At that point, it didn't have everything Rembrandt's pipeline needs, but most likely could be easily enhanced to support those things. Basically, the original version added support for multiple camera passes, texture targets, texture formats, passing textures from one pass to another etc, while preserving the standard rendering line if user wants that. &amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944733/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; [Flightgear-devel] [Rembrandt] the plan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Lauri Peltonen &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Mar 7th, 2012 &lt;br /&gt;
  |added  =  Mar 7th, 2012 &lt;br /&gt;
  |script_version = 0.36 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the early days of Zan's groundwork, providing the (hooks) infrastructure to enable base package developers to prototype, test and develop distinct rendering pipelines without requiring C++ space modifications has been a long-standing idea, especially after the [[Canvas]] system became available in early 2012, which demonstrated how RTT-rendering buffers (FBOs) could be set up, created and manipulated procedurally (i.e. at run-time) using XML, the property tree and [[Nasal]] scripting. &amp;lt;ref&amp;gt;{{forum link|type=search|title=Zan's Rembrandt and Canvas work|keywords=zan+rembrandt+canvas}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new '''Compositor''' is an improved re-implementation of Zan's original work using not just XML, but also [[Property Tree|properties]] and a handful of [[Canvas]] concepts.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
* Completely independent of other parts of the simulator, i.e. it's part of [[SimGear]] and can be used in a standalone fashion if needed, ala Canvas.&lt;br /&gt;
* Although independent, its aim is to be fully compatible with the current rendering framework in FG. This includes the [[Effects]] system, [[Howto:Configure camera view windows|CameraGroup]], [[Rembrandt]], [[ALS]] and [[Canvas]].&lt;br /&gt;
* Its functionality overlaps Rembrandt: what can be done with Rembrandt can be done with the Compositor, but not vice versa.&lt;br /&gt;
* Fully configurable via an XML interface without compromising performance (ala Effects, using [[PropertyList XML File|PropertyList files]]).&lt;br /&gt;
* Flexible, expandable and compatible with modern graphics.&lt;br /&gt;
* It doesn't increase the hardware requirements, it expands the hardware range FG can run on. People with integrated GPUs (Intel HD etc) can run a Compositor with a single pass that renders directly to the screen like before, while people with more powerful cards can run a Compositor that implements deferred rendering, for example.&lt;br /&gt;
* Static branching support. Every pipeline element can be enabled/disabled at startup via a [[Conditions|&amp;lt;condition&amp;gt; block]].&lt;br /&gt;
* The entire rendering pipeline can be reloaded via an fgcommand (&amp;lt;tt&amp;gt;reload-compositor&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== How to enable the Compositor ==&lt;br /&gt;
&lt;br /&gt;
The Compositor is now the default renderer framework in FlightGear since 2020/11/17. It will be included as part of version 2020.4 onwards.&lt;br /&gt;
&lt;br /&gt;
If you compile FlightGear from source, you can already try the Compositor. Make sure you are pulling the latest version of the 'next' branch. You can also try out the latest nightly build from the [[FlightGear build server]].&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
The Compositor introduces a new way of defining lights that is renderer agnostic, so every rendering pipeline will be able to access the lights that have been implemented like this. The resulting light volumes can be visualized for debugging purposes by setting the property &amp;lt;tt&amp;gt;/sim/debug/show-light-volumes&amp;lt;/tt&amp;gt; to true.&lt;br /&gt;
&lt;br /&gt;
You can edit existing lights with the '''[[Illuminator addon|Illuminator]]''', but you have to define them first e.g. in your aircraft. The Illuminator add-on is meant for fine-tuning the light parameters.&lt;br /&gt;
&lt;br /&gt;
[[Project Rembrandt]] light definitions are also read by the Compositor for backwards compatibility reasons. However, it is not recommended to use the old syntax for new/updated projects.&lt;br /&gt;
&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top style=&amp;quot;width: 20%;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.03&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.03&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.03&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/ambient&amp;gt;&lt;br /&gt;
  &amp;lt;diffuse&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.95&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.9&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.9&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/diffuse&amp;gt;&lt;br /&gt;
  &amp;lt;specular&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;0.95&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.9&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.9&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/specular&amp;gt;&lt;br /&gt;
  &amp;lt;attenuation&amp;gt;&lt;br /&gt;
    &amp;lt;c&amp;gt;1.0&amp;lt;/c&amp;gt;&lt;br /&gt;
    &amp;lt;l&amp;gt;0.09&amp;lt;/l&amp;gt;&lt;br /&gt;
    &amp;lt;q&amp;gt;0.032&amp;lt;/q&amp;gt;&lt;br /&gt;
  &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
  &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;controls/lighting/instruments-norm&amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/dim-factor&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top style=&amp;quot;width: 80%;&amp;quot;|&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''name'''&amp;lt;/tt&amp;gt;. An {{tag|animation}} will be able to reference the light by this name. Most [[Howto:Animate_models|animations]] will work as expected (rotate, translate, spin etc). Material animations are not supported.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''type'''&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;point&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''position'''&amp;lt;/tt&amp;gt;. The position of the light source in model space and in meters.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''direction'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. It indicates the direction of the spotlight. This parameter can be specified in three different ways:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 1px solid darkgray;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Direction vector&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Look-at point&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:33%;&amp;quot; |Rotation angles&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | A vector in model space that specifies the direction. Doesn't have to be normalized.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
&amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
&amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | The spotlight will calculate its direction by looking at this position from the light position. The point is in model space and in meters.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;lookat-x-m&amp;gt;-8.031&amp;lt;/lookat-x-m&amp;gt;&lt;br /&gt;
&amp;lt;lookat-y-m&amp;gt;0&amp;lt;/lookat-y-m&amp;gt;&lt;br /&gt;
&amp;lt;lookat-z-m&amp;gt;-2&amp;lt;/lookat-z-m&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | A three angle rotation in degrees that rotates the spotlight around the three axes. A 0 degree angle in all axes makes the spotlight point downwards (negative Z).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pitch-deg&amp;gt;90&amp;lt;/pitch-deg&amp;gt;&lt;br /&gt;
&amp;lt;roll-deg&amp;gt;0&amp;lt;/roll-deg&amp;gt;&lt;br /&gt;
&amp;lt;heading-deg&amp;gt;0&amp;lt;/heading-deg&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''ambient'''&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'''diffuse'''&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;'''specular'''&amp;lt;/tt&amp;gt;. Four-component vectors that specify the light color.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''attenuation'''&amp;lt;/tt&amp;gt;. Three-component vector where &amp;lt;code&amp;gt;&amp;lt;c&amp;gt;&amp;lt;/code&amp;gt; specifies the constant factor, &amp;lt;code&amp;gt;&amp;lt;l&amp;gt;&amp;lt;/code&amp;gt; specifies the linear factor and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;q&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; specifies the quadratic factor. These factors are plugged into the OpenGL light attenuation formula [[File:Spotlight_attenuation.png]] where d is the distance of the fragment to the light source. See this [http://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation table] for a list of attenuation values based on the range of the light.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''range-m'''&amp;lt;/tt&amp;gt;. Maximum range from the light source position in meters. This value will be used by the renderers to determine if a fragment is illuminated by this source. Every fragment outside this range isn't guaranteed to be affected by the light, even if the attenuation factor isn't 0 in that particular fragment.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''spot-cutoff'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. It specifies the maximum spread angle of a light source. Only values in the range 0 90 are accepted. If the angle between the direction of the light and the direction from the light to the fragment being lighted is greater than the spot cutoff angle, it won't be lit.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''spot-exponent'''&amp;lt;/tt&amp;gt;. Only available in &amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt; lights. Higher spot exponents result in a more focused light source, regardless of the spot cutoff angle.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''dim-factor'''&amp;lt;/tt&amp;gt; ('''Optional'''). Controls the dimming of the light source through an [[Expressions|expression]].&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''debug-color'''&amp;lt;/tt&amp;gt; ('''Optional'''). Sets the color of the debug light volume. By default it's red.&lt;br /&gt;
'''&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;Important: &amp;lt;/span&amp;gt;'''The following parameters are '''only''' available in the [[HDR Pipeline]].&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''color'''&amp;lt;/tt&amp;gt;. The color or hue of emitted light. It is expected to be in the sRGB color space.&lt;br /&gt;
* &amp;lt;tt&amp;gt;'''intensity'''&amp;lt;/tt&amp;gt;. The brightness of the light. This value can be (and will almost always be) higher than 1.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Shadows ===&lt;br /&gt;
&lt;br /&gt;
The shadow mapping algorithm can be customized entirely by the rendering pipeline. This means that each pipeline will have its own requirements when it comes to shadows. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Use the [[Howto:Animate models#Noshadow|&amp;lt;tt&amp;gt;noshadow&amp;lt;/tt&amp;gt; animation]] to disable shadows on objects that don't need them. An example would be billboarded lights (light sprites) or really small cockpit elements that don't need shadows and would cause degraded performance.&lt;br /&gt;
If the casted aircraft shadow appears blocky then there probably are some objects which need the noshadow animation applied. Most notably are billboarded lights which include [[ALS_technical_notes#ALS procedural lights|ALS procedural lights]].&lt;br /&gt;
* Try to mark as many cockpit objects as possible as &amp;lt;tt&amp;gt;interior&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;model&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;interior&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;usage&amp;gt;interior&amp;lt;/usage&amp;gt;&lt;br /&gt;
  &amp;lt;path&amp;gt;Aircraft/JA37/Models/ja37-interior.xml&amp;lt;/path&amp;gt; &amp;lt;!-- All the objects that should only be seen when inside the cockpit are in this file --&amp;gt;&lt;br /&gt;
&amp;lt;/model&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Unlike in Rembrandt, polygons facing the Sun are the ones used to generate the shadow map, so single sided surfaces and non-closed objects should be rendered correctly.&lt;br /&gt;
&lt;br /&gt;
== Effects and Shaders ==&lt;br /&gt;
&lt;br /&gt;
=== Schemes ===&lt;br /&gt;
&lt;br /&gt;
Effects can have different implementations depending on the Compositor pipeline being used. For example, a grass Effect implemented for a high quality pipeline might have much more detail than one that targets low specification machines. Still, they both implement the &amp;quot;look&amp;quot; of grass, so they share the same Effect file (grass.eff).&lt;br /&gt;
&lt;br /&gt;
The Compositor chooses which implementation of an Effect to render based on the &amp;lt;tt&amp;gt;&amp;lt;scheme&amp;gt;&amp;lt;/tt&amp;gt; of the techniques.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;technique n=&amp;quot;15&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;scheme&amp;gt;test-scheme&amp;lt;/scheme&amp;gt;&lt;br /&gt;
  [...]&lt;br /&gt;
&amp;lt;/technique&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the technique will be chosen if the Compositor pipeline &amp;lt;tt&amp;gt;&amp;lt;scene&amp;gt;&amp;lt;/tt&amp;gt; pass uses the &amp;lt;tt&amp;gt;test-scheme&amp;lt;/tt&amp;gt; Effect scheme. Consequently, porting an Effect to a Compositor pipeline will require knowing which Effect schemes it uses and writing a technique for each one. The only exception to this is the Classic/default pipeline, which uses techniques with no scheme.&lt;br /&gt;
&lt;br /&gt;
=== Built-in uniforms ===&lt;br /&gt;
&lt;br /&gt;
The Compositor provides a set of built-in uniforms that are passed along to every shader. These uniforms must '''not''' be defined in the Effect file, as they are defined and updated in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Type&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_TextureMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Texture matrix that replaces the old fixed-function behaviour. If no texture animations are present it corresponds to the identity matrix.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Viewport&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Viewport geometry for the current pass (x, y, width, height).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_PixelSize&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the width and height of the viewport.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|View matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the view matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Inverse of the projection matrix given by CameraGroup for this Compositor.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionCart&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in cartesian coordinates.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionGeod&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters).&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraDistanceToEarthCenter&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance from the camera to the center of the Earth in meters.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraWorldUp&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Camera up vector in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraViewUp&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Camera up vector in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_EarthRadius&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Earth radius right below the camera position in meters.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_NearFar&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Near and far clipping planes in meters). x component is the near plane, y component is the far plane.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Fcoef&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used by logarithmic depth.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FOVScale&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used by logarithmic depth.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Sun (directional light) direction in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirectionWorld&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Sun (directional light) direction in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunZenithCosTheta&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dot product between the Sun direction and the up vector at the camera position.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Moon (directional light) direction in view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonDirectionWorld&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Normalized Moon (directional light) direction in world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_MoonZenithCosTheta&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dot product between the Moon direction and the up vector at the camera position.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Creating a custom rendering pipeline ==&lt;br /&gt;
&lt;br /&gt;
Since the Compositor is completely data-driven, new rendering pipelines can be created by writing a custom XML pipeline definition. This section tries to document most of the available parameters, but the best and most up-to-date resource is the Compositor parsing code in SimGear ({{simgear file|simgear/scene/viewer}}). See existing pipelines in {{fgdata file|Compositor}} for practical examples on how to use these parameters.&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that every pipeline element can be enabled/disabled through a [[Conditions|&amp;lt;condition&amp;gt; block]]. This allows for dynamic rendering pipelines that have toggleable features. However, the pipeline can't be updated in real-time: the simulator has to be restarted or the Compositor has to be reloaded through the &amp;lt;tt&amp;gt;reload-compositor&amp;lt;/tt&amp;gt; [[Fgcommands|fgcommand]].&lt;br /&gt;
&lt;br /&gt;
=== Buffers ===&lt;br /&gt;
&lt;br /&gt;
A buffer represents a texture or, more generically, a region of GPU memory.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| string&lt;br /&gt;
|&lt;br /&gt;
| Passes will be able to address the buffer by this name&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;1d, 2d, 2d-array, 2d-multisample, 3d, rect, cubemap&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
| Any texture type allowed by OpenGL&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;width&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer or &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; to use the physical viewport width. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture width&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;screen-width-scale&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| If &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; was used, this controls the width scaling factor&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;height&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer or &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; to use the physical viewport height. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture height&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;screen-height-scale&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| If &amp;lt;tt&amp;gt;screen&amp;lt;/tt&amp;gt; was used, this controls the height scaling factor&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;depth&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Any unsigned integer. The &amp;lt;code&amp;gt;&amp;lt;property&amp;gt;&amp;lt;/code&amp;gt; tag can also be used to use a property value&lt;br /&gt;
|&lt;br /&gt;
| Texture depth&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| See {{simgear file|simgear/scene/viewer/CompositorBuffer.cxx}} for the latest available values&lt;br /&gt;
| &amp;lt;tt&amp;gt;rgba8&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Specifies the texture format. It corresponds to the ''internalformat'', ''format'' and ''type'' arguments of the OpenGL function ''glTexImage2D''&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;min-filter, mag-filter&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;linear, linear-mipmap-linear, linear-mipmap-nearest, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;linear&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Change the minification and magnification filtering respectively&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;wrap-s, wrap-t, wrap-r&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;clamp, clamp-to-edge, clamp-to-border, repeat, mirror&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;clamp-to-border&amp;lt;/tt&amp;gt;&lt;br /&gt;
| They change the wrap mode for each coordinate&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;anisotropy&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;border-color&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| vec4&lt;br /&gt;
| &amp;lt;tt&amp;gt;(0.0f, 0.0f, 0.0f, 0.0f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-comparison&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-texture-mode&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;luminance, intensity, alpha&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;luminance&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;shadow-compare-func&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;never, less, equal, lequal, greater, notequal, gequal, always&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;lequal&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Passes ===&lt;br /&gt;
&lt;br /&gt;
A pass wraps around an [http://public.vrac.iastate.edu/vancegroup/docs/OpenSceneGraphReferenceDocs-3.0/a00089.html osg::Camera]. Passes all have some common parameters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;clear-color, clear-accum, clear-depth and clear-stencil&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| vec4&lt;br /&gt;
| black, black, &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; respectively&lt;br /&gt;
| Pass clear colors&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;clear-mask&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;color, stencil, depth, accum&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;color depth&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Pass clear mask&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;effect-scheme&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid effect scheme name&lt;br /&gt;
| None&lt;br /&gt;
| The pass will try to use the specified effect scheme to draw every object.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Passes can render to a buffer (Render to Texture), to several buffers (Multiple Render Targets) or directly to the framebuffer. This is accomplished by the &amp;lt;code&amp;gt;&amp;lt;attachment&amp;gt;&amp;lt;/code&amp;gt; tag. Possible parameters of an attachment are:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Valid buffer name&lt;br /&gt;
| &lt;br /&gt;
| The name of the buffer to output to&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;component&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| &amp;lt;tt&amp;gt;color, color0&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;color15, depth, stencil, depth-stencil&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
| FBO attachment point&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;level&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Mipmap level of the texture that is attached&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;face&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Face of cube map texture or z-level of 3d texture&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;mipmap-generation&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Whether mipmap generation should be done for texture&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;multisample-samples&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Multisample anti-aliasing (MSAA) samples&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;multisample-color-samples&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Multisample anti-aliasing (MSAA) color samples&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Passes can also receive buffers as input and use them in their shaders. This is accomplished by the &amp;lt;code&amp;gt;&amp;lt;binding&amp;gt;&amp;lt;/code&amp;gt; tag, which has the following parameters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| Valid buffer name&lt;br /&gt;
| &lt;br /&gt;
| The name of the buffer to bind&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;unit&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| int&lt;br /&gt;
| &lt;br /&gt;
| The texture unit to place the texture on. Effects will be able to access the buffer on this texture unit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are specific pass types, each with their own set of custom parameters.&lt;br /&gt;
&lt;br /&gt;
==== scene ====&lt;br /&gt;
Renders the scene from the point of view given by the CameraGroup.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;cull-mask&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| A 32 bit number. See {{simgear file|simgear/scene/util/RenderConstants.hxx}} to know which bits enable what&lt;br /&gt;
| &amp;lt;tt&amp;gt;0xffffffff&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Specifies the cull mask to be used in the underlying &amp;lt;tt&amp;gt;osg::Camera&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;z-near, z-far&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float&lt;br /&gt;
| 0.0 uses the value given by the CameraGroup&lt;br /&gt;
| Sets a custom near and far values. Useful for implementing depth partition and limiting the depth range on cubemap passes&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;cubemap-face&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; (don't use cubemap)&lt;br /&gt;
| Ignores the given view and projection matrices and uses a custom one that renders the scene as if it was seen from inside a cubemap looking towards the specified face&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;use-shadow-pass&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| string&lt;br /&gt;
| Empty&lt;br /&gt;
| Name of a shadow mapping pass. Exposes shadow mapping related uniforms to the shaders of the current pass&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scene passes can also use the tag &amp;lt;code&amp;gt;&amp;lt;clustered-shading&amp;gt;&amp;lt;/code&amp;gt; to enable clustered shading (lights). The following parameters are available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-pointlights&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1024&lt;br /&gt;
| Maximum amount of point light sources allowed on the entire scene&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-spotlights&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1024&lt;br /&gt;
| Maximum amount of spot light sources allowed on the entire scene&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;max-light-indices&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 256&lt;br /&gt;
| Size of the light indices texture. Keep in mind that it is a 2D texture, so the total size will be e.g. 256x256&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;tile-size&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 128&lt;br /&gt;
| Size of each clustered shading tile&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;num-threads&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1&lt;br /&gt;
| Number of threads to use during the light culling process. Keep in mind that a high thread count when there aren't many lights will worsen performance due to the thread creation overhead&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;depth-slices&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| int&lt;br /&gt;
| 1&lt;br /&gt;
| Number of slices to partition the view frustum in the Z axis. Higher numbers will cull lights more aggressively, increasing performance if there are many lights further out that don't contribute much to the overall scene's lighting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== quad ====&lt;br /&gt;
Renders a fullscreen quad with an optional [[Effects|effect]] applied. Useful for screen space shaders (like SSAO, Screen Space Reflections or bloom) and deferred rendering.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;geometry&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| float values for &amp;lt;code&amp;gt;&amp;lt;x&amp;gt;, &amp;lt;y&amp;gt;, &amp;lt;width&amp;gt;, &amp;lt;height&amp;gt;, &amp;lt;scale&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;0.0, 0.0, 1.0, 1.0, 1.0&amp;lt;/tt&amp;gt; respectively&lt;br /&gt;
| Size of the fullscreen quad inside the viewport using normalized coordinates.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;effect&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid Effect file&lt;br /&gt;
| None&lt;br /&gt;
| This Effect will be applied to the quad geometry&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== csm ====&lt;br /&gt;
Implements Cascaded Shadow Mapping by rendering the scene from a light's point of view (the Sun by default). For now it only supports directional light sources. There has to be one &amp;lt;tt&amp;gt;csm&amp;lt;/tt&amp;gt; pass for each cascade.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center; font-size: 85%; width: auto; table-layout: fixed;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Parameter Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Optional&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Default Value&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Description&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;light-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| Valid light name that exists in the scene graph&lt;br /&gt;
| &amp;lt;tt&amp;gt;FGLightSource&amp;lt;/tt&amp;gt; (Sun)&lt;br /&gt;
| The name of the &amp;lt;tt&amp;gt;osg::LightSource&amp;lt;/tt&amp;gt; to use for this shadow map&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;render-at-night&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{Yes}}&lt;br /&gt;
| bool&lt;br /&gt;
| true&lt;br /&gt;
| Whether to render the shadows at night or not&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot;| &amp;lt;tt&amp;gt;near-m, far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
| {{No}}&lt;br /&gt;
| float (meters)&lt;br /&gt;
|&lt;br /&gt;
| They specify the range of the shadow map&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Wiki articles ===&lt;br /&gt;
* [[HDR Pipeline]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
* [[Canvas View Camera Element]]&lt;br /&gt;
* [[CompositeViewer Support]]&lt;br /&gt;
* [[Uniform Buffer Objects]]&lt;br /&gt;
* [[FlightGear CIGI Support (Common Image Generator Interface)]]&lt;br /&gt;
&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=36269|text=The Compositor}}&lt;br /&gt;
* {{forum link|t=35095|text=Clustered Forward Rendering}} (12/2018)&lt;br /&gt;
* {{forum link|t=33045|text=Getting started with RTT}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Shader_programming_in_FlightGear&amp;diff=139082</id>
		<title>Howto:Shader programming in FlightGear</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Shader_programming_in_FlightGear&amp;diff=139082"/>
		<updated>2024-02-07T13:09:50Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP|More to follow}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is meant to become an introduction to '''shader programming in FlightGear''', for the time being (03/2010), this is work in progress, please feel free to ask questions or suggest topics. Your help in improving and updating this article is appreciated, thanks!&lt;br /&gt;
&lt;br /&gt;
If you are creating a shader from scratch, you should follow the [[Shader Style Guide]].&lt;br /&gt;
&lt;br /&gt;
Keep in mind that this article assumes GLSL version 120. Some of the syntax might be outdated for modern GLSL versions (330 onwards).&lt;br /&gt;
&lt;br /&gt;
Tutorials about GLSL Programming in general are collected at [[GLSL Shader Programming Resources]]. For an OpenGL quick reference, please see: http://www.khronos.org/files/opengl-quick-reference-card.pdf for an GLSL quick reference see [http://www-evasion.imag.fr/Membres/Sebastien.Barbier/Enseignement/glsl_quickref.pdf glsl_quickref.pdf]&lt;br /&gt;
&lt;br /&gt;
== What is GLSL? ==&lt;br /&gt;
''GLSL'' (''OpenGL Shading Language'' or &amp;quot;GLslang&amp;quot;) is the official OpenGL shading language and allows you to write programs, so called &amp;quot;shaders&amp;quot; in a high level shading language that is based on the C programming language to create OpenGL fragment (pixel) and vertex shaders.&lt;br /&gt;
&lt;br /&gt;
With the recent advances in graphics cards, new features have been added to allow for increased flexibility in the rendering pipeline at the vertex and fragment level. Programmability at this level is achieved with the use of fragment and vertex shaders.&lt;br /&gt;
&lt;br /&gt;
GLSL was created to give developers more direct control of the graphics pipeline without having to use assembly language or hardware-specific languages. Shaders provide the possibility to process individual vertices or fragments individually, so that complex rendering tasks can be accomplished without stressing the CPU. Support for shader was first introduced via extensions in OpenGL 1.5, but is now part of the core OpenGL 2.0 standard.&lt;br /&gt;
&lt;br /&gt;
Shaders are written and stored as plain text files, which can be uploaded (as strings) and executed on the GPU (processor of the graphics card).&lt;br /&gt;
&lt;br /&gt;
== What is a shader? ==&lt;br /&gt;
A ''shader'' is a programmable replacement for parts of the fixed OpenGL function pipeline, you can imagine it sort of like a &amp;quot;plugin&amp;quot; to customize rendering for specific scene elements.&lt;br /&gt;
&lt;br /&gt;
GLSL shaders are not stand-alone applications; they require an application that utilizes the OpenGL API. &lt;br /&gt;
A shader is a program, to be run it must be loaded, compiled and linked. &lt;br /&gt;
Shaders will be compiled when the 3D application starts. They will be validated and optimized for the current hardware.&lt;br /&gt;
&lt;br /&gt;
Actually each vertex and fragment shader must have one entry point (the main function) each, but you can create and link more shaders.&lt;br /&gt;
&lt;br /&gt;
GLSL shaders themselves are simply a set of strings that are passed to the hardware vendors driver for compilation from within an application using the OpenGL APIs entry points. Shaders can be created on the fly from within an application or read in as text files, but must be sent to the driver in the form of a string. &lt;br /&gt;
&lt;br /&gt;
GLSL has explicit ties to the OpenGL API - to the extent that much of the OpenGL &amp;quot;state&amp;quot; (for example which light sources are bound, what material properties are currently set up) is presented as pre-defined global variables in GLSL.&lt;br /&gt;
&lt;br /&gt;
Shaders offer:&lt;br /&gt;
* Opportunity for Improved Visual Quality&lt;br /&gt;
* Algorithm Flexibility&lt;br /&gt;
* Performance Benefits&lt;br /&gt;
&lt;br /&gt;
Shaders have access to textures and the render state (parameters, matrices, lights, materials etc).&lt;br /&gt;
A &amp;quot;pass&amp;quot; is the rendering of a 3D Model with a vertex and pixel shader pair.&lt;br /&gt;
An effect can require multiple passes, while each pass can use a different shader and/or model pair.&lt;br /&gt;
A Pass can render to a texture (to be used by another pass). Think of the &amp;quot;fixed functionality&amp;quot; as the default Shader.&lt;br /&gt;
&lt;br /&gt;
To make it simple, a shader is a program that is loaded on the GPU and called for every vertex or pixel: this gives programmers the possibility to implement techniques and visual effects and execute them faster. In modern games or simulators lots of shaders are used: lights, water, skinning, reflections and much more. &lt;br /&gt;
&lt;br /&gt;
We can create as many shader programs as needed.  You can have many shaders of the same type (vertex or fragment) attached to the same program, but only one of them can define the entry point — the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
Each Shader program is assigned an handler, and you can have as many programs linked and ready to use as you want (and your hardware allows).&lt;br /&gt;
Once rendering, we can switch from program to program, and even go back to fixed functionality during a single frame. &lt;br /&gt;
&lt;br /&gt;
To really understand shaders, you should have a knowledge about the rendering pipeline; this helps to understand where and when the shaders act in the rendering process. In general, you must know that vertex are collected, processed by vertex shaders, primitives are built, then are applied colors, textures and are also called fragment shaders; finally it comes to the rasterization and the frame is put on the buffer. &lt;br /&gt;
&lt;br /&gt;
Some benefits of using GLSL are:&lt;br /&gt;
* Cross platform compatibility on multiple operating systems, including Linux, Mac OS and Windows.&lt;br /&gt;
* The ability to write shaders that can be used on any hardware vendor’s graphics card that supports the OpenGL Shading Language.&lt;br /&gt;
* Each hardware vendor includes the GLSL compiler in their driver, thus allowing each vendor to create code optimized for their particular graphics cards architecture.&lt;br /&gt;
&lt;br /&gt;
== Language features ==&lt;br /&gt;
While GLSL has a C-Like syntax, it introduces some new types and keywords. To get a detailed view of the language, please see the GLSL specification you can find on http://www.opengl.org/documentation/glsl/&lt;br /&gt;
&lt;br /&gt;
The OpenGL Shading Language provides many operators familiar to those with a background in using the C programming language. This gives shader developers flexibility when writing shaders. GLSL contains the operators in C and C++, with the exception of pointers. Bitwise operators were added in version 1.30.&lt;br /&gt;
&lt;br /&gt;
Similar to the C programming language, GLSL supports loops and branching, including &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;for&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;do-while&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;break&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;continue&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
User defined functions are supported, and a wide variety of commonly used functions are provided built-in as well. This allows the graphics card manufacturer the ability to optimize these built-in functions at the hardware level if they are inclined to do so. Many of these functions are similar to those found in the math library of the C programming language such as &amp;lt;code&amp;gt;exp()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;abs()&amp;lt;/code&amp;gt; while others are specific to graphics programming such as &amp;lt;code&amp;gt;smoothstep()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;texture2D()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Error Reports, Debugging, Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
Shaders are compiled at FG startup.&lt;br /&gt;
&lt;br /&gt;
Shader compilation errors can be found in the fgfs.log file.  More about the [[Commonly_used_debugging_tools#fgfs.log|fgfs.log here]].&lt;br /&gt;
&lt;br /&gt;
As of FG 2016.4.4, shaders do not seem to recompile upon Debug/Reload Aircraft Model or File/Reset. So the only option to re-compile/test a shader is to quit a re-start FG altogether.&lt;br /&gt;
&lt;br /&gt;
== Shader types ==&lt;br /&gt;
There are two types of shaders in GLSL: ''vertex shaders'' and ''fragment shaders'' (with geometry shaders being a part of OpenGL 3.2).&lt;br /&gt;
&lt;br /&gt;
These are executed by vertex and fragment processors in the graphics hardware.&lt;br /&gt;
&lt;br /&gt;
* Vertex shaders transform vertices, set up data for fragment shaders&lt;br /&gt;
* Fragment shaders operate on fragments generated by rasterization&lt;br /&gt;
* Geometry shaders create geometry on the GPU&lt;br /&gt;
&lt;br /&gt;
Typically, vertex shader files use the file extension &amp;lt;code&amp;gt;.vert&amp;lt;/code&amp;gt;, while fragment shader files use the &amp;lt;code&amp;gt;.frag&amp;lt;/code&amp;gt; extension. &lt;br /&gt;
In FlightGear, these files can be found in the &amp;lt;code&amp;gt;Shaders&amp;lt;/code&amp;gt; subdirectory of the base package, in essence &amp;lt;code&amp;gt;$FG_ROOT/Shaders&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For a list of currently available shaders, you may want to take a look at: {{fg root file|Shaders}}.&lt;br /&gt;
&lt;br /&gt;
So, shaders generally go around in pairs - one shader (the ''vertex shader'') is a short program that takes in one vertex from the main CPU and produces one vertex that is passed on to the GPU rasterizer which uses the vertices to create triangles - which it then chops up into individual pixel-sized fragments. &lt;br /&gt;
&lt;br /&gt;
A vertex shader is run once per vertex, while a fragment shader is run once per fragment covered by the primitive being rendered (a point, a line or a triangle). A fragment equate a pixel except in the case of multi-sampling where a pixel can be the weighted average of several fragments. Multi-sampling is used to remove aliasing and jagged edges.&lt;br /&gt;
Many such executions can happen in parallel. There is no communication or ordering between executions. Vertex shaders are flexible and quick.&lt;br /&gt;
&lt;br /&gt;
=== Vertex shaders ===&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |The vertex shader doesn't know anything about the mesh it renders, it just knows one single vertex at a time and all the info that is attached to the vertex (normals, tangents, binormals, color,...)  And the vertex shader doesn't really draw anything, it just takes care of all the things which have to do with 'where in space' you are.&lt;br /&gt;
The way this works is that for all the vertices of an object you want to render, the position of the object gets attached to all vertices (currently in the color spot). The vertex shader then just adds the offset vector to the vertex coordinate with respect to the origin.&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/32326487/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] cities in FG &amp;amp; how to move forward&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Renk Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2014-05-11&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Input&lt;br /&gt;
| Vertex attributes&lt;br /&gt;
|-&lt;br /&gt;
! Output&lt;br /&gt;
| At least vertex position (in the clip space)&lt;br /&gt;
|-&lt;br /&gt;
! Restrictions&lt;br /&gt;
| Cannot access any vertex other than the current one&lt;br /&gt;
|-&lt;br /&gt;
! ''Note''&lt;br /&gt;
| ''Loading a vertex shader turns off parts of the OpenGL pipeline (vertex shaders fully replace the &amp;quot;Texturing &amp;amp; Lighting unit&amp;quot;).''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Objects in a computer graphics scene are usually meshes that are made up of polygons. The corner of each of those polygons is called a ''vertex''.&lt;br /&gt;
A vertex shader receives input in the form of per-vertex variables called ''attribute variables'', and per-polygon variables called ''uniform variables''.&lt;br /&gt;
The vertex shader must specify the coordinates of the vertex in question. This way, the geometry of the object can be modified. &lt;br /&gt;
&lt;br /&gt;
Vertex shaders operate on each vertex, the vertex shader is executed for every vertex related OpenGL call (for example &amp;lt;code&amp;gt;glVertex*&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;glDrawArrays&amp;lt;/code&amp;gt;).&lt;br /&gt;
Accordingly, this means for example, that for meshes that contain for example 5000 vertices, the vertex shader will also be executed 5000 times.&lt;br /&gt;
&lt;br /&gt;
A single vertex itself is composed of a number of ''attributes'' (vertex attrib), such as: position, texture coordinates, normal and color for the most common. &lt;br /&gt;
The position (attribute) is the most important one. The coordinates (x, y and z) of the vertex's entering position are those which have been given by the 3D modeler during the creation of the 3D model. The vertex's position is defined in the local space of the mesh (or object space). &lt;br /&gt;
&lt;br /&gt;
A vertex shader provides almost full control over what is happening with each vertex. Consequently, all per-vertex operations of the fixed function OpenGL pipeline are replaced by the custom vertex shader. &lt;br /&gt;
&lt;br /&gt;
Vertex shaders take application geometry and per-vertex attributes as input and transform the input data in some meaningful way.&lt;br /&gt;
&lt;br /&gt;
* A vertex shader '''must''' write to &amp;lt;code&amp;gt;gl_Position&amp;lt;/code&amp;gt;&lt;br /&gt;
* A vertex shader '''can''' write to &amp;lt;code&amp;gt;gl_PointSize&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;gl_ClipVertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_Vertex&amp;lt;/code&amp;gt; is an attribute supplying the untransformed vertex coordinate&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_Position&amp;lt;/code&amp;gt; is an special output variable for the transformed vertex coordinate&lt;br /&gt;
&lt;br /&gt;
A vertex shader can also set other variables which are called ''varying variables''.&lt;br /&gt;
The values of these variables are passed on to the second kind of shader, the ''fragment shader''. &lt;br /&gt;
The fragment shader is run for every pixel on the screen where the polygons of the mesh appear. The fragment shader is responsible for setting the final color of that little piece of the mesh&lt;br /&gt;
&lt;br /&gt;
Common tasks for a vertex shader include:&lt;br /&gt;
* Vertex position transformation&lt;br /&gt;
* Per vertex lighting&lt;br /&gt;
* Normal transformation&lt;br /&gt;
* Texture coordinates transformation or generation&lt;br /&gt;
* Vertex color computation&lt;br /&gt;
* Geometry skinning&lt;br /&gt;
* Animation&lt;br /&gt;
* Setting up data for fragment shaders&lt;br /&gt;
&lt;br /&gt;
The vertex shader runs from start to end for each and every vertex that's passed into the graphics card – the fragment process does the same thing at the pixel level. In most scenes there are a heck of a lot more pixel fragments than there are vertices – so the performance of the fragment shader is vastly more important and any work we can do in the vertex shader, we probably should. &lt;br /&gt;
&lt;br /&gt;
A minum vertex shader example may looks this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
  gl_Position = ftransform();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fragment shaders ===&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |the fragment shader basically knows only the pixel it is about to render and whatever information is passed from the vertex shader. Based on 'where' the vertex shader says the pixel is, the rasterizer stage determines what the texture for the pixel should be. &lt;br /&gt;
But there are techniques to do this in a different way, for instance the water depth map uses world coordinates to look up a world texture, and the gardens would have to be drawn in a similar way.&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/32326487/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] cities in FG &amp;amp; how to move forward&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Renk Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2014-05-11&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Input&lt;br /&gt;
| Interpolation of the vertex shader outputs&lt;br /&gt;
|-&lt;br /&gt;
! Output&lt;br /&gt;
| Usually a fragment color.&lt;br /&gt;
|-&lt;br /&gt;
! Restrictions&lt;br /&gt;
| Fragment shaders have no knowledge of neighboring pixels.&lt;br /&gt;
|-&lt;br /&gt;
! ''Note''&lt;br /&gt;
| ''Loading a fragment shader turns off parts of the OpenGL pipeline (pixel shaders fully replace the &amp;quot;Texturing Unit&amp;quot;).''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other shader (the ''fragment shader'' - also (incorrectly) known as the &amp;quot;pixel shader&amp;quot;) takes one pixel from the rasterizer and generates one pixel to write or blend into the frame buffer. &lt;br /&gt;
&lt;br /&gt;
A fragment shader can write to the following special output variables:&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_FragColor&amp;lt;/code&amp;gt; to set the color of the fragment&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_FragData[n]&amp;lt;/code&amp;gt; to output to a specific render target&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_FragDepth&amp;lt;/code&amp;gt; to set the fragment depth&lt;br /&gt;
&lt;br /&gt;
Common tasks of fragment shaders include:&lt;br /&gt;
* Texturing (even procedural)&lt;br /&gt;
* Per pixel lighting and material application&lt;br /&gt;
* Ray tracing&lt;br /&gt;
* Fragment color computation&lt;br /&gt;
* Operations on Interpolated Values&lt;br /&gt;
* Doing operations per fragment to make pretty pictures&lt;br /&gt;
&lt;br /&gt;
A minimum fragment shader may look like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A fragment shader takes perspective-correct interpolated attribute values as input and either discards the fragment or outputs the fragment's color.&lt;br /&gt;
&lt;br /&gt;
Fragment shaders operate on every fragment which is produced by rasterization. Fragment shaders give you nearly full control over what is happening with each fragment. However just like vertex shaders, a fragment shader replaces all per-fragment operations of the fixed function OpenGL pipeline.&lt;br /&gt;
&lt;br /&gt;
== Data types in GLSL ==&lt;br /&gt;
Note that there is no implicit type conversion in GLSL, all conversions and initializations have to be done using explicit constructor calls!&lt;br /&gt;
&lt;br /&gt;
=== Scalars ===&lt;br /&gt;
* &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; – 32 bit, very nearly IEEE-754 compatible&lt;br /&gt;
* &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; – at least 16 bit, but not backed by a fixed-width register&lt;br /&gt;
* &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; – like C++, but must be explicitly used for all flow control&lt;br /&gt;
&lt;br /&gt;
=== Vectors ===&lt;br /&gt;
* &amp;lt;code&amp;gt;vec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec4&amp;lt;/code&amp;gt; – 2D, 3D and 4D floating point vector&lt;br /&gt;
* &amp;lt;code&amp;gt;ivec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ivec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ivec4&amp;lt;/code&amp;gt; – 2D, 3D and 4D integer vector&lt;br /&gt;
* &amp;lt;code&amp;gt;bvec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bvec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bvec4&amp;lt;/code&amp;gt; – 2D, 3D and 4D boolean vectors&lt;br /&gt;
&lt;br /&gt;
Accessing a vector can be done using letters as well as standard C selectors.&lt;br /&gt;
&lt;br /&gt;
TODO: explain swizzling&lt;br /&gt;
&lt;br /&gt;
One can use the letters x,y,z,w to access vectors components; r,g,b,a for color components; and&lt;br /&gt;
s,t,p,q for texture coordinates.&lt;br /&gt;
&lt;br /&gt;
=== Matrices ===&lt;br /&gt;
* &amp;lt;code&amp;gt;mat2&amp;lt;/code&amp;gt; – 2x2 floating point matrix&lt;br /&gt;
* &amp;lt;code&amp;gt;mat3&amp;lt;/code&amp;gt; – 3x3 floating point matrix&lt;br /&gt;
* &amp;lt;code&amp;gt;mat4&amp;lt;/code&amp;gt; – 4x4 floating potint matrix	&lt;br /&gt;
&lt;br /&gt;
=== Samplers ===&lt;br /&gt;
In GLSL, textures are represented and accessed using so called &amp;quot;samplers&amp;quot;, which are used for sampling textures and which have to be uniform. The following samplers are available:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;sampler1D&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sampler2D&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sampler3D&amp;lt;/code&amp;gt; – 1D, 2D and 3D texture&lt;br /&gt;
* &amp;lt;code&amp;gt;samplerCube&amp;lt;/code&amp;gt; – Cube Map texture&lt;br /&gt;
* &amp;lt;code&amp;gt;sampler1Dshadow&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sampler2Dshadow&amp;lt;/code&amp;gt; – 1D and 2D depth-component texture&lt;br /&gt;
&lt;br /&gt;
=== Arrays ===&lt;br /&gt;
GLSL supports the same syntax for creating arrays that is already known from C or C++, e.g.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec2 foo[10];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, arrays can be declared using the same syntax as in C, but can't be initialized when declared. Accessing array's elements is done as in C.&lt;br /&gt;
&lt;br /&gt;
=== Structures ===&lt;br /&gt;
Structures can also be created like in C or C++, e.g.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct foo {&lt;br /&gt;
  vec3 pos;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Global storage qualifiers ==&lt;br /&gt;
Used for communication between shaders and application:&lt;br /&gt;
* &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; – For declaring non-writable, compile-time constant variables&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute&amp;lt;/code&amp;gt; – For frequently changing (per vertex) information passed from the application to a vertex shader (no integers, bools, structs, or arrays)&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform&amp;lt;/code&amp;gt; – For infrequently changing (per primitive) information passed from the application to a vertex or fragment shader:constant shader parameters that can be changed between draws (cannot be written to in a shader, do not change per-vertex or per-fragment)&lt;br /&gt;
* &amp;lt;code&amp;gt;varying&amp;lt;/code&amp;gt; – For information passed from a vertex shader to a fragment shader, will be interpolated in a perspective-correct manner during rasterization (can write in vertex shader, but only read in fragment shader)&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
* Much like C++&lt;br /&gt;
* Entry point into a shader is &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Overloading based on parameter type (but not return type)&lt;br /&gt;
* No support for direct or indirect recursion&lt;br /&gt;
* Call by value-return calling convention&lt;br /&gt;
&lt;br /&gt;
As in C, a shader is structured in functions. At least each type of shader must have a main function declared with the following syntax: &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt;&lt;br /&gt;
User defined functions may be defined. As in C a function may have a return value, and use the return statement to pass out its result. A function can be void. The return type can have any type, except array.&lt;br /&gt;
&lt;br /&gt;
=== Parameter qualifiers ===&lt;br /&gt;
The parameters of a function may have the following qualifiers:&lt;br /&gt;
* &amp;lt;code&amp;gt;in&amp;lt;/code&amp;gt; – Copy in, but don't copy back out (still writable within function)&lt;br /&gt;
* &amp;lt;code&amp;gt;out&amp;lt;/code&amp;gt; – Only copy out; undefined at function entry point&lt;br /&gt;
* &amp;lt;code&amp;gt;inout&amp;lt;/code&amp;gt; – Copy in and copy out&lt;br /&gt;
&lt;br /&gt;
If no qualifier is specified, by default it is considered to be in.&lt;br /&gt;
&lt;br /&gt;
== Built-ins ==&lt;br /&gt;
=== Vertex shader ===&lt;br /&gt;
* &amp;lt;code&amp;gt;vec4 gl_Position;&amp;lt;/code&amp;gt; – '''Must''' be written&lt;br /&gt;
* &amp;lt;code&amp;gt;vec4 gl_ClipPosition;&amp;lt;/code&amp;gt; – May be written&lt;br /&gt;
* &amp;lt;code&amp;gt;float gl_PointSize;&amp;lt;/code&amp;gt; – May be written&lt;br /&gt;
&lt;br /&gt;
=== Fragment shader ===&lt;br /&gt;
* &amp;lt;code&amp;gt;float gl_FragColor;&amp;lt;/code&amp;gt; – May be written&lt;br /&gt;
* &amp;lt;code&amp;gt;float gl_FragDepth;&amp;lt;/code&amp;gt; – May be read/written&lt;br /&gt;
* &amp;lt;code&amp;gt;vec4 gl_FragCoord;&amp;lt;/code&amp;gt; – May be read&lt;br /&gt;
* &amp;lt;code&amp;gt;bool gl_FrontFacing;&amp;lt;/code&amp;gt; – May be read&lt;br /&gt;
&lt;br /&gt;
=== Vertex attributes ===&lt;br /&gt;
Only available in vertex shaders.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_Vertex;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec3 gl_Normal;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_Color;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_SecondaryColor;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_MultiTexCoordn;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute float gl_FogCoord;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Uniforms ===&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_ModelViewMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_ProjectionMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_ModelViewProjectionMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat3 gl_NormalMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_TextureMatrix[n];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters {&lt;br /&gt;
  vec4 emission;&lt;br /&gt;
  vec4 ambient;&lt;br /&gt;
  vec4 diffuse;&lt;br /&gt;
  vec4 specular;&lt;br /&gt;
  float shininess;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform gl_MaterialParameters gl_FrontMaterial;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform gl_MaterialParameters gl_BackMaterial;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters {&lt;br /&gt;
  vec4 ambient;&lt;br /&gt;
  vec4 diffuse;&lt;br /&gt;
  vec4 specular;&lt;br /&gt;
  vec4 position;&lt;br /&gt;
  vec4 halfVector;&lt;br /&gt;
  vec3 spotDirection;&lt;br /&gt;
  float spotExponent;&lt;br /&gt;
  float spotCutoff;&lt;br /&gt;
  float spotCosCutoff;&lt;br /&gt;
  float constantAttenuation&lt;br /&gt;
  float linearAttenuation&lt;br /&gt;
  float quadraticAttenuation&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Varyings ===&lt;br /&gt;
An interface between vertex and fragment shaders is provided by varying variables: Vertex shaders compute values per vertex and fragment shaders compute values per fragment. &lt;br /&gt;
The value of a varying variable defined in a vertex shader, will be interpolated (perspective-correct) over the primitive being rendered and the interpolated value in the fragment shader can be accessed.&lt;br /&gt;
&lt;br /&gt;
Varying variables can only be used with the data types &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec4&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mat2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mat3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mat4&amp;lt;/code&amp;gt;. (and arrays of them too.)&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_FrontColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_BackColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_FrontSecColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_BackSecColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_Color; // fragment&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_SecondaryColor; // fragment&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_TexCoord[]; // both&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying float gl_FogFragCoord; // both&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
== Anatomy of a shader ==&lt;br /&gt;
A shader's entry point is the main function which returns void and takes no arguments (void)&lt;br /&gt;
&lt;br /&gt;
=== Anatomy of a vertex shader ===&lt;br /&gt;
The function &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt; is called afresh for each vertex in the 3D object model:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
// Vertex Shader&lt;br /&gt;
void main() {&lt;br /&gt;
  gl_Position = gl_Vertex;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anatomy of a fragment shader ===&lt;br /&gt;
The function &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt; is called afresh for each fragment/pixel in the 3D object model:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
// Fragment Shader&lt;br /&gt;
void main() {&lt;br /&gt;
  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Practical application – ALS landing lights – spotlight ==&lt;br /&gt;
[[File:ALS Secondary Light Proof of Concept.png|thumb|300px|ALS secondary light proof of concept]]&lt;br /&gt;
[[File:Als Secondary Lights combined with Fog Effect.jpg|thumb|300px|Weather settings to produce fog and ALS landing lights on a runway.]]&lt;br /&gt;
[[File:Model on Water and Trees on Land.jpg|thumb|300px|Model on water and trees on land ALS lights effect]]&lt;br /&gt;
[[File:Model on Water.jpg|thumb|300px|ALS lights effect over model and water.]]&lt;br /&gt;
[[File:ALS Lights over Model and Terrain.jpg|thumb|300px|ALS lights over model and terrain]]&lt;br /&gt;
&lt;br /&gt;
The ALS landing lights-spotlight (we'll call it ALS lights from now on) is a good example for showing how to incorporate a shader effect into FlightGear as it touches many parts of the visuals we see and many parts of the coding pipeline.&lt;br /&gt;
&lt;br /&gt;
In the case of ALS Lights, you have to add the effect to every visual item rendered on the screen that you want to see a light shining on. If you want it to be capable of shining on everything, you have to account for each separate item and how that item is rendered.  That is a lot of code to touch.&lt;br /&gt;
&lt;br /&gt;
The list might include&lt;br /&gt;
* Terrain&lt;br /&gt;
** Runway&lt;br /&gt;
** Dirtrunway&lt;br /&gt;
** Agriculture&lt;br /&gt;
* Models&lt;br /&gt;
** AI&lt;br /&gt;
** Aircraft&lt;br /&gt;
** Tree&lt;br /&gt;
** Buildings&lt;br /&gt;
* Weather&lt;br /&gt;
** Fog&lt;br /&gt;
** Clouds&lt;br /&gt;
** Hazes&lt;br /&gt;
* Water&lt;br /&gt;
** Inland&lt;br /&gt;
** Ocean&lt;br /&gt;
** Stream&lt;br /&gt;
&lt;br /&gt;
Some of these items may be controlled or rendered by the same effect and shader file. They might have to be accounted for individually. They may have special lighting influences that have to be accounted for. You have to take each one separately and account for all its needs. &lt;br /&gt;
&lt;br /&gt;
The example highlighted in this article is what was added to &amp;lt;code&amp;gt;tree.eff&amp;lt;/code&amp;gt; to shine the lights on trees.&lt;br /&gt;
&lt;br /&gt;
=== Program flow simplified ===&lt;br /&gt;
Preferences/Nasal/XML → Property tree → Effect file → Shader → Rendered to screen&lt;br /&gt;
&lt;br /&gt;
=== Preferences/Nasal/XML ===&lt;br /&gt;
Any combination of Preferences, [[Nasal|Nasal]] or [[Xml|XML]] manipulates data in the [[Property Tree|property tree]]. &lt;br /&gt;
In this case the switch to turn on the landing or spot light and a couple other needed data containers are defined in &amp;lt;code&amp;gt;$FG_ROOT/preferences.xml&amp;lt;/code&amp;gt; with the following lines.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;als-secondary-lights&amp;gt;&lt;br /&gt;
 &amp;lt;use-searchlight type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/use-searchlight&amp;gt;&lt;br /&gt;
 &amp;lt;use-landing-light type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/use-landing-light&amp;gt;&lt;br /&gt;
 &amp;lt;use-alt-landing-light type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/use-alt-landing-light&amp;gt;&lt;br /&gt;
 &amp;lt;landing-light1-offset-deg type=&amp;quot;float&amp;quot;&amp;gt;0.0&amp;lt;/landing-light1-offset-deg&amp;gt;&lt;br /&gt;
 &amp;lt;landing-light2-offset-deg type=&amp;quot;float&amp;quot;&amp;gt;0.0&amp;lt;/landing-light2-offset-deg&amp;gt;&lt;br /&gt;
&amp;lt;/als-secondary-lights&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They show up in the property tree under &amp;lt;code&amp;gt;sim/rendering/als-secondary-lights&amp;lt;/code&amp;gt; and can be activated or manipulated by normal Nasal calls or XML.&lt;br /&gt;
&lt;br /&gt;
=== Property tree ===&lt;br /&gt;
The [[Property Tree|property tree]] is like the CPU of the [[FlightGear]] program at a user level. It's a go-between that allows the user to see and influence many aspects at the heart of the program in ALMOST real time. More of the internals of FlightGear are being exposed to the property tree than ever before. This allows us to have user level access in areas of the code that used to only be reserved for [[Programming Resources|programmers]]. Because of the manner in which the property tree is fed information, and the one step removed from the C source, care must be taken in how it is used. Depending on how it is used it won't be as responsive to manipulation as it would be if you were to change the same information at the C source level. &lt;br /&gt;
 &lt;br /&gt;
=== Effects file ===&lt;br /&gt;
The effects file is the mechanism we use to combine and manipulate all the necessary data to create stunning visual effects. It's the link between the data contained and produced in Nasal, XML and the property tree and the graphics rendering pipeline. It's there to allow us to create these affects without having to know or use the C++ code base. Its flexible framework allows for an almost infinite range of sophisticated effects.&lt;br /&gt;
&lt;br /&gt;
See this page for more details: [[Effect Framework]]&lt;br /&gt;
&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
Parameter entries defined in the Effect file correspond to a property tree data container (static or variable). They will contain the data needed by the shader program to perform its magic. The type of information contained in the property tree might be program control data or variable/static data that the shader program can manipulate prior to sending on to render.&lt;br /&gt;
In the case of ALS lights, below is some of the data passed to, and used by, the shader program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
 &amp;lt;display_xsize&amp;gt;&amp;lt;use&amp;gt;/sim/startup/xsize&amp;lt;/use&amp;gt;&amp;lt;/display_xsize&amp;gt;&lt;br /&gt;
 &amp;lt;display_ysize&amp;gt;&amp;lt;use&amp;gt;/sim/startup/ysize&amp;lt;/use&amp;gt;&amp;lt;/display_ysize&amp;gt;&lt;br /&gt;
 &amp;lt;view_pitch_offset&amp;gt;&amp;lt;use&amp;gt;/sim/current-view/pitch-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/view_pitch_offset&amp;gt;&lt;br /&gt;
 &amp;lt;view_heading_offset&amp;gt;&amp;lt;use&amp;gt;/sim/current-view/heading-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/view_heading_offset&amp;gt;&lt;br /&gt;
 &amp;lt;view_fov&amp;gt;&amp;lt;use&amp;gt;/sim/current-view/field-of-view&amp;lt;/use&amp;gt;&amp;lt;/view_fov&amp;gt;&lt;br /&gt;
 &amp;lt;use_searchlight&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/use-searchlight&amp;lt;/use&amp;gt;&amp;lt;/use_searchlight&amp;gt;&lt;br /&gt;
 &amp;lt;use_landing_light&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/use-landing-light&amp;lt;/use&amp;gt;&amp;lt;/use_landing_light&amp;gt;&lt;br /&gt;
 &amp;lt;use_alt_landing_light&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/use-alt-landing-light&amp;lt;/use&amp;gt;&amp;lt;/use_alt_landing_light&amp;gt;&lt;br /&gt;
 &amp;lt;landing_light1_offset&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/landing-light1-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/landing_light1_offset&amp;gt;&lt;br /&gt;
 &amp;lt;landing_light2_offset&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/landing-light2-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/landing_light2_offset&amp;gt;&lt;br /&gt;
 &amp;lt;quality_level&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/shaders/landmass&amp;lt;/use&amp;gt;&amp;lt;/quality_level&amp;gt;&lt;br /&gt;
 &amp;lt;tquality_level&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/shaders/transition&amp;lt;/use&amp;gt;&amp;lt;/tquality_level&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;use-searchlight&amp;lt;/code&amp;gt; entry, it is pointing to the use-searchlight entry in the property tree under &amp;lt;code&amp;gt;sim/rendering/als-secondary-lights&amp;lt;/code&amp;gt; that was defined in &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Some of this data may play a duel role inside the shader program. In other words it might be used to control other functions in addition to ALS lights.&lt;br /&gt;
There will also be other parameter entries that have nothing to do with ALS lights. They might be used for other actions or effects the shader is handling. &lt;br /&gt;
&lt;br /&gt;
==== Technique ====&lt;br /&gt;
In general, the shader program and the uniforms are defined in between the technique tags. The technique is assigned an index to distinguish one technique from another (technique n=&amp;quot;1&amp;quot;). As is the case with tree.eff, sometimes the shader program and its uniforms are defined and needed in more than one technique. In the case of &amp;lt;code&amp;gt;tree.eff&amp;lt;/code&amp;gt; it is used in technique 4 and 5. Which means in FlightGear, the tree shader set to either of the the highest two shader settings still produces ALS lights when activated.&lt;br /&gt;
&lt;br /&gt;
==== Shader program ====&lt;br /&gt;
Next comes the entry to define what shader program the parameters data is going to be passed to.&lt;br /&gt;
This is where you specify what shader program is to be used by the technique. ALS has the lowest techniques, with higher quality preceding lower quality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
 &amp;lt;fragment-shader&amp;gt;Shaders/tree-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
 &amp;lt;fragment-shader&amp;gt;Shaders/secondary_lights.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In the case of ALS Lights, so far we only have to deal with the fragment shader.&lt;br /&gt;
&lt;br /&gt;
The program section of the effect file is a nifty method used to allow users to add shaders to FlightGear without having to add code at C level language base. The C level base is programed to recognize the XML tag pair of &amp;lt;program&amp;gt;&amp;lt;/program&amp;gt; and thus incorporate the GLSL program files pointed to between the tags. Otherwise you would have to add the GLSL program calls in the base C requiring a completely different set of programing skills and also the necessity of compiling FlightGear everytime you want to add new shader. It can work this way because shader programs are compiled at run-time.&lt;br /&gt;
&lt;br /&gt;
We'll describe the contents of the shader programs below. For now, suffice it to say &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; contains the main program and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt; has functions that are passed uniform data that is manipulated and returned to main for processing.&lt;br /&gt;
&lt;br /&gt;
==== Uniforms ====&lt;br /&gt;
The uniforms section is the mechanism that feeds the parameter data to the shader program.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;view_pitch_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;view_pitch_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;view_heading_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;view_heading_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;field_of_view&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;view_fov&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;landing_light1_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;landing_light1_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;landing_light2_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;landing_light2_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;use_searchlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;use_searchlight&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;use_landing_light&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;use_landing_light&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;use_alt_landing_light&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;use_alt_landing_light&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;display_xsize&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;display_xsize&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;display_ysize&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;display_ysize&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note the name, &amp;lt;code&amp;gt;use_searchlight&amp;lt;/code&amp;gt;, which was originally defined in &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt; and then became an entry in parameters is now being passed to the program shader by the uniform. Below in the &amp;quot;Shader program&amp;quot; section, we will show you how the shader receives the uniform's data.&lt;br /&gt;
&lt;br /&gt;
=== Shader programs ===&lt;br /&gt;
The shader programs used in this example are &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== secondary_lights.frag ===&lt;br /&gt;
&amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt; consists of&lt;br /&gt;
* Uniform inputs (data coming into the shader to be manipulated&lt;br /&gt;
* Functions that manipulate the uniform data&lt;br /&gt;
&lt;br /&gt;
Following it the actual GLSL code in &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Uniform input ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform int display_xsize;&lt;br /&gt;
uniform int display_ysize;&lt;br /&gt;
uniform float field_of_view;&lt;br /&gt;
uniform float view_pitch_offset;&lt;br /&gt;
uniform float view_heading_offset;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Functions ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float light_distance_fading(in float dist)&lt;br /&gt;
{&lt;br /&gt;
  return min(1.0, 10000.0/(dist*dist));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
float fog_backscatter(in float avisibility)&lt;br /&gt;
{&lt;br /&gt;
  return 0.5* min(1.0,10000.0/(avisibility*avisibility));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vec3 searchlight()&lt;br /&gt;
{&lt;br /&gt;
  vec2 center = vec2 (float(display_xsize) * 0.5, float(display_ysize) * 0.4);&lt;br /&gt;
  float headlightIntensity;  &lt;br /&gt;
  float lightRadius = (float(display_xsize) *9.16 /field_of_view);&lt;br /&gt;
  float angularDist = length(gl_FragCoord.xy -center);&lt;br /&gt;
  if (angularDist &amp;lt; lightRadius)&lt;br /&gt;
  {&lt;br /&gt;
    headlightIntensity = pow(cos(angularDist/lightRadius * 1.57075),2.0);&lt;br /&gt;
    //headlightIntensity = headlightIntensity * &lt;br /&gt;
    //headlightIntensity*= clamp(1.0 + 0.15 * log(1000.0/(dist*dist)),0.0,1.0);&lt;br /&gt;
    return  headlightIntensity * vec3 (0.5,0.5, 0.5);&lt;br /&gt;
  }&lt;br /&gt;
  else return vec3 (0.0,0.0,0.0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vec3 landing_light(in float offset)&lt;br /&gt;
{&lt;br /&gt;
  float fov_h = field_of_view;&lt;br /&gt;
  float fov_v = float(display_ysize)/float(display_xsize) * field_of_view; &lt;br /&gt;
  float yaw_offset;&lt;br /&gt;
  if (view_heading_offset &amp;gt; 180.0)&lt;br /&gt;
    {yaw_offset = -360.0+view_heading_offset;}&lt;br /&gt;
  else&lt;br /&gt;
    {yaw_offset = view_heading_offset;}&lt;br /&gt;
  float x_offset = (float(display_xsize) / fov_h * (yaw_offset + offset));&lt;br /&gt;
  float y_offset = -(float(display_ysize) / fov_v * view_pitch_offset);&lt;br /&gt;
  vec2 center = vec2 (float(display_xsize) * 0.5 + x_offset, float(display_ysize) * 0.4 + y_offset);&lt;br /&gt;
  float landingLightIntensity;  &lt;br /&gt;
  float lightRadius = (float(display_xsize) *9.16 /field_of_view);&lt;br /&gt;
  float angularDist = length(gl_FragCoord.xy -center);&lt;br /&gt;
  if (angularDist &amp;lt; lightRadius)&lt;br /&gt;
  {&lt;br /&gt;
    landingLightIntensity = pow(cos(angularDist/lightRadius * 1.57075),2.0);&lt;br /&gt;
    //landingLightIntensity *= min(1.0, 10000.0/(dist*dist));&lt;br /&gt;
    return  landingLightIntensity * vec3 (0.5,0.5, 0.5);&lt;br /&gt;
  }&lt;br /&gt;
  else return vec3 (0.0,0.0,0.0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tree-ALS.frag ===&lt;br /&gt;
&amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; consists of&lt;br /&gt;
* Uniform inputs (data coming into the shader to be manipulated&lt;br /&gt;
* Functions that manipulate the uniform data&lt;br /&gt;
&lt;br /&gt;
Following it the actual GLSL code in &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt;.&lt;br /&gt;
While there is significantly more code in &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt;, only the code that was included for the ALS lights is being shown and discussed here.&lt;br /&gt;
&lt;br /&gt;
==== Uniform input ====&lt;br /&gt;
Uniform data is brought into the shader in the following manner.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform float landing_light1_offset;&lt;br /&gt;
uniform float landing_light2_offset;&lt;br /&gt;
uniform int use_searchlight;&lt;br /&gt;
uniform int use_landing_light;&lt;br /&gt;
uniform int use_alt_landing_light;&lt;br /&gt;
uniform int quality_level;&lt;br /&gt;
uniform int tquality_level;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note &amp;lt;code&amp;gt;use_searchlight&amp;lt;/code&amp;gt; and how it is defined as incoming uniform data.&lt;br /&gt;
&lt;br /&gt;
==== Variable data ====&lt;br /&gt;
Variable data can be defined in the shader program. An example of variable data defined in the shader program that is needed for ALS lights is&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3 secondary_light = vec3 (0.0,0.0,0.0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Functions ====&lt;br /&gt;
Function calls to the function defined in &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt; are&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3 searchlight();&lt;br /&gt;
vec3 landing_light(in float offset);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You don't have to use any path information or includes in the code because the GLSL compiler program takes care of linking all the shader programs as long as they are defined correctly in the &amp;quot;programs&amp;quot; section of the effect file.&lt;br /&gt;
Variable data can be passed to and returned from GLSL functions just like any other language.&lt;br /&gt;
&lt;br /&gt;
==== Main program ====&lt;br /&gt;
The &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function is the heart of the shader program. This is where the shader program manipulates all the data made available to it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  vec3 secondary_light = vec3 (0.0,0.0,0.0);&lt;br /&gt;
  if ((quality_level&amp;gt;5) &amp;amp;&amp;amp; (tquality_level&amp;gt;5))&lt;br /&gt;
  {&lt;br /&gt;
    if (use_searchlight == 1)&lt;br /&gt;
    {&lt;br /&gt;
      secondary_light += searchlight();&lt;br /&gt;
    }&lt;br /&gt;
    if (use_landing_light == 1)&lt;br /&gt;
    {&lt;br /&gt;
      secondary_light += landing_light(landing_light1_offset);&lt;br /&gt;
    }&lt;br /&gt;
    if (use_alt_landing_light == 1)&lt;br /&gt;
    {&lt;br /&gt;
      secondary_light += landing_light(landing_light2_offset);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  vec4 fragColor = vec4 (gl_Color.rgb +secondary_light * light_distance_fading(dist),1.0) * texel;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how &amp;lt;code&amp;gt;use_searchlight&amp;lt;/code&amp;gt; is used in the main function to determine if the property defined in &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt; and manipulated in the property tree is set to true or 1.&lt;br /&gt;
&lt;br /&gt;
Some of the variable data contained in the shader program is used for other purposes and is introduced into the shader program from other property, parameter and uniform definitions not pertaining to ALS lights.&lt;br /&gt;
&lt;br /&gt;
==== File list ====&lt;br /&gt;
Files that are directly touched by this effect include &lt;br /&gt;
* &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;agriculture.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;crop&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;agriculture-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;airfield.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;airfield-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;building.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;model-combined-deferred&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;model-combined&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 4)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;model-ALS-ultra.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Inherits uniforms from &amp;lt;code&amp;gt;model-combined-deferred&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;model-combined&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;dirt-runway.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;crop&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;drunway-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;model-combined.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;model-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 4)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;model-ALS-ultra.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 4)&lt;br /&gt;
* &amp;lt;code&amp;gt;model-default.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Adds properties&lt;br /&gt;
** Adds program shaders (technique 5)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;model-ALS-base.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 5)&lt;br /&gt;
* &amp;lt;code&amp;gt;runway.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from terrain-default&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;runway-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;terrain-default.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Adds properties&lt;br /&gt;
** Adds program shaders (technique 3)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;terrain-ALS-ultra.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 3)&lt;br /&gt;
* &amp;lt;code&amp;gt;tree.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Adds properties&lt;br /&gt;
** Adds program shaders (technique 4 and 5)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 4 and 5)&lt;br /&gt;
* &amp;lt;code&amp;gt;urban.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 1 and 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;urban-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 1 and 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;water.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 1)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;water-ALS-high.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 1)&lt;br /&gt;
* &amp;lt;code&amp;gt;water-inland.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;water-ALS-high.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
&lt;br /&gt;
== General comments from forum discussion ==&lt;br /&gt;
{{cquote|In principle, we always do the same steps in the fragment shaders to determine the color of a pixel:&lt;br /&gt;
&lt;br /&gt;
* texel color - what is the base color of the pixel fully lit and unfogged&lt;br /&gt;
* lighting - how is this color changed by the light falling onto that pixel, usually the relation is something like fragColor equals texel * light&lt;br /&gt;
* fogging - how much is the color hidden by haze, usually the relation is something like gl_FragColor equals mix(fragColor, hazeColor, transmission_factor);&lt;br /&gt;
what is displayed on the screen in the end is whatever gl_FragColor is set to&lt;br /&gt;
&lt;br /&gt;
But the location where this happens isn't always obvious - often (part) of the light is computed in the vertex shader already, in which case it typically enters the fragment shader as gl_Color.&lt;br /&gt;
&lt;br /&gt;
So, the lighting equation in tree-haze.frag is indeed&lt;br /&gt;
vec4 fragColor equals vec4 (gl_Color.xyz,1.0) * texel;&lt;br /&gt;
and your change to the light should happen just before that. But you can't do&lt;br /&gt;
gl_Color.rgb equals gl_Color.rgb + my_light;&lt;br /&gt;
because gl_Color.rgb is a varying variable type, and you can't assign new values to them inside the shader, so you need to either make a new variable or just do&lt;br /&gt;
vec4 fragColor equals vec4 ((gl_Color.rgb + my_light),1.0) * texel;&lt;br /&gt;
(note that color.rgb is the same as color.xyz, GLSL doesn't really care which convention you use, but I took a few months to learn that, so early code by myself often uses xyz indexing convention for color vectors as well).&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=15#p220075 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Tue Oct 07, 2014 12:04 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|An effect is a container for a series of techniques which are all the possible things you could do with some object.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;predicate&amp;gt; section inside each effect determines which of the techniques we actually run. Typically the predicate section contains conditionals on a) rendering framework properties b) OpenGL extension support and c) quality level properties. The renderer searches the effects from lowest to highest technique number and uses the first one that fits the bill (which is why high quality levels precede low quality levels).&lt;br /&gt;
&lt;br /&gt;
The rendering itself is specified as &amp;lt;pass&amp;gt; - each pass runs the renderer over the whole scene. We may sometimes make a quick first pass to fill the depth buffer or a stencil buffer, but usually we render with a single pass.&lt;br /&gt;
&lt;br /&gt;
Techniques may not involve a shader at all, for instance 12 in terrain-default is a pure fixed pipeline fallback technique, but all the rendering you're interested in use a shader, which means they have a &amp;lt;program&amp;gt; section which determines what actual code is supposed to run.&lt;br /&gt;
&lt;br /&gt;
If you run a shader, that needs parameters specified as &amp;lt;uniform&amp;gt;, and textures which need to be assigned to a texture unit _and_ be declared as a uniform sampler.&lt;br /&gt;
&lt;br /&gt;
In addition, each technique contains a host of parameter configuring the fixed pipeline elements, like alpha tests before the fragment stage, or depth buffer writing/reading, alpha blending,... you can ignore them on the first go.&lt;br /&gt;
&lt;br /&gt;
So if you want to look at which shader code is executed when you call the water effect at a certain quality level, you need to work your way through the predicate sections of the techniques from lowest to highest till you find the one that matches, and then look into the program section of that technique.&lt;br /&gt;
&lt;br /&gt;
Now, to make matters more complicated, all the parameters and textures that are assigned to uniforms and texture units in the techniques need to be declared and linked to properties were applicable in the &amp;lt;parameters&amp;gt; section heading each effect declaration. So a texture you want to use has to appear three times - in the parameters section heading the effect, inside the technique assigned to a texture unit and assigned to a uniform sampler.&lt;br /&gt;
&lt;br /&gt;
Now, inheritance moves all the declared parameters and techniques from one effect to the one inheriting. In the case of water, that means the technique is actually _not_ inherited because terrain-default.eff doesn't contain a technique 1 at all, but the general &amp;lt;parameters&amp;gt; section is inherited. So you don't need to declare the additions to &amp;lt;parameters&amp;gt; again, but you do need to make the changes to the &amp;lt;programs&amp;gt; and the &amp;lt;uniform&amp;gt; sections.&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=15#p220152 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Wed Oct 08, 2014 1:58 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|At low water shader quality, water isn't rendered separately from the terrain, i.e. it runs via terrain-default.eff - since you modified that to allow light, light works for water out of the box.&lt;br /&gt;
At high water slider, the techniques in water.eff kick in, and only then do you need to modify the specific water shader code. Now, the peculiar thing about water is that there are two effects (water.eff and water_inland.eff) sharing the same shader code (but calling it with somewhat different parameters). So the function not found error was presumably caused by you modifying water.eff whereas the water you were seeing was initiated by water_inland.eff, and in that effect, the secondary_lights.frag wasn't initially in the program section. So if you alter the water shader code, you need to modify two effect files rather than one to pass the right parameters and access the functions you need.&lt;br /&gt;
&lt;br /&gt;
..........&lt;br /&gt;
..........&lt;br /&gt;
&lt;br /&gt;
Adding them _after_ fogging, isn't what you want - you'll see that if visibility is &amp;lt;100 m, everything will go black at night, because fog color is black at night, so finalColor.rgb of a heavily fogged object will also be black, and then when you light it up, you multiply your light value with black and it'll be black. Or, if you add the light value (which you should only do if the object you add it to is a light color itself), then you'll get a featureless grey. You want to add light after texel color and before fogging.&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=30#p220216 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Wed Oct 08, 2014 11:19 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|So, in old times when rendering textures was slow and complicated, we rendered objects with monochromatic surface colors. Then the (schematic) lighting equation (without specular, and the sum of ambient and diffuse already computed) was&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals objectColor.rgb * light.rgb + objectEmissive.rgb&lt;br /&gt;
&lt;br /&gt;
Now, we have textures and so we get&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals objectColor.rgb * texel.rgb * light.rgb + objectEmissive.rgb + lightMapTexel.rgb&lt;br /&gt;
&lt;br /&gt;
Since we can have the full color information in the texture, objectColor.rgb is usually (1.0,1.0,1.0) because the info is redundant. But if you don't use a texture, of course objectColor.rgb has the actual color value (incidentially, I think we shouldn't texture with monochromatic surfaces at all, it creates a jarring visual impression which can be cured by using even a small texture...)&lt;br /&gt;
&lt;br /&gt;
But if you do, the rendering pipeline is set up to compute color.rgb equals objectColor * light.rgb in the vertex shader, so the equation we have in the fragment shader is something like&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals color.rgb * texel.rgb + objectEmissive.rgb + lightMapTexel.rgb&lt;br /&gt;
&lt;br /&gt;
and if we add a secondary light like&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals (color.rgb + secLight.rgb) * texel.rgb&lt;br /&gt;
&lt;br /&gt;
it of course can never recover the color information, because color.rgb is zero at night since you multiplied the actual color with zero sunlight and the texel doesn't carry information for an untextured object.&lt;br /&gt;
&lt;br /&gt;
Since the secondary light is in screen coordinates, it can't appear in the vertex shader, so the solution would be to pass the actual color and light rather than their product to the fragment shader. Which is expensive, because we need another varying vec3, and varying variable types fill memory and need to be computed an interpolated per vertex/per fragment - which is why I'm not sure whether we shouldn't accept the loss of the color...&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=45#p220321 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Sat Oct 11, 2014 1:28 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|Inheritance works like this:&lt;br /&gt;
&lt;br /&gt;
The base effect has a list of things&lt;br /&gt;
&lt;br /&gt;
A1 B1 C1 D1&lt;br /&gt;
&lt;br /&gt;
The second effect inherits 1 but just declares C2 and E2, so then the list is&lt;br /&gt;
&lt;br /&gt;
A1 B1 C2 D1 E2&lt;br /&gt;
&lt;br /&gt;
The third effect inherits from 2 and declares A3, so then the list is&lt;br /&gt;
&lt;br /&gt;
A3 B1 C2 D1 E2&lt;br /&gt;
&lt;br /&gt;
whereas if the third effect would inherit from 1, then the list would be&lt;br /&gt;
&lt;br /&gt;
A3 B1 C1 D1&lt;br /&gt;
&lt;br /&gt;
So if already present, inheritance overrides, if not present it adds. I suspect that's why programs need to be indexed, so they they override and don't add...&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=45#p220403 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Sat Oct 11, 2014 11:33 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|Shader Programming in FlightGear]]&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category: Core developer documentation]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Shader_Style_Guide&amp;diff=139081</id>
		<title>Shader Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Shader_Style_Guide&amp;diff=139081"/>
		<updated>2024-02-07T13:05:52Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
FlightGear uses [[Shader|shaders]] written in GLSL. If you are creating a new shader from scratch, you should be following the style of this documentation. For an introduction to shader programming, see [[Howto:Shader programming in FlightGear]].&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
* Vertex, fragment, geometry and compute shaders should have the following file extensions, respectively: &amp;lt;tt&amp;gt;.vert&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.frag&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.geom&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;.comp&amp;lt;/tt&amp;gt; (ex: &amp;lt;tt&amp;gt;shading_opaque.frag&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* Spaces in the file name must be substituted by an underscore '&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'. You must not use a dash '&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;'. For example, {{xt|shader_opaque.frag}} is correct but {{!xt|shader-opaque.frag}} is not.&lt;br /&gt;
* Every shader file must contain one and only one &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; function. If a shader does not contain a &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; function, it is considered a shader library, and its file extension must be &amp;lt;tt&amp;gt;.glsl&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Shader libraries ==&lt;br /&gt;
&lt;br /&gt;
If a function can be used by several shaders, put it on a separate &amp;lt;tt&amp;gt;.glsl&amp;lt;/tt&amp;gt; library file. Shader libraries can be used with other shaders by linking them together. For example, in the [[Effect framework|Effect]] file you can write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
    &amp;lt;fragment-shader&amp;gt;Shaders/HDR/shading.frag&amp;lt;/fragment-shader&amp;gt; &amp;lt;!-- Contains the main() function --&amp;gt;&lt;br /&gt;
    &amp;lt;fragment-shader&amp;gt;Shaders/HDR/math.glsl&amp;lt;/fragment-shader&amp;gt;    &amp;lt;!-- Contains some utility functions that can be used in shading.frag, but no main() --&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use the functions contained in &amp;lt;tt&amp;gt;math.glsl&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;shading.frag&amp;lt;/tt&amp;gt;, you must declare the signatures of the functions you intend to use at the top of the file. For example, if the &amp;lt;tt&amp;gt;math.glsl&amp;lt;/tt&amp;gt; library contains a function named &amp;lt;tt&amp;gt;saturate()&amp;lt;/tt&amp;gt;, in &amp;lt;tt&amp;gt;shading.frag&amp;lt;/tt&amp;gt; you must write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float saturate(float x);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Due to how OpenGL shader linking works, we can only share functions between shader files. If you want to share a constant across multiple files, create a new library file and write a function that returns the constant. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float M_PI() {&lt;br /&gt;
    return 3.14159265358979323846;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Keep in mind that structs cannot be shared across shader files, so make sure they are only used locally.&lt;br /&gt;
&lt;br /&gt;
== Naming ==&lt;br /&gt;
&lt;br /&gt;
* Naming should follow &amp;lt;tt&amp;gt;snake_case&amp;lt;/tt&amp;gt; convention. The only exceptions are type names (ex: &amp;lt;tt&amp;gt;PointLight&amp;lt;/tt&amp;gt;) and the &amp;lt;tt&amp;gt;fragColor&amp;lt;/tt&amp;gt; output variable.&lt;br /&gt;
* Do not use reserved keywords like &amp;lt;tt&amp;gt;sampler&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Single letter vectors should be a capital letter (ex: &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt; for '''N'''ormal, instead of &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Sampler resource names should have the &amp;lt;tt&amp;gt;_tex&amp;lt;/tt&amp;gt; suffix (ex: &amp;lt;code&amp;gt;uniform sampler2D color_tex;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Space prefix ===&lt;br /&gt;
&lt;br /&gt;
Variable names can have a prefix depending on the space they are in:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;ws_&amp;lt;/tt&amp;gt; for '''W'''orld '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;vs_&amp;lt;/tt&amp;gt; for '''V'''iew or Eye '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;ls_&amp;lt;/tt&amp;gt; for '''L'''ocal or Model '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;cs_&amp;lt;/tt&amp;gt; for '''C'''lip '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;ndc_&amp;lt;/tt&amp;gt; for '''NDC''' coordinates (clip coordinates after perspective division).&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The structure of a shader file should follow this order:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
#version 330 core&lt;br /&gt;
/*&lt;br /&gt;
 * Small description of what the shader does.&lt;br /&gt;
 * Try to cite as many resources as possible. Shader code is known to be hard to understand without a reference implementation or any math.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// #defines from the corresponding Effect file&lt;br /&gt;
#pragma import_defines(MY_OWN_DEFINE MY_OTHER_DEFINE)&lt;br /&gt;
&lt;br /&gt;
// Fragment writes or vertex attributes&lt;br /&gt;
layout(location = 0) out vec4 fragColor;&lt;br /&gt;
&lt;br /&gt;
// Inputs/outputs&lt;br /&gt;
in vec2 texcoord;&lt;br /&gt;
&lt;br /&gt;
// Custom uniforms (defined in the .eff file)&lt;br /&gt;
uniform sampler2D color_tex;&lt;br /&gt;
&lt;br /&gt;
// Predefined uniforms (from C++)&lt;br /&gt;
uniform mat4 fg_ProjectionMatrix;&lt;br /&gt;
&lt;br /&gt;
// Constants&lt;br /&gt;
const float MY_CONSTANT = 1.0;&lt;br /&gt;
&lt;br /&gt;
// Function signatures of linked shader libraries&lt;br /&gt;
float M_PI();&lt;br /&gt;
&lt;br /&gt;
// Local functions&lt;br /&gt;
vec3 my_local_function(in vec3 input, out vec3 output)&lt;br /&gt;
{&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ENTRY POINT&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
#ifdef MY_OWN_DEFINE&lt;br /&gt;
    // ...&lt;br /&gt;
#else&lt;br /&gt;
    // ...&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core developer documentation]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Shader_programming_in_FlightGear&amp;diff=139080</id>
		<title>Howto:Shader programming in FlightGear</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Shader_programming_in_FlightGear&amp;diff=139080"/>
		<updated>2024-02-07T13:03:19Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP|More to follow}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are creating a shader from scratch, you should follow the [[Shader Style Guide]].&lt;br /&gt;
&lt;br /&gt;
This is meant to become an introduction to '''shader programming in FlightGear''', for the time being (03/2010), this is work in progress, please feel free to ask questions or suggest topics.&lt;br /&gt;
&lt;br /&gt;
Your help in improving and updating this article is appreciated, thanks!&lt;br /&gt;
&lt;br /&gt;
Tutorials about GLSL Programming in general are collected at [[GLSL Shader Programming Resources]].&lt;br /&gt;
&lt;br /&gt;
For an OpenGL quick reference, please see: http://www.khronos.org/files/opengl-quick-reference-card.pdf for an GLSL quick reference see [http://www-evasion.imag.fr/Membres/Sebastien.Barbier/Enseignement/glsl_quickref.pdf glsl_quickref.pdf]&lt;br /&gt;
&lt;br /&gt;
== What is GLSL? ==&lt;br /&gt;
''GLSL'' (''OpenGL Shading Language'' or &amp;quot;GLslang&amp;quot;) is the official OpenGL shading language and allows you to write programs, so called &amp;quot;shaders&amp;quot; in a high level shading language that is based on the C programming language to create OpenGL fragment (pixel) and vertex shaders.&lt;br /&gt;
&lt;br /&gt;
With the recent advances in graphics cards, new features have been added to allow for increased flexibility in the rendering pipeline at the vertex and fragment level. Programmability at this level is achieved with the use of fragment and vertex shaders.&lt;br /&gt;
&lt;br /&gt;
GLSL was created to give developers more direct control of the graphics pipeline without having to use assembly language or hardware-specific languages. Shaders provide the possibility to process individual vertices or fragments individually, so that complex rendering tasks can be accomplished without stressing the CPU. Support for shader was first introduced via extensions in OpenGL 1.5, but is now part of the core OpenGL 2.0 standard.&lt;br /&gt;
&lt;br /&gt;
Shaders are written and stored as plain text files, which can be uploaded (as strings) and executed on the GPU (processor of the graphics card).&lt;br /&gt;
&lt;br /&gt;
== What is a shader? ==&lt;br /&gt;
A ''shader'' is a programmable replacement for parts of the fixed OpenGL function pipeline, you can imagine it sort of like a &amp;quot;plugin&amp;quot; to customize rendering for specific scene elements.&lt;br /&gt;
&lt;br /&gt;
GLSL shaders are not stand-alone applications; they require an application that utilizes the OpenGL API. &lt;br /&gt;
A shader is a program, to be run it must be loaded, compiled and linked. &lt;br /&gt;
Shaders will be compiled when the 3D application starts. They will be validated and optimized for the current hardware.&lt;br /&gt;
&lt;br /&gt;
Actually each vertex and fragment shader must have one entry point (the main function) each, but you can create and link more shaders.&lt;br /&gt;
&lt;br /&gt;
GLSL shaders themselves are simply a set of strings that are passed to the hardware vendors driver for compilation from within an application using the OpenGL APIs entry points. Shaders can be created on the fly from within an application or read in as text files, but must be sent to the driver in the form of a string. &lt;br /&gt;
&lt;br /&gt;
GLSL has explicit ties to the OpenGL API - to the extent that much of the OpenGL &amp;quot;state&amp;quot; (for example which light sources are bound, what material properties are currently set up) is presented as pre-defined global variables in GLSL.&lt;br /&gt;
&lt;br /&gt;
Shaders offer:&lt;br /&gt;
* Opportunity for Improved Visual Quality&lt;br /&gt;
* Algorithm Flexibility&lt;br /&gt;
* Performance Benefits&lt;br /&gt;
&lt;br /&gt;
Shaders have access to textures and the render state (parameters, matrices, lights, materials etc).&lt;br /&gt;
A &amp;quot;pass&amp;quot; is the rendering of a 3D Model with a vertex and pixel shader pair.&lt;br /&gt;
An effect can require multiple passes, while each pass can use a different shader and/or model pair.&lt;br /&gt;
A Pass can render to a texture (to be used by another pass). Think of the &amp;quot;fixed functionality&amp;quot; as the default Shader.&lt;br /&gt;
&lt;br /&gt;
To make it simple, a shader is a program that is loaded on the GPU and called for every vertex or pixel: this gives programmers the possibility to implement techniques and visual effects and execute them faster. In modern games or simulators lots of shaders are used: lights, water, skinning, reflections and much more. &lt;br /&gt;
&lt;br /&gt;
We can create as many shader programs as needed.  You can have many shaders of the same type (vertex or fragment) attached to the same program, but only one of them can define the entry point — the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
Each Shader program is assigned an handler, and you can have as many programs linked and ready to use as you want (and your hardware allows).&lt;br /&gt;
Once rendering, we can switch from program to program, and even go back to fixed functionality during a single frame. &lt;br /&gt;
&lt;br /&gt;
To really understand shaders, you should have a knowledge about the rendering pipeline; this helps to understand where and when the shaders act in the rendering process. In general, you must know that vertex are collected, processed by vertex shaders, primitives are built, then are applied colors, textures and are also called fragment shaders; finally it comes to the rasterization and the frame is put on the buffer. &lt;br /&gt;
&lt;br /&gt;
Some benefits of using GLSL are:&lt;br /&gt;
* Cross platform compatibility on multiple operating systems, including Linux, Mac OS and Windows.&lt;br /&gt;
* The ability to write shaders that can be used on any hardware vendor’s graphics card that supports the OpenGL Shading Language.&lt;br /&gt;
* Each hardware vendor includes the GLSL compiler in their driver, thus allowing each vendor to create code optimized for their particular graphics cards architecture.&lt;br /&gt;
&lt;br /&gt;
== Language features ==&lt;br /&gt;
While GLSL has a C-Like syntax, it introduces some new types and keywords. To get a detailed view of the language, please see the GLSL specification you can find on http://www.opengl.org/documentation/glsl/&lt;br /&gt;
&lt;br /&gt;
The OpenGL Shading Language provides many operators familiar to those with a background in using the C programming language. This gives shader developers flexibility when writing shaders. GLSL contains the operators in C and C++, with the exception of pointers. Bitwise operators were added in version 1.30.&lt;br /&gt;
&lt;br /&gt;
Similar to the C programming language, GLSL supports loops and branching, including &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;for&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;do-while&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;break&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;continue&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
User defined functions are supported, and a wide variety of commonly used functions are provided built-in as well. This allows the graphics card manufacturer the ability to optimize these built-in functions at the hardware level if they are inclined to do so. Many of these functions are similar to those found in the math library of the C programming language such as &amp;lt;code&amp;gt;exp()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;abs()&amp;lt;/code&amp;gt; while others are specific to graphics programming such as &amp;lt;code&amp;gt;smoothstep()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;texture2D()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Error Reports, Debugging, Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
Shaders are compiled at FG startup.&lt;br /&gt;
&lt;br /&gt;
Shader compilation errors can be found in the fgfs.log file.  More about the [[Commonly_used_debugging_tools#fgfs.log|fgfs.log here]].&lt;br /&gt;
&lt;br /&gt;
As of FG 2016.4.4, shaders do not seem to recompile upon Debug/Reload Aircraft Model or File/Reset. So the only option to re-compile/test a shader is to quit a re-start FG altogether.&lt;br /&gt;
&lt;br /&gt;
== Shader types ==&lt;br /&gt;
There are two types of shaders in GLSL: ''vertex shaders'' and ''fragment shaders'' (with geometry shaders being a part of OpenGL 3.2).&lt;br /&gt;
&lt;br /&gt;
These are executed by vertex and fragment processors in the graphics hardware.&lt;br /&gt;
&lt;br /&gt;
* Vertex shaders transform vertices, set up data for fragment shaders&lt;br /&gt;
* Fragment shaders operate on fragments generated by rasterization&lt;br /&gt;
* Geometry shaders create geometry on the GPU&lt;br /&gt;
&lt;br /&gt;
Typically, vertex shader files use the file extension &amp;lt;code&amp;gt;.vert&amp;lt;/code&amp;gt;, while fragment shader files use the &amp;lt;code&amp;gt;.frag&amp;lt;/code&amp;gt; extension. &lt;br /&gt;
In FlightGear, these files can be found in the &amp;lt;code&amp;gt;Shaders&amp;lt;/code&amp;gt; subdirectory of the base package, in essence &amp;lt;code&amp;gt;$FG_ROOT/Shaders&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For a list of currently available shaders, you may want to take a look at: {{fg root file|Shaders}}.&lt;br /&gt;
&lt;br /&gt;
So, shaders generally go around in pairs - one shader (the ''vertex shader'') is a short program that takes in one vertex from the main CPU and produces one vertex that is passed on to the GPU rasterizer which uses the vertices to create triangles - which it then chops up into individual pixel-sized fragments. &lt;br /&gt;
&lt;br /&gt;
A vertex shader is run once per vertex, while a fragment shader is run once per fragment covered by the primitive being rendered (a point, a line or a triangle). A fragment equate a pixel except in the case of multi-sampling where a pixel can be the weighted average of several fragments. Multi-sampling is used to remove aliasing and jagged edges.&lt;br /&gt;
Many such executions can happen in parallel. There is no communication or ordering between executions. Vertex shaders are flexible and quick.&lt;br /&gt;
&lt;br /&gt;
=== Vertex shaders ===&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |The vertex shader doesn't know anything about the mesh it renders, it just knows one single vertex at a time and all the info that is attached to the vertex (normals, tangents, binormals, color,...)  And the vertex shader doesn't really draw anything, it just takes care of all the things which have to do with 'where in space' you are.&lt;br /&gt;
The way this works is that for all the vertices of an object you want to render, the position of the object gets attached to all vertices (currently in the color spot). The vertex shader then just adds the offset vector to the vertex coordinate with respect to the origin.&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/32326487/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] cities in FG &amp;amp; how to move forward&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Renk Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2014-05-11&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Input&lt;br /&gt;
| Vertex attributes&lt;br /&gt;
|-&lt;br /&gt;
! Output&lt;br /&gt;
| At least vertex position (in the clip space)&lt;br /&gt;
|-&lt;br /&gt;
! Restrictions&lt;br /&gt;
| Cannot access any vertex other than the current one&lt;br /&gt;
|-&lt;br /&gt;
! ''Note''&lt;br /&gt;
| ''Loading a vertex shader turns off parts of the OpenGL pipeline (vertex shaders fully replace the &amp;quot;Texturing &amp;amp; Lighting unit&amp;quot;).''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Objects in a computer graphics scene are usually meshes that are made up of polygons. The corner of each of those polygons is called a ''vertex''.&lt;br /&gt;
A vertex shader receives input in the form of per-vertex variables called ''attribute variables'', and per-polygon variables called ''uniform variables''.&lt;br /&gt;
The vertex shader must specify the coordinates of the vertex in question. This way, the geometry of the object can be modified. &lt;br /&gt;
&lt;br /&gt;
Vertex shaders operate on each vertex, the vertex shader is executed for every vertex related OpenGL call (for example &amp;lt;code&amp;gt;glVertex*&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;glDrawArrays&amp;lt;/code&amp;gt;).&lt;br /&gt;
Accordingly, this means for example, that for meshes that contain for example 5000 vertices, the vertex shader will also be executed 5000 times.&lt;br /&gt;
&lt;br /&gt;
A single vertex itself is composed of a number of ''attributes'' (vertex attrib), such as: position, texture coordinates, normal and color for the most common. &lt;br /&gt;
The position (attribute) is the most important one. The coordinates (x, y and z) of the vertex's entering position are those which have been given by the 3D modeler during the creation of the 3D model. The vertex's position is defined in the local space of the mesh (or object space). &lt;br /&gt;
&lt;br /&gt;
A vertex shader provides almost full control over what is happening with each vertex. Consequently, all per-vertex operations of the fixed function OpenGL pipeline are replaced by the custom vertex shader. &lt;br /&gt;
&lt;br /&gt;
Vertex shaders take application geometry and per-vertex attributes as input and transform the input data in some meaningful way.&lt;br /&gt;
&lt;br /&gt;
* A vertex shader '''must''' write to &amp;lt;code&amp;gt;gl_Position&amp;lt;/code&amp;gt;&lt;br /&gt;
* A vertex shader '''can''' write to &amp;lt;code&amp;gt;gl_PointSize&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;gl_ClipVertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_Vertex&amp;lt;/code&amp;gt; is an attribute supplying the untransformed vertex coordinate&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_Position&amp;lt;/code&amp;gt; is an special output variable for the transformed vertex coordinate&lt;br /&gt;
&lt;br /&gt;
A vertex shader can also set other variables which are called ''varying variables''.&lt;br /&gt;
The values of these variables are passed on to the second kind of shader, the ''fragment shader''. &lt;br /&gt;
The fragment shader is run for every pixel on the screen where the polygons of the mesh appear. The fragment shader is responsible for setting the final color of that little piece of the mesh&lt;br /&gt;
&lt;br /&gt;
Common tasks for a vertex shader include:&lt;br /&gt;
* Vertex position transformation&lt;br /&gt;
* Per vertex lighting&lt;br /&gt;
* Normal transformation&lt;br /&gt;
* Texture coordinates transformation or generation&lt;br /&gt;
* Vertex color computation&lt;br /&gt;
* Geometry skinning&lt;br /&gt;
* Animation&lt;br /&gt;
* Setting up data for fragment shaders&lt;br /&gt;
&lt;br /&gt;
The vertex shader runs from start to end for each and every vertex that's passed into the graphics card – the fragment process does the same thing at the pixel level. In most scenes there are a heck of a lot more pixel fragments than there are vertices – so the performance of the fragment shader is vastly more important and any work we can do in the vertex shader, we probably should. &lt;br /&gt;
&lt;br /&gt;
A minum vertex shader example may looks this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
  gl_Position = ftransform();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fragment shaders ===&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |the fragment shader basically knows only the pixel it is about to render and whatever information is passed from the vertex shader. Based on 'where' the vertex shader says the pixel is, the rasterizer stage determines what the texture for the pixel should be. &lt;br /&gt;
But there are techniques to do this in a different way, for instance the water depth map uses world coordinates to look up a world texture, and the gardens would have to be drawn in a similar way.&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/32326487/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] cities in FG &amp;amp; how to move forward&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Renk Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2014-05-11&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Input&lt;br /&gt;
| Interpolation of the vertex shader outputs&lt;br /&gt;
|-&lt;br /&gt;
! Output&lt;br /&gt;
| Usually a fragment color.&lt;br /&gt;
|-&lt;br /&gt;
! Restrictions&lt;br /&gt;
| Fragment shaders have no knowledge of neighboring pixels.&lt;br /&gt;
|-&lt;br /&gt;
! ''Note''&lt;br /&gt;
| ''Loading a fragment shader turns off parts of the OpenGL pipeline (pixel shaders fully replace the &amp;quot;Texturing Unit&amp;quot;).''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The other shader (the ''fragment shader'' - also (incorrectly) known as the &amp;quot;pixel shader&amp;quot;) takes one pixel from the rasterizer and generates one pixel to write or blend into the frame buffer. &lt;br /&gt;
&lt;br /&gt;
A fragment shader can write to the following special output variables:&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_FragColor&amp;lt;/code&amp;gt; to set the color of the fragment&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_FragData[n]&amp;lt;/code&amp;gt; to output to a specific render target&lt;br /&gt;
* &amp;lt;code&amp;gt;gl_FragDepth&amp;lt;/code&amp;gt; to set the fragment depth&lt;br /&gt;
&lt;br /&gt;
Common tasks of fragment shaders include:&lt;br /&gt;
* Texturing (even procedural)&lt;br /&gt;
* Per pixel lighting and material application&lt;br /&gt;
* Ray tracing&lt;br /&gt;
* Fragment color computation&lt;br /&gt;
* Operations on Interpolated Values&lt;br /&gt;
* Doing operations per fragment to make pretty pictures&lt;br /&gt;
&lt;br /&gt;
A minimum fragment shader may look like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A fragment shader takes perspective-correct interpolated attribute values as input and either discards the fragment or outputs the fragment's color.&lt;br /&gt;
&lt;br /&gt;
Fragment shaders operate on every fragment which is produced by rasterization. Fragment shaders give you nearly full control over what is happening with each fragment. However just like vertex shaders, a fragment shader replaces all per-fragment operations of the fixed function OpenGL pipeline.&lt;br /&gt;
&lt;br /&gt;
== Data types in GLSL ==&lt;br /&gt;
Note that there is no implicit type conversion in GLSL, all conversions and initializations have to be done using explicit constructor calls!&lt;br /&gt;
&lt;br /&gt;
=== Scalars ===&lt;br /&gt;
* &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; – 32 bit, very nearly IEEE-754 compatible&lt;br /&gt;
* &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; – at least 16 bit, but not backed by a fixed-width register&lt;br /&gt;
* &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; – like C++, but must be explicitly used for all flow control&lt;br /&gt;
&lt;br /&gt;
=== Vectors ===&lt;br /&gt;
* &amp;lt;code&amp;gt;vec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec4&amp;lt;/code&amp;gt; – 2D, 3D and 4D floating point vector&lt;br /&gt;
* &amp;lt;code&amp;gt;ivec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ivec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ivec4&amp;lt;/code&amp;gt; – 2D, 3D and 4D integer vector&lt;br /&gt;
* &amp;lt;code&amp;gt;bvec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bvec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bvec4&amp;lt;/code&amp;gt; – 2D, 3D and 4D boolean vectors&lt;br /&gt;
&lt;br /&gt;
Accessing a vector can be done using letters as well as standard C selectors.&lt;br /&gt;
&lt;br /&gt;
TODO: explain swizzling&lt;br /&gt;
&lt;br /&gt;
One can use the letters x,y,z,w to access vectors components; r,g,b,a for color components; and&lt;br /&gt;
s,t,p,q for texture coordinates.&lt;br /&gt;
&lt;br /&gt;
=== Matrices ===&lt;br /&gt;
* &amp;lt;code&amp;gt;mat2&amp;lt;/code&amp;gt; – 2x2 floating point matrix&lt;br /&gt;
* &amp;lt;code&amp;gt;mat3&amp;lt;/code&amp;gt; – 3x3 floating point matrix&lt;br /&gt;
* &amp;lt;code&amp;gt;mat4&amp;lt;/code&amp;gt; – 4x4 floating potint matrix	&lt;br /&gt;
&lt;br /&gt;
=== Samplers ===&lt;br /&gt;
In GLSL, textures are represented and accessed using so called &amp;quot;samplers&amp;quot;, which are used for sampling textures and which have to be uniform. The following samplers are available:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;sampler1D&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sampler2D&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sampler3D&amp;lt;/code&amp;gt; – 1D, 2D and 3D texture&lt;br /&gt;
* &amp;lt;code&amp;gt;samplerCube&amp;lt;/code&amp;gt; – Cube Map texture&lt;br /&gt;
* &amp;lt;code&amp;gt;sampler1Dshadow&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sampler2Dshadow&amp;lt;/code&amp;gt; – 1D and 2D depth-component texture&lt;br /&gt;
&lt;br /&gt;
=== Arrays ===&lt;br /&gt;
GLSL supports the same syntax for creating arrays that is already known from C or C++, e.g.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec2 foo[10];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, arrays can be declared using the same syntax as in C, but can't be initialized when declared. Accessing array's elements is done as in C.&lt;br /&gt;
&lt;br /&gt;
=== Structures ===&lt;br /&gt;
Structures can also be created like in C or C++, e.g.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct foo {&lt;br /&gt;
  vec3 pos;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Global storage qualifiers ==&lt;br /&gt;
Used for communication between shaders and application:&lt;br /&gt;
* &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; – For declaring non-writable, compile-time constant variables&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute&amp;lt;/code&amp;gt; – For frequently changing (per vertex) information passed from the application to a vertex shader (no integers, bools, structs, or arrays)&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform&amp;lt;/code&amp;gt; – For infrequently changing (per primitive) information passed from the application to a vertex or fragment shader:constant shader parameters that can be changed between draws (cannot be written to in a shader, do not change per-vertex or per-fragment)&lt;br /&gt;
* &amp;lt;code&amp;gt;varying&amp;lt;/code&amp;gt; – For information passed from a vertex shader to a fragment shader, will be interpolated in a perspective-correct manner during rasterization (can write in vertex shader, but only read in fragment shader)&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
* Much like C++&lt;br /&gt;
* Entry point into a shader is &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Overloading based on parameter type (but not return type)&lt;br /&gt;
* No support for direct or indirect recursion&lt;br /&gt;
* Call by value-return calling convention&lt;br /&gt;
&lt;br /&gt;
As in C, a shader is structured in functions. At least each type of shader must have a main function declared with the following syntax: &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt;&lt;br /&gt;
User defined functions may be defined. As in C a function may have a return value, and use the return statement to pass out its result. A function can be void. The return type can have any type, except array.&lt;br /&gt;
&lt;br /&gt;
=== Parameter qualifiers ===&lt;br /&gt;
The parameters of a function may have the following qualifiers:&lt;br /&gt;
* &amp;lt;code&amp;gt;in&amp;lt;/code&amp;gt; – Copy in, but don't copy back out (still writable within function)&lt;br /&gt;
* &amp;lt;code&amp;gt;out&amp;lt;/code&amp;gt; – Only copy out; undefined at function entry point&lt;br /&gt;
* &amp;lt;code&amp;gt;inout&amp;lt;/code&amp;gt; – Copy in and copy out&lt;br /&gt;
&lt;br /&gt;
If no qualifier is specified, by default it is considered to be in.&lt;br /&gt;
&lt;br /&gt;
== Built-ins ==&lt;br /&gt;
=== Vertex shader ===&lt;br /&gt;
* &amp;lt;code&amp;gt;vec4 gl_Position;&amp;lt;/code&amp;gt; – '''Must''' be written&lt;br /&gt;
* &amp;lt;code&amp;gt;vec4 gl_ClipPosition;&amp;lt;/code&amp;gt; – May be written&lt;br /&gt;
* &amp;lt;code&amp;gt;float gl_PointSize;&amp;lt;/code&amp;gt; – May be written&lt;br /&gt;
&lt;br /&gt;
=== Fragment shader ===&lt;br /&gt;
* &amp;lt;code&amp;gt;float gl_FragColor;&amp;lt;/code&amp;gt; – May be written&lt;br /&gt;
* &amp;lt;code&amp;gt;float gl_FragDepth;&amp;lt;/code&amp;gt; – May be read/written&lt;br /&gt;
* &amp;lt;code&amp;gt;vec4 gl_FragCoord;&amp;lt;/code&amp;gt; – May be read&lt;br /&gt;
* &amp;lt;code&amp;gt;bool gl_FrontFacing;&amp;lt;/code&amp;gt; – May be read&lt;br /&gt;
&lt;br /&gt;
=== Vertex attributes ===&lt;br /&gt;
Only available in vertex shaders.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_Vertex;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec3 gl_Normal;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_Color;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_SecondaryColor;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute vec4 gl_MultiTexCoordn;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;attribute float gl_FogCoord;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Uniforms ===&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_ModelViewMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_ProjectionMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_ModelViewProjectionMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat3 gl_NormalMatrix;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform mat4 gl_TextureMatrix[n];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters {&lt;br /&gt;
  vec4 emission;&lt;br /&gt;
  vec4 ambient;&lt;br /&gt;
  vec4 diffuse;&lt;br /&gt;
  vec4 specular;&lt;br /&gt;
  float shininess;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform gl_MaterialParameters gl_FrontMaterial;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform gl_MaterialParameters gl_BackMaterial;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters {&lt;br /&gt;
  vec4 ambient;&lt;br /&gt;
  vec4 diffuse;&lt;br /&gt;
  vec4 specular;&lt;br /&gt;
  vec4 position;&lt;br /&gt;
  vec4 halfVector;&lt;br /&gt;
  vec3 spotDirection;&lt;br /&gt;
  float spotExponent;&lt;br /&gt;
  float spotCutoff;&lt;br /&gt;
  float spotCosCutoff;&lt;br /&gt;
  float constantAttenuation&lt;br /&gt;
  float linearAttenuation&lt;br /&gt;
  float quadraticAttenuation&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Varyings ===&lt;br /&gt;
An interface between vertex and fragment shaders is provided by varying variables: Vertex shaders compute values per vertex and fragment shaders compute values per fragment. &lt;br /&gt;
The value of a varying variable defined in a vertex shader, will be interpolated (perspective-correct) over the primitive being rendered and the interpolated value in the fragment shader can be accessed.&lt;br /&gt;
&lt;br /&gt;
Varying variables can only be used with the data types &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vec4&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mat2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mat3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mat4&amp;lt;/code&amp;gt;. (and arrays of them too.)&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_FrontColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_BackColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_FrontSecColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_BackSecColor; // vertex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_Color; // fragment&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_SecondaryColor; // fragment&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying vec4 gl_TexCoord[]; // both&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;varying float gl_FogFragCoord; // both&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
== Anatomy of a shader ==&lt;br /&gt;
A shader's entry point is the main function which returns void and takes no arguments (void)&lt;br /&gt;
&lt;br /&gt;
=== Anatomy of a vertex shader ===&lt;br /&gt;
The function &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt; is called afresh for each vertex in the 3D object model:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
// Vertex Shader&lt;br /&gt;
void main() {&lt;br /&gt;
  gl_Position = gl_Vertex;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anatomy of a fragment shader ===&lt;br /&gt;
The function &amp;lt;code&amp;gt;void main()&amp;lt;/code&amp;gt; is called afresh for each fragment/pixel in the 3D object model:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
// Fragment Shader&lt;br /&gt;
void main() {&lt;br /&gt;
  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Practical application – ALS landing lights – spotlight ==&lt;br /&gt;
[[File:ALS Secondary Light Proof of Concept.png|thumb|300px|ALS secondary light proof of concept]]&lt;br /&gt;
[[File:Als Secondary Lights combined with Fog Effect.jpg|thumb|300px|Weather settings to produce fog and ALS landing lights on a runway.]]&lt;br /&gt;
[[File:Model on Water and Trees on Land.jpg|thumb|300px|Model on water and trees on land ALS lights effect]]&lt;br /&gt;
[[File:Model on Water.jpg|thumb|300px|ALS lights effect over model and water.]]&lt;br /&gt;
[[File:ALS Lights over Model and Terrain.jpg|thumb|300px|ALS lights over model and terrain]]&lt;br /&gt;
&lt;br /&gt;
The ALS landing lights-spotlight (we'll call it ALS lights from now on) is a good example for showing how to incorporate a shader effect into FlightGear as it touches many parts of the visuals we see and many parts of the coding pipeline.&lt;br /&gt;
&lt;br /&gt;
In the case of ALS Lights, you have to add the effect to every visual item rendered on the screen that you want to see a light shining on. If you want it to be capable of shining on everything, you have to account for each separate item and how that item is rendered.  That is a lot of code to touch.&lt;br /&gt;
&lt;br /&gt;
The list might include&lt;br /&gt;
* Terrain&lt;br /&gt;
** Runway&lt;br /&gt;
** Dirtrunway&lt;br /&gt;
** Agriculture&lt;br /&gt;
* Models&lt;br /&gt;
** AI&lt;br /&gt;
** Aircraft&lt;br /&gt;
** Tree&lt;br /&gt;
** Buildings&lt;br /&gt;
* Weather&lt;br /&gt;
** Fog&lt;br /&gt;
** Clouds&lt;br /&gt;
** Hazes&lt;br /&gt;
* Water&lt;br /&gt;
** Inland&lt;br /&gt;
** Ocean&lt;br /&gt;
** Stream&lt;br /&gt;
&lt;br /&gt;
Some of these items may be controlled or rendered by the same effect and shader file. They might have to be accounted for individually. They may have special lighting influences that have to be accounted for. You have to take each one separately and account for all its needs. &lt;br /&gt;
&lt;br /&gt;
The example highlighted in this article is what was added to &amp;lt;code&amp;gt;tree.eff&amp;lt;/code&amp;gt; to shine the lights on trees.&lt;br /&gt;
&lt;br /&gt;
=== Program flow simplified ===&lt;br /&gt;
Preferences/Nasal/XML → Property tree → Effect file → Shader → Rendered to screen&lt;br /&gt;
&lt;br /&gt;
=== Preferences/Nasal/XML ===&lt;br /&gt;
Any combination of Preferences, [[Nasal|Nasal]] or [[Xml|XML]] manipulates data in the [[Property Tree|property tree]]. &lt;br /&gt;
In this case the switch to turn on the landing or spot light and a couple other needed data containers are defined in &amp;lt;code&amp;gt;$FG_ROOT/preferences.xml&amp;lt;/code&amp;gt; with the following lines.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;als-secondary-lights&amp;gt;&lt;br /&gt;
 &amp;lt;use-searchlight type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/use-searchlight&amp;gt;&lt;br /&gt;
 &amp;lt;use-landing-light type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/use-landing-light&amp;gt;&lt;br /&gt;
 &amp;lt;use-alt-landing-light type=&amp;quot;bool&amp;quot;&amp;gt;false&amp;lt;/use-alt-landing-light&amp;gt;&lt;br /&gt;
 &amp;lt;landing-light1-offset-deg type=&amp;quot;float&amp;quot;&amp;gt;0.0&amp;lt;/landing-light1-offset-deg&amp;gt;&lt;br /&gt;
 &amp;lt;landing-light2-offset-deg type=&amp;quot;float&amp;quot;&amp;gt;0.0&amp;lt;/landing-light2-offset-deg&amp;gt;&lt;br /&gt;
&amp;lt;/als-secondary-lights&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They show up in the property tree under &amp;lt;code&amp;gt;sim/rendering/als-secondary-lights&amp;lt;/code&amp;gt; and can be activated or manipulated by normal Nasal calls or XML.&lt;br /&gt;
&lt;br /&gt;
=== Property tree ===&lt;br /&gt;
The [[Property Tree|property tree]] is like the CPU of the [[FlightGear]] program at a user level. It's a go-between that allows the user to see and influence many aspects at the heart of the program in ALMOST real time. More of the internals of FlightGear are being exposed to the property tree than ever before. This allows us to have user level access in areas of the code that used to only be reserved for [[Programming Resources|programmers]]. Because of the manner in which the property tree is fed information, and the one step removed from the C source, care must be taken in how it is used. Depending on how it is used it won't be as responsive to manipulation as it would be if you were to change the same information at the C source level. &lt;br /&gt;
 &lt;br /&gt;
=== Effects file ===&lt;br /&gt;
The effects file is the mechanism we use to combine and manipulate all the necessary data to create stunning visual effects. It's the link between the data contained and produced in Nasal, XML and the property tree and the graphics rendering pipeline. It's there to allow us to create these affects without having to know or use the C++ code base. Its flexible framework allows for an almost infinite range of sophisticated effects.&lt;br /&gt;
&lt;br /&gt;
See this page for more details: [[Effect Framework]]&lt;br /&gt;
&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
Parameter entries defined in the Effect file correspond to a property tree data container (static or variable). They will contain the data needed by the shader program to perform its magic. The type of information contained in the property tree might be program control data or variable/static data that the shader program can manipulate prior to sending on to render.&lt;br /&gt;
In the case of ALS lights, below is some of the data passed to, and used by, the shader program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
 &amp;lt;display_xsize&amp;gt;&amp;lt;use&amp;gt;/sim/startup/xsize&amp;lt;/use&amp;gt;&amp;lt;/display_xsize&amp;gt;&lt;br /&gt;
 &amp;lt;display_ysize&amp;gt;&amp;lt;use&amp;gt;/sim/startup/ysize&amp;lt;/use&amp;gt;&amp;lt;/display_ysize&amp;gt;&lt;br /&gt;
 &amp;lt;view_pitch_offset&amp;gt;&amp;lt;use&amp;gt;/sim/current-view/pitch-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/view_pitch_offset&amp;gt;&lt;br /&gt;
 &amp;lt;view_heading_offset&amp;gt;&amp;lt;use&amp;gt;/sim/current-view/heading-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/view_heading_offset&amp;gt;&lt;br /&gt;
 &amp;lt;view_fov&amp;gt;&amp;lt;use&amp;gt;/sim/current-view/field-of-view&amp;lt;/use&amp;gt;&amp;lt;/view_fov&amp;gt;&lt;br /&gt;
 &amp;lt;use_searchlight&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/use-searchlight&amp;lt;/use&amp;gt;&amp;lt;/use_searchlight&amp;gt;&lt;br /&gt;
 &amp;lt;use_landing_light&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/use-landing-light&amp;lt;/use&amp;gt;&amp;lt;/use_landing_light&amp;gt;&lt;br /&gt;
 &amp;lt;use_alt_landing_light&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/use-alt-landing-light&amp;lt;/use&amp;gt;&amp;lt;/use_alt_landing_light&amp;gt;&lt;br /&gt;
 &amp;lt;landing_light1_offset&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/landing-light1-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/landing_light1_offset&amp;gt;&lt;br /&gt;
 &amp;lt;landing_light2_offset&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/als-secondary-lights/landing-light2-offset-deg&amp;lt;/use&amp;gt;&amp;lt;/landing_light2_offset&amp;gt;&lt;br /&gt;
 &amp;lt;quality_level&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/shaders/landmass&amp;lt;/use&amp;gt;&amp;lt;/quality_level&amp;gt;&lt;br /&gt;
 &amp;lt;tquality_level&amp;gt;&amp;lt;use&amp;gt;/sim/rendering/shaders/transition&amp;lt;/use&amp;gt;&amp;lt;/tquality_level&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;use-searchlight&amp;lt;/code&amp;gt; entry, it is pointing to the use-searchlight entry in the property tree under &amp;lt;code&amp;gt;sim/rendering/als-secondary-lights&amp;lt;/code&amp;gt; that was defined in &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Some of this data may play a duel role inside the shader program. In other words it might be used to control other functions in addition to ALS lights.&lt;br /&gt;
There will also be other parameter entries that have nothing to do with ALS lights. They might be used for other actions or effects the shader is handling. &lt;br /&gt;
&lt;br /&gt;
==== Technique ====&lt;br /&gt;
In general, the shader program and the uniforms are defined in between the technique tags. The technique is assigned an index to distinguish one technique from another (technique n=&amp;quot;1&amp;quot;). As is the case with tree.eff, sometimes the shader program and its uniforms are defined and needed in more than one technique. In the case of &amp;lt;code&amp;gt;tree.eff&amp;lt;/code&amp;gt; it is used in technique 4 and 5. Which means in FlightGear, the tree shader set to either of the the highest two shader settings still produces ALS lights when activated.&lt;br /&gt;
&lt;br /&gt;
==== Shader program ====&lt;br /&gt;
Next comes the entry to define what shader program the parameters data is going to be passed to.&lt;br /&gt;
This is where you specify what shader program is to be used by the technique. ALS has the lowest techniques, with higher quality preceding lower quality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
 &amp;lt;fragment-shader&amp;gt;Shaders/tree-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
 &amp;lt;fragment-shader&amp;gt;Shaders/secondary_lights.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In the case of ALS Lights, so far we only have to deal with the fragment shader.&lt;br /&gt;
&lt;br /&gt;
The program section of the effect file is a nifty method used to allow users to add shaders to FlightGear without having to add code at C level language base. The C level base is programed to recognize the XML tag pair of &amp;lt;program&amp;gt;&amp;lt;/program&amp;gt; and thus incorporate the GLSL program files pointed to between the tags. Otherwise you would have to add the GLSL program calls in the base C requiring a completely different set of programing skills and also the necessity of compiling FlightGear everytime you want to add new shader. It can work this way because shader programs are compiled at run-time.&lt;br /&gt;
&lt;br /&gt;
We'll describe the contents of the shader programs below. For now, suffice it to say &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; contains the main program and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt; has functions that are passed uniform data that is manipulated and returned to main for processing.&lt;br /&gt;
&lt;br /&gt;
==== Uniforms ====&lt;br /&gt;
The uniforms section is the mechanism that feeds the parameter data to the shader program.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;view_pitch_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;view_pitch_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;view_heading_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;view_heading_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;field_of_view&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;view_fov&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;landing_light1_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;landing_light1_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;landing_light2_offset&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;float&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;landing_light2_offset&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;use_searchlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;use_searchlight&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;use_landing_light&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;use_landing_light&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;use_alt_landing_light&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;use_alt_landing_light&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;display_xsize&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;display_xsize&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
 &amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;display_ysize&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;int&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value&amp;gt;&amp;lt;use&amp;gt;display_ysize&amp;lt;/use&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
 &amp;lt;/uniform&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note the name, &amp;lt;code&amp;gt;use_searchlight&amp;lt;/code&amp;gt;, which was originally defined in &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt; and then became an entry in parameters is now being passed to the program shader by the uniform. Below in the &amp;quot;Shader program&amp;quot; section, we will show you how the shader receives the uniform's data.&lt;br /&gt;
&lt;br /&gt;
=== Shader programs ===&lt;br /&gt;
The shader programs used in this example are &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== secondary_lights.frag ===&lt;br /&gt;
&amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt; consists of&lt;br /&gt;
* Uniform inputs (data coming into the shader to be manipulated&lt;br /&gt;
* Functions that manipulate the uniform data&lt;br /&gt;
&lt;br /&gt;
Following it the actual GLSL code in &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Uniform input ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform int display_xsize;&lt;br /&gt;
uniform int display_ysize;&lt;br /&gt;
uniform float field_of_view;&lt;br /&gt;
uniform float view_pitch_offset;&lt;br /&gt;
uniform float view_heading_offset;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Functions ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float light_distance_fading(in float dist)&lt;br /&gt;
{&lt;br /&gt;
  return min(1.0, 10000.0/(dist*dist));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
float fog_backscatter(in float avisibility)&lt;br /&gt;
{&lt;br /&gt;
  return 0.5* min(1.0,10000.0/(avisibility*avisibility));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vec3 searchlight()&lt;br /&gt;
{&lt;br /&gt;
  vec2 center = vec2 (float(display_xsize) * 0.5, float(display_ysize) * 0.4);&lt;br /&gt;
  float headlightIntensity;  &lt;br /&gt;
  float lightRadius = (float(display_xsize) *9.16 /field_of_view);&lt;br /&gt;
  float angularDist = length(gl_FragCoord.xy -center);&lt;br /&gt;
  if (angularDist &amp;lt; lightRadius)&lt;br /&gt;
  {&lt;br /&gt;
    headlightIntensity = pow(cos(angularDist/lightRadius * 1.57075),2.0);&lt;br /&gt;
    //headlightIntensity = headlightIntensity * &lt;br /&gt;
    //headlightIntensity*= clamp(1.0 + 0.15 * log(1000.0/(dist*dist)),0.0,1.0);&lt;br /&gt;
    return  headlightIntensity * vec3 (0.5,0.5, 0.5);&lt;br /&gt;
  }&lt;br /&gt;
  else return vec3 (0.0,0.0,0.0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vec3 landing_light(in float offset)&lt;br /&gt;
{&lt;br /&gt;
  float fov_h = field_of_view;&lt;br /&gt;
  float fov_v = float(display_ysize)/float(display_xsize) * field_of_view; &lt;br /&gt;
  float yaw_offset;&lt;br /&gt;
  if (view_heading_offset &amp;gt; 180.0)&lt;br /&gt;
    {yaw_offset = -360.0+view_heading_offset;}&lt;br /&gt;
  else&lt;br /&gt;
    {yaw_offset = view_heading_offset;}&lt;br /&gt;
  float x_offset = (float(display_xsize) / fov_h * (yaw_offset + offset));&lt;br /&gt;
  float y_offset = -(float(display_ysize) / fov_v * view_pitch_offset);&lt;br /&gt;
  vec2 center = vec2 (float(display_xsize) * 0.5 + x_offset, float(display_ysize) * 0.4 + y_offset);&lt;br /&gt;
  float landingLightIntensity;  &lt;br /&gt;
  float lightRadius = (float(display_xsize) *9.16 /field_of_view);&lt;br /&gt;
  float angularDist = length(gl_FragCoord.xy -center);&lt;br /&gt;
  if (angularDist &amp;lt; lightRadius)&lt;br /&gt;
  {&lt;br /&gt;
    landingLightIntensity = pow(cos(angularDist/lightRadius * 1.57075),2.0);&lt;br /&gt;
    //landingLightIntensity *= min(1.0, 10000.0/(dist*dist));&lt;br /&gt;
    return  landingLightIntensity * vec3 (0.5,0.5, 0.5);&lt;br /&gt;
  }&lt;br /&gt;
  else return vec3 (0.0,0.0,0.0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tree-ALS.frag ===&lt;br /&gt;
&amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; consists of&lt;br /&gt;
* Uniform inputs (data coming into the shader to be manipulated&lt;br /&gt;
* Functions that manipulate the uniform data&lt;br /&gt;
&lt;br /&gt;
Following it the actual GLSL code in &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt;.&lt;br /&gt;
While there is significantly more code in &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt;, only the code that was included for the ALS lights is being shown and discussed here.&lt;br /&gt;
&lt;br /&gt;
==== Uniform input ====&lt;br /&gt;
Uniform data is brought into the shader in the following manner.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform float landing_light1_offset;&lt;br /&gt;
uniform float landing_light2_offset;&lt;br /&gt;
uniform int use_searchlight;&lt;br /&gt;
uniform int use_landing_light;&lt;br /&gt;
uniform int use_alt_landing_light;&lt;br /&gt;
uniform int quality_level;&lt;br /&gt;
uniform int tquality_level;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note &amp;lt;code&amp;gt;use_searchlight&amp;lt;/code&amp;gt; and how it is defined as incoming uniform data.&lt;br /&gt;
&lt;br /&gt;
==== Variable data ====&lt;br /&gt;
Variable data can be defined in the shader program. An example of variable data defined in the shader program that is needed for ALS lights is&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3 secondary_light = vec3 (0.0,0.0,0.0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Functions ====&lt;br /&gt;
Function calls to the function defined in &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt; are&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3 searchlight();&lt;br /&gt;
vec3 landing_light(in float offset);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You don't have to use any path information or includes in the code because the GLSL compiler program takes care of linking all the shader programs as long as they are defined correctly in the &amp;quot;programs&amp;quot; section of the effect file.&lt;br /&gt;
Variable data can be passed to and returned from GLSL functions just like any other language.&lt;br /&gt;
&lt;br /&gt;
==== Main program ====&lt;br /&gt;
The &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; function is the heart of the shader program. This is where the shader program manipulates all the data made available to it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  vec3 secondary_light = vec3 (0.0,0.0,0.0);&lt;br /&gt;
  if ((quality_level&amp;gt;5) &amp;amp;&amp;amp; (tquality_level&amp;gt;5))&lt;br /&gt;
  {&lt;br /&gt;
    if (use_searchlight == 1)&lt;br /&gt;
    {&lt;br /&gt;
      secondary_light += searchlight();&lt;br /&gt;
    }&lt;br /&gt;
    if (use_landing_light == 1)&lt;br /&gt;
    {&lt;br /&gt;
      secondary_light += landing_light(landing_light1_offset);&lt;br /&gt;
    }&lt;br /&gt;
    if (use_alt_landing_light == 1)&lt;br /&gt;
    {&lt;br /&gt;
      secondary_light += landing_light(landing_light2_offset);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  vec4 fragColor = vec4 (gl_Color.rgb +secondary_light * light_distance_fading(dist),1.0) * texel;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how &amp;lt;code&amp;gt;use_searchlight&amp;lt;/code&amp;gt; is used in the main function to determine if the property defined in &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt; and manipulated in the property tree is set to true or 1.&lt;br /&gt;
&lt;br /&gt;
Some of the variable data contained in the shader program is used for other purposes and is introduced into the shader program from other property, parameter and uniform definitions not pertaining to ALS lights.&lt;br /&gt;
&lt;br /&gt;
==== File list ====&lt;br /&gt;
Files that are directly touched by this effect include &lt;br /&gt;
* &amp;lt;code&amp;gt;preferences.xml&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;agriculture.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;crop&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;agriculture-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;airfield.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;airfield-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;building.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;model-combined-deferred&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;model-combined&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 4)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;model-ALS-ultra.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Inherits uniforms from &amp;lt;code&amp;gt;model-combined-deferred&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;model-combined&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;dirt-runway.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;crop&amp;lt;/code&amp;gt; &amp;lt;&amp;lt; &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;drunway-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;model-combined.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;model-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 4)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;model-ALS-ultra.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 4)&lt;br /&gt;
* &amp;lt;code&amp;gt;model-default.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Adds properties&lt;br /&gt;
** Adds program shaders (technique 5)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;model-ALS-base.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 5)&lt;br /&gt;
* &amp;lt;code&amp;gt;runway.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from terrain-default&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;runway-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;terrain-default.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Adds properties&lt;br /&gt;
** Adds program shaders (technique 3)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;terrain-ALS-ultra.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 3)&lt;br /&gt;
* &amp;lt;code&amp;gt;tree.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Adds properties&lt;br /&gt;
** Adds program shaders (technique 4 and 5)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;tree-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 4 and 5)&lt;br /&gt;
* &amp;lt;code&amp;gt;urban.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 1 and 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;urban-ALS.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 1 and 2)&lt;br /&gt;
* &amp;lt;code&amp;gt;water.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 1)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;water-ALS-high.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 1)&lt;br /&gt;
* &amp;lt;code&amp;gt;water-inland.eff&amp;lt;/code&amp;gt;:&lt;br /&gt;
** Inherits properties from &amp;lt;code&amp;gt;terrain-default&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds program shaders (technique 2)&lt;br /&gt;
*** Fragment &amp;lt;code&amp;gt;water-ALS-high.frag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;secondary_lights.frag&amp;lt;/code&amp;gt;&lt;br /&gt;
** Adds uniforms (technique 2)&lt;br /&gt;
&lt;br /&gt;
== General comments from forum discussion ==&lt;br /&gt;
{{cquote|In principle, we always do the same steps in the fragment shaders to determine the color of a pixel:&lt;br /&gt;
&lt;br /&gt;
* texel color - what is the base color of the pixel fully lit and unfogged&lt;br /&gt;
* lighting - how is this color changed by the light falling onto that pixel, usually the relation is something like fragColor equals texel * light&lt;br /&gt;
* fogging - how much is the color hidden by haze, usually the relation is something like gl_FragColor equals mix(fragColor, hazeColor, transmission_factor);&lt;br /&gt;
what is displayed on the screen in the end is whatever gl_FragColor is set to&lt;br /&gt;
&lt;br /&gt;
But the location where this happens isn't always obvious - often (part) of the light is computed in the vertex shader already, in which case it typically enters the fragment shader as gl_Color.&lt;br /&gt;
&lt;br /&gt;
So, the lighting equation in tree-haze.frag is indeed&lt;br /&gt;
vec4 fragColor equals vec4 (gl_Color.xyz,1.0) * texel;&lt;br /&gt;
and your change to the light should happen just before that. But you can't do&lt;br /&gt;
gl_Color.rgb equals gl_Color.rgb + my_light;&lt;br /&gt;
because gl_Color.rgb is a varying variable type, and you can't assign new values to them inside the shader, so you need to either make a new variable or just do&lt;br /&gt;
vec4 fragColor equals vec4 ((gl_Color.rgb + my_light),1.0) * texel;&lt;br /&gt;
(note that color.rgb is the same as color.xyz, GLSL doesn't really care which convention you use, but I took a few months to learn that, so early code by myself often uses xyz indexing convention for color vectors as well).&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=15#p220075 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Tue Oct 07, 2014 12:04 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|An effect is a container for a series of techniques which are all the possible things you could do with some object.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;predicate&amp;gt; section inside each effect determines which of the techniques we actually run. Typically the predicate section contains conditionals on a) rendering framework properties b) OpenGL extension support and c) quality level properties. The renderer searches the effects from lowest to highest technique number and uses the first one that fits the bill (which is why high quality levels precede low quality levels).&lt;br /&gt;
&lt;br /&gt;
The rendering itself is specified as &amp;lt;pass&amp;gt; - each pass runs the renderer over the whole scene. We may sometimes make a quick first pass to fill the depth buffer or a stencil buffer, but usually we render with a single pass.&lt;br /&gt;
&lt;br /&gt;
Techniques may not involve a shader at all, for instance 12 in terrain-default is a pure fixed pipeline fallback technique, but all the rendering you're interested in use a shader, which means they have a &amp;lt;program&amp;gt; section which determines what actual code is supposed to run.&lt;br /&gt;
&lt;br /&gt;
If you run a shader, that needs parameters specified as &amp;lt;uniform&amp;gt;, and textures which need to be assigned to a texture unit _and_ be declared as a uniform sampler.&lt;br /&gt;
&lt;br /&gt;
In addition, each technique contains a host of parameter configuring the fixed pipeline elements, like alpha tests before the fragment stage, or depth buffer writing/reading, alpha blending,... you can ignore them on the first go.&lt;br /&gt;
&lt;br /&gt;
So if you want to look at which shader code is executed when you call the water effect at a certain quality level, you need to work your way through the predicate sections of the techniques from lowest to highest till you find the one that matches, and then look into the program section of that technique.&lt;br /&gt;
&lt;br /&gt;
Now, to make matters more complicated, all the parameters and textures that are assigned to uniforms and texture units in the techniques need to be declared and linked to properties were applicable in the &amp;lt;parameters&amp;gt; section heading each effect declaration. So a texture you want to use has to appear three times - in the parameters section heading the effect, inside the technique assigned to a texture unit and assigned to a uniform sampler.&lt;br /&gt;
&lt;br /&gt;
Now, inheritance moves all the declared parameters and techniques from one effect to the one inheriting. In the case of water, that means the technique is actually _not_ inherited because terrain-default.eff doesn't contain a technique 1 at all, but the general &amp;lt;parameters&amp;gt; section is inherited. So you don't need to declare the additions to &amp;lt;parameters&amp;gt; again, but you do need to make the changes to the &amp;lt;programs&amp;gt; and the &amp;lt;uniform&amp;gt; sections.&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=15#p220152 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Wed Oct 08, 2014 1:58 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|At low water shader quality, water isn't rendered separately from the terrain, i.e. it runs via terrain-default.eff - since you modified that to allow light, light works for water out of the box.&lt;br /&gt;
At high water slider, the techniques in water.eff kick in, and only then do you need to modify the specific water shader code. Now, the peculiar thing about water is that there are two effects (water.eff and water_inland.eff) sharing the same shader code (but calling it with somewhat different parameters). So the function not found error was presumably caused by you modifying water.eff whereas the water you were seeing was initiated by water_inland.eff, and in that effect, the secondary_lights.frag wasn't initially in the program section. So if you alter the water shader code, you need to modify two effect files rather than one to pass the right parameters and access the functions you need.&lt;br /&gt;
&lt;br /&gt;
..........&lt;br /&gt;
..........&lt;br /&gt;
&lt;br /&gt;
Adding them _after_ fogging, isn't what you want - you'll see that if visibility is &amp;lt;100 m, everything will go black at night, because fog color is black at night, so finalColor.rgb of a heavily fogged object will also be black, and then when you light it up, you multiply your light value with black and it'll be black. Or, if you add the light value (which you should only do if the object you add it to is a light color itself), then you'll get a featureless grey. You want to add light after texel color and before fogging.&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=30#p220216 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Wed Oct 08, 2014 11:19 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|So, in old times when rendering textures was slow and complicated, we rendered objects with monochromatic surface colors. Then the (schematic) lighting equation (without specular, and the sum of ambient and diffuse already computed) was&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals objectColor.rgb * light.rgb + objectEmissive.rgb&lt;br /&gt;
&lt;br /&gt;
Now, we have textures and so we get&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals objectColor.rgb * texel.rgb * light.rgb + objectEmissive.rgb + lightMapTexel.rgb&lt;br /&gt;
&lt;br /&gt;
Since we can have the full color information in the texture, objectColor.rgb is usually (1.0,1.0,1.0) because the info is redundant. But if you don't use a texture, of course objectColor.rgb has the actual color value (incidentially, I think we shouldn't texture with monochromatic surfaces at all, it creates a jarring visual impression which can be cured by using even a small texture...)&lt;br /&gt;
&lt;br /&gt;
But if you do, the rendering pipeline is set up to compute color.rgb equals objectColor * light.rgb in the vertex shader, so the equation we have in the fragment shader is something like&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals color.rgb * texel.rgb + objectEmissive.rgb + lightMapTexel.rgb&lt;br /&gt;
&lt;br /&gt;
and if we add a secondary light like&lt;br /&gt;
&lt;br /&gt;
visibleColor.rgb equals (color.rgb + secLight.rgb) * texel.rgb&lt;br /&gt;
&lt;br /&gt;
it of course can never recover the color information, because color.rgb is zero at night since you multiplied the actual color with zero sunlight and the texel doesn't carry information for an untextured object.&lt;br /&gt;
&lt;br /&gt;
Since the secondary light is in screen coordinates, it can't appear in the vertex shader, so the solution would be to pass the actual color and light rather than their product to the fragment shader. Which is expensive, because we need another varying vec3, and varying variable types fill memory and need to be computed an interpolated per vertex/per fragment - which is why I'm not sure whether we shouldn't accept the loss of the color...&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=45#p220321 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Sat Oct 11, 2014 1:28 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|Inheritance works like this:&lt;br /&gt;
&lt;br /&gt;
The base effect has a list of things&lt;br /&gt;
&lt;br /&gt;
A1 B1 C1 D1&lt;br /&gt;
&lt;br /&gt;
The second effect inherits 1 but just declares C2 and E2, so then the list is&lt;br /&gt;
&lt;br /&gt;
A1 B1 C2 D1 E2&lt;br /&gt;
&lt;br /&gt;
The third effect inherits from 2 and declares A3, so then the list is&lt;br /&gt;
&lt;br /&gt;
A3 B1 C2 D1 E2&lt;br /&gt;
&lt;br /&gt;
whereas if the third effect would inherit from 1, then the list would be&lt;br /&gt;
&lt;br /&gt;
A3 B1 C1 D1&lt;br /&gt;
&lt;br /&gt;
So if already present, inheritance overrides, if not present it adds. I suspect that's why programs need to be indexed, so they they override and don't add...&amp;lt;ref&amp;gt;{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&amp;amp;t=24226&amp;amp;start=45#p220403 &lt;br /&gt;
|title=ALS landing lights&lt;br /&gt;
|author=Thorsten Renk |date= Sat Oct 11, 2014 11:33 -0700}}&amp;lt;/ref&amp;gt;|Thorsten Renk}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|Shader Programming in FlightGear]]&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category: Core developer documentation]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Shader_Style_Guide&amp;diff=139079</id>
		<title>Shader Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Shader_Style_Guide&amp;diff=139079"/>
		<updated>2024-02-07T13:01:54Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
FlightGear uses [[Shader|shaders]] written in GLSL. If you are creating a new shader from scratch, you should be following the style of this documentation. For an introduction to shader programming, see [[Howto:Shader programming in FlightGear]].&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
* Vertex, fragment, geometry and compute shaders should have the following file extensions, respectively: &amp;lt;tt&amp;gt;.vert&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.frag&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.geom&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;.comp&amp;lt;/tt&amp;gt; (ex: &amp;lt;tt&amp;gt;shading_opaque.frag&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* Spaces in the file name must be substituted by an underscore '&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'. You must not use a dash '&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;'. For example, {{xt|shader_opaque.frag}} is correct but {{!xt|shader-opaque.frag}} is not.&lt;br /&gt;
* Every shader file must contain one and only one &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; function. If a shader does not contain a &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; function, it is considered a shader library, and its file extension must be &amp;lt;tt&amp;gt;.glsl&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Shader libraries ==&lt;br /&gt;
&lt;br /&gt;
If a function can be used by several shaders, put it on a separate &amp;lt;tt&amp;gt;.glsl&amp;lt;/tt&amp;gt; library file. Shader libraries can be used with other shaders by linking them together. For example, in the [[Effect framework|Effect]] file you can write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
    &amp;lt;fragment-shader&amp;gt;Shaders/HDR/shading.frag&amp;lt;/fragment-shader&amp;gt; &amp;lt;!-- Contains the main() function --&amp;gt;&lt;br /&gt;
    &amp;lt;fragment-shader&amp;gt;Shaders/HDR/math.glsl&amp;lt;/fragment-shader&amp;gt;    &amp;lt;!-- Contains some utility functions that can be used in shading.frag, but no main() --&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use the functions contained in &amp;lt;tt&amp;gt;math.glsl&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;shading.frag&amp;lt;/tt&amp;gt;, you must declare the signatures of the functions you intend to use at the top of the file. For example, if the &amp;lt;tt&amp;gt;math.glsl&amp;lt;/tt&amp;gt; library contains a function named &amp;lt;tt&amp;gt;saturate()&amp;lt;/tt&amp;gt;, in &amp;lt;tt&amp;gt;shading.frag&amp;lt;/tt&amp;gt; you must write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float saturate(float x);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Due to how OpenGL shader linking works, we can only share functions between shader files. If you want to share a constant across multiple files, create a new library file and write a function that returns the constant. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float M_PI() {&lt;br /&gt;
    return 3.14159265358979323846;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Keep in mind that structs cannot be shared across shader files, so make sure they are only used locally.&lt;br /&gt;
&lt;br /&gt;
== Naming ==&lt;br /&gt;
&lt;br /&gt;
* Naming should follow &amp;lt;tt&amp;gt;snake_case&amp;lt;/tt&amp;gt; convention. The only exceptions are type names (ex: &amp;lt;tt&amp;gt;PointLight&amp;lt;/tt&amp;gt;) and the &amp;lt;tt&amp;gt;fragColor&amp;lt;/tt&amp;gt; output variable.&lt;br /&gt;
* Do not use reserved keywords like &amp;lt;tt&amp;gt;sampler&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Single letter vectors should be a capital letter (ex: &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt; for '''N'''ormal, instead of &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Sampler resource names should have the &amp;lt;tt&amp;gt;_tex&amp;lt;/tt&amp;gt; suffix (ex: &amp;lt;code&amp;gt;uniform sampler2D color_tex;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Space prefix ===&lt;br /&gt;
&lt;br /&gt;
Variable names can have a prefix depending on the space they are in:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;ws_&amp;lt;/tt&amp;gt; for '''W'''orld '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;vs_&amp;lt;/tt&amp;gt; for '''V'''iew or Eye '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;ls_&amp;lt;/tt&amp;gt; for '''L'''ocal or Model '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;cs_&amp;lt;/tt&amp;gt; for '''C'''lip '''S'''pace.&lt;br /&gt;
* &amp;lt;tt&amp;gt;ndc_&amp;lt;/tt&amp;gt; for '''NDC''' coordinates (clip coordinates after perspective division).&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The structure of a shader file should follow this order:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Small description of what the shader does.&lt;br /&gt;
 * Try to cite as many resources as possible. Shader code is known to be hard to understand without a reference implementation or any math.&lt;br /&gt;
 */&lt;br /&gt;
#version 330 core&lt;br /&gt;
&lt;br /&gt;
// Fragment writes or vertex attributes&lt;br /&gt;
layout(location = 0) out vec4 fragColor;&lt;br /&gt;
&lt;br /&gt;
// Inputs/outputs&lt;br /&gt;
in vec2 texcoord;&lt;br /&gt;
&lt;br /&gt;
// Custom uniforms (defined in the .eff file)&lt;br /&gt;
uniform sampler2D color_tex;&lt;br /&gt;
&lt;br /&gt;
// Predefined uniforms (from C++)&lt;br /&gt;
uniform mat4 fg_ProjectionMatrix;&lt;br /&gt;
&lt;br /&gt;
// Constants&lt;br /&gt;
const float MY_CONSTANT = 1.0;&lt;br /&gt;
&lt;br /&gt;
// Function signatures of linked shader libraries&lt;br /&gt;
float M_PI();&lt;br /&gt;
&lt;br /&gt;
// Local functions&lt;br /&gt;
vec3 my_local_function(in vec3 input, out vec3 output)&lt;br /&gt;
{&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ENTRY POINT&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category: Core developer documentation]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=139078</id>
		<title>Effect framework</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=139078"/>
		<updated>2024-02-07T12:59:15Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
The '''Effect framework''' as per FlightGear version 2020.3&lt;br /&gt;
&lt;br /&gt;
Effects describe the graphical appearance of 3D objects and scenery in&lt;br /&gt;
FlightGear. The main motivation for effects is to support OpenGL&lt;br /&gt;
shaders and to provide different implementations for graphics hardware&lt;br /&gt;
of varying capabilities. Effects are similar to DirectX effects files&lt;br /&gt;
and Ogre3D material scripts.&lt;br /&gt;
&lt;br /&gt;
An effect is a property list. The property list syntax is extended&lt;br /&gt;
with new &amp;quot;vec3d&amp;quot; and &amp;quot;vec4d&amp;quot; types to support common computer graphics&lt;br /&gt;
values. Effects are read from files with a &amp;quot;.eff&amp;quot; extension or can be&lt;br /&gt;
created on-the-fly by FlightGear at runtime.  An effect consists of a&lt;br /&gt;
&amp;quot;parameters&amp;quot; section followed by &amp;quot;technique&amp;quot; descriptions.  The&lt;br /&gt;
&amp;quot;parameters&amp;quot; section is a tree of values that describe, abstractly,&lt;br /&gt;
the graphical characteristics of objects that use the effect. Techniques&lt;br /&gt;
refer to these parameters and use them to set OpenGL state or to set&lt;br /&gt;
parameters for shader programs. The names of properties in the&lt;br /&gt;
parameter section can be whatever the effects author chooses, although&lt;br /&gt;
some standard parameters  are set by FlightGear itself. On the other&lt;br /&gt;
hand, the properties in the techniques section are all defined by the&lt;br /&gt;
FlightGear. &lt;br /&gt;
&lt;br /&gt;
== Default effects in terrain materials and models ==&lt;br /&gt;
Effects for terrain work in this way: for each material type in&lt;br /&gt;
materials.xml an effect is created that inherits from a single default&lt;br /&gt;
terrain effect, Effects/terrain-default.eff. The parameters section of&lt;br /&gt;
the effect is filled in using the ambient, diffuse, specular,&lt;br /&gt;
emissive, shininess, and transparent fields of the material. The&lt;br /&gt;
parameters image, filter, wrap-s, and wrap-t are also initialized from&lt;br /&gt;
the material xml. Seperate effects are created for each texture&lt;br /&gt;
variant of a material.&lt;br /&gt;
&lt;br /&gt;
Model effects are created by walking the OpenSceneGraph scene graph&lt;br /&gt;
for a model and replacing nodes (osg::Geode) that have state sets with&lt;br /&gt;
node that uses an effect instead. Again, a small effect is created&lt;br /&gt;
with parameters extracted from OSG objects; this effect inherits, by&lt;br /&gt;
default, from Effects/model-default.eff. A larger set of parameters is&lt;br /&gt;
created for model effects than for terrain because there is more&lt;br /&gt;
variation possible from the OSG model loaders than from the terrain&lt;br /&gt;
system. The parameters created are: &lt;br /&gt;
&lt;br /&gt;
* material active, ambient, diffuse, specular, emissive, shininess, color mode&lt;br /&gt;
# blend active, source, destination&lt;br /&gt;
# shade-model&lt;br /&gt;
# cull-face&lt;br /&gt;
* rendering-hint&lt;br /&gt;
* texture type, image, filter, wrap-s, wrap-t&lt;br /&gt;
&lt;br /&gt;
== Specifying custom effects ==&lt;br /&gt;
You can specify the effects that will be used by FlightGear as the&lt;br /&gt;
base effect when it creates terrain and model effects.&lt;br /&gt;
&lt;br /&gt;
In the terrain materials.xml, an &amp;quot;effect&amp;quot; property specifies the name&lt;br /&gt;
of the model to use.&lt;br /&gt;
&lt;br /&gt;
Material animations will be implemented by creating a new effect&lt;br /&gt;
that inherits from one in a model, overriding the parameters that&lt;br /&gt;
will be animated.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
The $FGDATA/Effects directory contains the effects definitions; look there for&lt;br /&gt;
examples. Effects/crop.eff is a good example of a complex effect.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
To apply an effect to a model or part of a model use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/light-cone&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;Cone&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/effect&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;inherits-from&amp;gt; &amp;lt;/inherits-from&amp;gt; contains the path to the effect you want to apply.&lt;br /&gt;
The effect does not need the file extension.&lt;br /&gt;
&lt;br /&gt;
=== Parameters in model file ===&lt;br /&gt;
&lt;br /&gt;
Parameters can be put into the model files effect application as well. But only bool, int, float, string can be used there.&lt;br /&gt;
&lt;br /&gt;
=== Chrome old usage ===&lt;br /&gt;
&lt;br /&gt;
Chrome, although now implemented as an effect, still retains the old method of application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;shader&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;shader&amp;gt;chrome&amp;lt;/shader&amp;gt;&lt;br /&gt;
  &amp;lt;texture&amp;gt;glass_shader.png&amp;lt;/texture&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;windscreen&amp;lt;/object-name&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in order to maintain backward compatibility.&lt;br /&gt;
&lt;br /&gt;
== Reload effects at runtime ==&lt;br /&gt;
To reload an effect applied in a model xml file (e.g. some parameters and what it enherits from) just go into debug menu and select Reload Model.&lt;br /&gt;
&lt;br /&gt;
To reload the entire effect framework including eff files, go into menu and debug and configure development extensions and reload shaders. This is broken in 2020.1 though, but works in earlier FG versions.&lt;br /&gt;
&lt;br /&gt;
== The XML tags of an effect ==&lt;br /&gt;
&lt;br /&gt;
=== name ===&lt;br /&gt;
The name of the effect&lt;br /&gt;
&lt;br /&gt;
=== inherits-from ===&lt;br /&gt;
One feature not fully illustrated in the sample below is that&lt;br /&gt;
effects can inherit from each other. The parent effect is listed in&lt;br /&gt;
the &amp;quot;inherits-from&amp;quot; form. The child effect's property tree is&lt;br /&gt;
overlaid over that of the parent. Nodes that have the same name and&lt;br /&gt;
property index -- set by the &amp;quot;n=&amp;quot; attribute in the property tag --&lt;br /&gt;
are recursively merged. Leaf property nodes from the child have&lt;br /&gt;
precedence.  This means that effects that inherit from the example&lt;br /&gt;
effect below could be very short, listing just new&lt;br /&gt;
parameters and adding nothing to the techniques section;&lt;br /&gt;
alternatively, a technique could be altered or customized in a&lt;br /&gt;
child, listing (for example) a different shader program. An example&lt;br /&gt;
showing inheritance Effects/crop.eff, which inherits some if its&lt;br /&gt;
values from Effects/terrain-default.eff.&lt;br /&gt;
&lt;br /&gt;
FlightGear directly uses effects inheritance to assign effects to 3D&lt;br /&gt;
models and terrain. As described below, at runtime small effects are&lt;br /&gt;
created that contain material and texture values in a &amp;quot;parameters&amp;quot;&lt;br /&gt;
section. These effects inherit from another effect which references&lt;br /&gt;
those parameters in its &amp;quot;techniques&amp;quot; section. The derived effect&lt;br /&gt;
overrides any default values that might be in the base effect's&lt;br /&gt;
parameters section.&lt;br /&gt;
&lt;br /&gt;
=== parameters ===&lt;br /&gt;
Custom parameters that controls the effect.&lt;br /&gt;
&lt;br /&gt;
Note that parameters can use the &amp;lt;use&amp;gt; tags to enable properties to specify the values.&lt;br /&gt;
&lt;br /&gt;
=== generate ===&lt;br /&gt;
&lt;br /&gt;
Often shader effects need tangent vectors to work properly. These &lt;br /&gt;
tangent vectors, usually called tangent and binormal, are computed &lt;br /&gt;
on the CPU and given to the shader as vertex attributes. These &lt;br /&gt;
vectors are computed on demand on the geometry using the effect if &lt;br /&gt;
the 'generate' clause is present in the effect file.&lt;br /&gt;
&lt;br /&gt;
Example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;generate&amp;gt;&lt;br /&gt;
  &amp;lt;tangent type=&amp;quot;int&amp;quot;&amp;gt;6&amp;lt;/tangent&amp;gt;&lt;br /&gt;
  &amp;lt;binormal type=&amp;quot;int&amp;quot;&amp;gt;7&amp;lt;/binormal&amp;gt;&lt;br /&gt;
  &amp;lt;normal type=&amp;quot;int&amp;quot;&amp;gt;8&amp;lt;/normal&amp;gt;&lt;br /&gt;
&amp;lt;/generate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valid subnodes of 'generate' are 'tangent', 'binormal' or 'normal'.&lt;br /&gt;
The integer value of these subnode is the index of the attribute &lt;br /&gt;
that will hold the value of the vec3 vector.&lt;br /&gt;
&lt;br /&gt;
Normal is really redundant and should not be used, as that is already generated from loading the mesh.&lt;br /&gt;
&lt;br /&gt;
The generate clause is located under PropertyList in the xml file.&lt;br /&gt;
&lt;br /&gt;
In order to be available for the vertex shader, these data should &lt;br /&gt;
be bound to an attribute in the program clause, like this :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
  &amp;lt;vertex-shader&amp;gt;my_vertex_shader&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
  &amp;lt;attribute&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;my_tangent_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;index&amp;gt;6&amp;lt;/index&amp;gt;&lt;br /&gt;
  &amp;lt;/attribute&amp;gt;&lt;br /&gt;
  &amp;lt;attribute&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;my_binormal_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;index&amp;gt;7&amp;lt;/index&amp;gt;&lt;br /&gt;
  &amp;lt;/attribute&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
attribute names are whatever the shader use. The index is the one &lt;br /&gt;
declared in the 'generate' clause. So because generate/tangent has &lt;br /&gt;
value 6 and my_tangent_attribute has index 6, my_tangent_attribute &lt;br /&gt;
holds the tangent value for the vertex.&lt;br /&gt;
&lt;br /&gt;
=== technique ===&lt;br /&gt;
A certain way of rendering this effect. Different pipelines typically have their own techniques.&lt;br /&gt;
&lt;br /&gt;
==== scheme ====&lt;br /&gt;
Used by the [[Compositor]] to choose which implementation of an Effect to render. For example, if a Compositor scene pass specifies the &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; scheme, all techniques that use &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; will be used to render the pass. If an Effect doesn't contain a technique that implements this scheme, the object will be ignored and not rendered on that pass. Techniques with no scheme are considered ''default'' and will be used by scene passes when no explicit scheme has been provided.&lt;br /&gt;
&lt;br /&gt;
==== predicate ====&lt;br /&gt;
A technique can contain a predicate that describes the OpenGL&lt;br /&gt;
functionality required to support the technique. The first&lt;br /&gt;
technique with a valid predicate in the list of techniques is used&lt;br /&gt;
to set up the graphics state of the effect. A technique with no&lt;br /&gt;
predicate is always assumed to be valid. The predicate is written in a&lt;br /&gt;
little expression language that supports the following primitives:&lt;br /&gt;
&lt;br /&gt;
and, or, equal, less, less-equal&lt;br /&gt;
glversion - returns the version number of OpenGL&lt;br /&gt;
extension-supported - returns true if an OpenGL extension is supported&lt;br /&gt;
property - returns the boolean value of a property&lt;br /&gt;
float-property - returns the float value of a property, useful inside equal, less or less-equal nodes&lt;br /&gt;
shader-language - returns the version of GLSL supported, or 0 if there is none.&lt;br /&gt;
&lt;br /&gt;
The proper way to test whether to enable a shader-based technique is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
  &amp;lt;and&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;less-equal&amp;gt;&lt;br /&gt;
      &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;1.0&amp;lt;/value&amp;gt;&lt;br /&gt;
      &amp;lt;shader-language/&amp;gt;&lt;br /&gt;
    &amp;lt;/less-equal&amp;gt;&lt;br /&gt;
  &amp;lt;/and&amp;gt;&lt;br /&gt;
&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is also a property set by the user to indicate what is the level &lt;br /&gt;
of quality desired. This level of quality can be checked in the predicate&lt;br /&gt;
like this :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
  &amp;lt;and&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;less-equal&amp;gt;&lt;br /&gt;
      &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
      &amp;lt;float-property&amp;gt;/sim/rendering/quality-level&amp;lt;/float-property&amp;gt;&lt;br /&gt;
    &amp;lt;/less-equal&amp;gt;&lt;br /&gt;
    &amp;lt;!-- other predicate conditions --&amp;gt;&lt;br /&gt;
  &amp;lt;/and&amp;gt;&lt;br /&gt;
&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
The range of /sim/rendering/quality-level is [0..5]&lt;br /&gt;
 * 2.0 is the threshold for relief mapping effects,&lt;br /&gt;
 * 4.0 is the threshold for geometry shader usage.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
  &amp;lt;and&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shaders/quality-level&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;property&amp;gt;/sim/rendering/shaders/model&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;or&amp;gt;&lt;br /&gt;
      &amp;lt;less-equal&amp;gt;&lt;br /&gt;
        &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
        &amp;lt;glversion/&amp;gt;&lt;br /&gt;
      &amp;lt;/less-equal&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_shader_objects&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_shading_language_100&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_vertex_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
        &amp;lt;extension-supported&amp;gt;GL_ARB_fragment_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
    &amp;lt;/or&amp;gt;&lt;br /&gt;
  &amp;lt;/and&amp;gt;&lt;br /&gt;
&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pass ====&lt;br /&gt;
A technique can consist of several passes. A pass is basically an Open&lt;br /&gt;
Scene Graph StateSet. Ultimately all OpenGL and OSG modes and state&lt;br /&gt;
attributes  will be accessable in techniques. State attributes -- that&lt;br /&gt;
is, technique properties that have children and are not just boolean&lt;br /&gt;
modes -- have an &amp;lt;active&amp;gt; parameter which enables or disables the&lt;br /&gt;
attribute. In this way a technique can declare parameters it needs,&lt;br /&gt;
but not enable the attribute at all if it is not needed; the decision&lt;br /&gt;
can be based on a parameter in the parameters section of the&lt;br /&gt;
effect. For example, effects that support transparent and opaque&lt;br /&gt;
geometry could have as part of a technique:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;blend&amp;gt;&lt;br /&gt;
  &amp;lt;active&amp;gt;&amp;lt;use&amp;gt;blend/active&amp;lt;/use&amp;gt;&amp;lt;/active&amp;gt;&lt;br /&gt;
  &amp;lt;source&amp;gt;src-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;destination&amp;gt;one-minus-src-alpha&amp;lt;/destination&amp;gt;&lt;br /&gt;
&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So if the blend/active parameter is true blending will be activated&lt;br /&gt;
using the usual blending equation; otherwise blending is disabled.&lt;br /&gt;
&lt;br /&gt;
Values are assigned to technique properties in several ways:&lt;br /&gt;
&lt;br /&gt;
	* They can appear directly in the techniques section as a&lt;br /&gt;
		constant. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uniform&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;ColorsTex&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;sampler-1d&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;value type=&amp;quot;int&amp;quot;&amp;gt;2&amp;lt;/value&amp;gt;&lt;br /&gt;
&amp;lt;/uniform&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		* The name of a property in the parameters section can be&lt;br /&gt;
		referenced using a &amp;quot;use&amp;quot; clause. For example, in the technique&lt;br /&gt;
		section:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;material&amp;gt;&lt;br /&gt;
  &amp;lt;ambient&amp;gt;&amp;lt;use&amp;gt;material/ambient&amp;lt;/use&amp;gt;&amp;lt;/ambient&amp;gt;&lt;br /&gt;
&amp;lt;/material&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		Then, in the parameters section of the effect:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;parameters&amp;gt;&lt;br /&gt;
  &amp;lt;material&amp;gt;&lt;br /&gt;
    &amp;lt;ambient type=&amp;quot;vec4d&amp;quot;&amp;gt;0.2 0.2 0.2 1.0&amp;lt;/ambient&amp;gt;&lt;br /&gt;
  &amp;lt;/material&amp;gt;&lt;br /&gt;
&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		It's worth pointing out that the &amp;quot;material&amp;quot; property in a&lt;br /&gt;
		technique specifies part of OpenGL's state, whereas &amp;quot;material&amp;quot;&lt;br /&gt;
		in the parameters section is just a name, part of a&lt;br /&gt;
		hierarchical namespace.&lt;br /&gt;
&lt;br /&gt;
		* A property in the parameters section doesn't need to contain&lt;br /&gt;
		a constant value; it can also contain a &amp;quot;use&amp;quot; property. Here&lt;br /&gt;
		the value of the use clause is the name of a node in an&lt;br /&gt;
		external property tree which will be used as the source of a&lt;br /&gt;
		value. If the name begins with '/', the node is in&lt;br /&gt;
		FlightGear's global property tree; otherwise, it is in a local&lt;br /&gt;
		property tree, usually belonging to a model [NOT IMPLEMENTED&lt;br /&gt;
		YET]. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;parameters&amp;gt;&lt;br /&gt;
  &amp;lt;chrome-light&amp;gt;&amp;lt;use&amp;gt;/rendering/scene/chrome-light&amp;lt;/use&amp;gt;&amp;lt;/chrome-light&amp;gt;&lt;br /&gt;
&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		The type is determined by what is expected by the technique&lt;br /&gt;
		attribute that will ultimately receive the value. [There is&lt;br /&gt;
		no way to get vector values out of the main property system&lt;br /&gt;
		yet; this will be fixed shortly.] Values that are declared&lt;br /&gt;
		this way are dynamically updated if the property node&lt;br /&gt;
		changes.&lt;br /&gt;
&lt;br /&gt;
===== lighting =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== material =====&lt;br /&gt;
children: active, ambient, ambient-front, ambient-back, diffuse,&lt;br /&gt;
		 diffuse-front, diffuse-back, specular, specular-front,&lt;br /&gt;
		 specular-back, emissive, emissive-front, emissive-back, shininess,&lt;br /&gt;
		 shininess-front, shininess-back, color-mode&lt;br /&gt;
&lt;br /&gt;
===== blend =====&lt;br /&gt;
Children: active, source, destination, source-rgb, source-alpha, destination-rgb, destination-alpha&lt;br /&gt;
&lt;br /&gt;
Children values: dst-alpha, dst-color, one, one-minus-dst-alpha, one-minus-dst-color, one-minus-src-alpha, one-minus-src-color, src-alpha, src-alpha-saturate, src-color, constant-color, one-minus-constant-color, constant-alpha, one-minus-constant-alpha, zero&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;blend&amp;gt;&lt;br /&gt;
  &amp;lt;active&amp;gt;true&amp;lt;/active&amp;gt;&lt;br /&gt;
  &amp;lt;source&amp;gt;one-minus-dst-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
  &amp;lt;destination&amp;gt;src-alpha-saturate&amp;lt;/destination&amp;gt;&lt;br /&gt;
&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== blend (simple) =====&lt;br /&gt;
A blend tag with 0 will do nothing.&lt;br /&gt;
A blend tag with 1 will do the same as source-alpha: one-minus-dst-alpha, in other words it will enable z transparency using alpha from the fragment shader.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;blend&amp;gt;1&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== shade-model =====&lt;br /&gt;
flat or smooth&lt;br /&gt;
&lt;br /&gt;
===== cull-face =====&lt;br /&gt;
front, back, front-back, off&lt;br /&gt;
&lt;br /&gt;
===== texture-unit =====&lt;br /&gt;
unit: integer denoting which unit it is&lt;br /&gt;
&lt;br /&gt;
image: the texture path&lt;br /&gt;
&lt;br /&gt;
images: multiple texture paths&lt;br /&gt;
&lt;br /&gt;
type: 2d, noise, cubemap, 3d (3d was added in 2020.1 and is used for layers of 2d textures defining a volumetric 3d texture)&lt;br /&gt;
&lt;br /&gt;
filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
mag-filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
wrap: repeat, clamp-to-edge, clamp-to-border, clamp, mirror&lt;br /&gt;
&lt;br /&gt;
internal-format: normalized&lt;br /&gt;
&lt;br /&gt;
environment: mode, color&lt;br /&gt;
:mode: add,blend,decal,modulate,replace&lt;br /&gt;
:color: rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: replace, modulate, add, add-signed, interpolate, subtract, dot3-rgb, dot3-rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: combine-rgb, combine-alpha, source0-rgb, source1-rgb, source2-rgb, source0-alpha, source1-alpha,source2-alpha,operand0-rgb,operand1-rgb,operand2-rgb,operand0-alpha,operand1-alpha,operand2-alpha,scale-rgb,scale-alpha&lt;br /&gt;
&lt;br /&gt;
point-sprite: true, false&lt;br /&gt;
&lt;br /&gt;
mipmap-control functions: auto, average, sum, product, min, max&lt;br /&gt;
&lt;br /&gt;
texgen:&lt;br /&gt;
:mode: object-linear, eye-linear, sphere-map, normal-map, reflection-map&lt;br /&gt;
:planes: s, t, r, q as doubles&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;texture-unit&amp;gt;&lt;br /&gt;
  &amp;lt;unit&amp;gt;3&amp;lt;/unit&amp;gt;&lt;br /&gt;
  &amp;lt;image&amp;gt;Textures/Terrain/void.png&amp;lt;/image&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;2d&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;filter&amp;gt;linear-mipmap-linear&amp;lt;/filter&amp;gt;&lt;br /&gt;
  &amp;lt;mag-filter&amp;gt;linear-mipmap-linear&amp;lt;/mag-filter&amp;gt;&lt;br /&gt;
  &amp;lt;wrap-s&amp;gt;repeat&amp;lt;/wrap-s&amp;gt;&lt;br /&gt;
  &amp;lt;wrap-t&amp;gt;repeat&amp;lt;/wrap-t&amp;gt;&lt;br /&gt;
  &amp;lt;wrap-r&amp;gt;repeat&amp;lt;/wrap-r&amp;gt;&lt;br /&gt;
  &amp;lt;internal-format&amp;gt;normalized&amp;lt;/internal-format&amp;gt;&lt;br /&gt;
  &amp;lt;mipmap-control&amp;gt;&lt;br /&gt;
    &amp;lt;function-r&amp;gt;average&amp;lt;/function-r&amp;gt;&lt;br /&gt;
    &amp;lt;function-g&amp;gt;min&amp;lt;/function-g&amp;gt;&lt;br /&gt;
    &amp;lt;function-b&amp;gt;sum&amp;lt;/function-b&amp;gt;&lt;br /&gt;
    &amp;lt;function-a&amp;gt;product&amp;lt;/function-a&amp;gt;&lt;br /&gt;
  &amp;lt;/mipmap-control&amp;gt;&lt;br /&gt;
  &amp;lt;environment&amp;gt;&lt;br /&gt;
    &amp;lt;mode&amp;gt;decal&amp;lt;/mode&amp;gt;&lt;br /&gt;
    &amp;lt;color&amp;gt;0.0 0.1 0.6 1.0&amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;/environment&amp;gt;&lt;br /&gt;
  &amp;lt;point-sprite&amp;gt;true&amp;lt;/point-sprite&amp;gt;&lt;br /&gt;
  &amp;lt;texenv-combine&amp;gt;operand0-rgb&amp;lt;/texenv-combine&amp;gt;&lt;br /&gt;
  &amp;lt;texgen&amp;gt;&lt;br /&gt;
    &amp;lt;mode&amp;gt;S&amp;lt;/mode&amp;gt;&lt;br /&gt;
    &amp;lt;planes&amp;gt;0.075, 0.0, 0.0, 0.5&amp;lt;/planes&amp;gt;&lt;br /&gt;
  &amp;lt;/texgen&amp;gt;&lt;br /&gt;
&amp;lt;/texture-unit&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Textures of type 3d has to be packed on the x axis. Here is an example: [https://raw.githubusercontent.com/sebh/TileableVolumeNoise/master/Examples/noiseErosionPacked.jpg noiseErosionPacked.jpg]&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-two-side =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== polygon-mode =====&lt;br /&gt;
children: front, back&lt;br /&gt;
&lt;br /&gt;
Valid values:  fill, line, point&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-point-size =====&lt;br /&gt;
true, false&lt;br /&gt;
&lt;br /&gt;
===== uniform =====&lt;br /&gt;
Data accessible by shaders.&lt;br /&gt;
&lt;br /&gt;
name: the name&lt;br /&gt;
&lt;br /&gt;
type: bool, int, float, float-vec3, float-vec4, sampler-1d, sampler-2d, sampler-3d, sampler-1d-shadow, sampler-2d-shadow, sampler-cube&lt;br /&gt;
&lt;br /&gt;
===== alpha-test =====&lt;br /&gt;
&lt;br /&gt;
active: true, false&lt;br /&gt;
&lt;br /&gt;
comparison: never, less, equal, lequal, greater, notequal, gequal, always&lt;br /&gt;
&lt;br /&gt;
reference: 0 to 1&lt;br /&gt;
&lt;br /&gt;
===== render-bin =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
bin-number: This is an integer defining the order stuff will be rendered in, it can be negative also.&lt;br /&gt;
&lt;br /&gt;
bin-name: RenderBin, DepthSortedBin&lt;br /&gt;
&lt;br /&gt;
===== rendering-hint =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
default, opaque, transparent&lt;br /&gt;
&lt;br /&gt;
This basically just sets Renderbin:&lt;br /&gt;
&lt;br /&gt;
opaque = bin 10, depthsortedbin&lt;br /&gt;
&lt;br /&gt;
transparent = bin 0, renderbin&lt;br /&gt;
&lt;br /&gt;
default = inherit renderbin details from parent node&lt;br /&gt;
&lt;br /&gt;
===== depth =====&lt;br /&gt;
&lt;br /&gt;
* function: Specifies the depth comparison function. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthFunc.xhtml &amp;lt;tt&amp;gt;glDepthFunc&amp;lt;/tt&amp;gt;].&lt;br /&gt;
* near, far: Specify the mapping of depth values from normalized device coordinates to window coordinates. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml &amp;lt;tt&amp;gt;glDepthRange&amp;lt;/tt&amp;gt;]&lt;br /&gt;
* write-mask: Whether to write to the depth buffer or not.&lt;br /&gt;
* enabled: Whether depth testing is enabled or not.&lt;br /&gt;
&lt;br /&gt;
===== define =====&lt;br /&gt;
&lt;br /&gt;
Injects a &amp;lt;tt&amp;gt;#define&amp;lt;/tt&amp;gt; preprocessor directive into the shaders used in this pass. It is then possible to create logic around this define using conventional preprocessor directives like &amp;lt;tt&amp;gt;#ifdef&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;#endif&amp;lt;/tt&amp;gt;, etc. Keep in mind that shaders must import the define before being able to use it. For example, for a define named &amp;lt;tt&amp;gt;USE_TEXTUREMAPPING&amp;lt;/tt&amp;gt;, the following GLSL code must be placed right after the &amp;lt;tt&amp;gt;#version&amp;lt;/tt&amp;gt; directive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
#pragma import_defines(USE_TEXTUREMAPPING)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* name: Name of the define.&lt;br /&gt;
* value: Value of the define (optional).&lt;br /&gt;
&lt;br /&gt;
===== program =====&lt;br /&gt;
* vertex-shader&lt;br /&gt;
* geometry-shader&lt;br /&gt;
* fragment-shader&lt;br /&gt;
* attribute&lt;br /&gt;
* geometry-vertices-out: integer, max number of vertices emitted by geometry shader&lt;br /&gt;
* geometry-input-type: points, lines, lines-adjacency, triangles, triangles-adjacency&lt;br /&gt;
* geometry-output-type: points, line-strip, triangle-strip&lt;br /&gt;
* uniform-block-binding: has name and index (since 2020.1)&lt;br /&gt;
&lt;br /&gt;
example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
  &amp;lt;vertex-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
  &amp;lt;fragment-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
  &amp;lt;fragment-shader n=&amp;quot;1&amp;quot;&amp;gt;Shaders/noise.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
  &amp;lt;fragment-shader n=&amp;quot;2&amp;quot;&amp;gt;Shaders/filters-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See this page for more about shaders: [[Howto:Shader programming in FlightGear]]&lt;br /&gt;
&lt;br /&gt;
== Uniforms passed to shaders outside the XML effect framework ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Type&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, view matrix used to transform from world to view space. Same as osg_ViewMatrix, but for fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, view matrix inverse used to transform from view to world space. Same as osg_ViewMatrixInverse but for fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, projection matrix inverse&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionCart&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in cartesian coordinates&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionGeod&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunAmbientColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDiffuseColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunSpecularColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FogColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FogDensity&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ShadowNumber&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ShadowDistances&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_DepthInColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Tells if the depth is stored in a depth texture or a color texture&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Planes&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used to convert the value of the depth buffer to a depth that can be used to compute the eye space position of the fragment&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_BufferSize&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dimensions of the buffer, used to convert gl_FragCoord into the range [0..1][0..1]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG, used only when working on actual geometry. Transforms from world to view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG, used only when working on actual geometry. Transforms from view to world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_SimulationTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_DeltaFrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameNumber&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=37364|title=Application of effects}} - Testing which kind of groups an effect can be applied to and when&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=139077</id>
		<title>Effect framework</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=139077"/>
		<updated>2024-02-07T12:49:07Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
The '''Effect framework''' as per FlightGear version 2020.3&lt;br /&gt;
&lt;br /&gt;
Effects describe the graphical appearance of 3D objects and scenery in&lt;br /&gt;
FlightGear. The main motivation for effects is to support OpenGL&lt;br /&gt;
shaders and to provide different implementations for graphics hardware&lt;br /&gt;
of varying capabilities. Effects are similar to DirectX effects files&lt;br /&gt;
and Ogre3D material scripts.&lt;br /&gt;
&lt;br /&gt;
An effect is a property list. The property list syntax is extended&lt;br /&gt;
with new &amp;quot;vec3d&amp;quot; and &amp;quot;vec4d&amp;quot; types to support common computer graphics&lt;br /&gt;
values. Effects are read from files with a &amp;quot;.eff&amp;quot; extension or can be&lt;br /&gt;
created on-the-fly by FlightGear at runtime.  An effect consists of a&lt;br /&gt;
&amp;quot;parameters&amp;quot; section followed by &amp;quot;technique&amp;quot; descriptions.  The&lt;br /&gt;
&amp;quot;parameters&amp;quot; section is a tree of values that describe, abstractly,&lt;br /&gt;
the graphical characteristics of objects that use the effect. Techniques&lt;br /&gt;
refer to these parameters and use them to set OpenGL state or to set&lt;br /&gt;
parameters for shader programs. The names of properties in the&lt;br /&gt;
parameter section can be whatever the effects author chooses, although&lt;br /&gt;
some standard parameters  are set by FlightGear itself. On the other&lt;br /&gt;
hand, the properties in the techniques section are all defined by the&lt;br /&gt;
FlightGear. &lt;br /&gt;
&lt;br /&gt;
== Default effects in terrain materials and models ==&lt;br /&gt;
Effects for terrain work in this way: for each material type in&lt;br /&gt;
materials.xml an effect is created that inherits from a single default&lt;br /&gt;
terrain effect, Effects/terrain-default.eff. The parameters section of&lt;br /&gt;
the effect is filled in using the ambient, diffuse, specular,&lt;br /&gt;
emissive, shininess, and transparent fields of the material. The&lt;br /&gt;
parameters image, filter, wrap-s, and wrap-t are also initialized from&lt;br /&gt;
the material xml. Seperate effects are created for each texture&lt;br /&gt;
variant of a material.&lt;br /&gt;
&lt;br /&gt;
Model effects are created by walking the OpenSceneGraph scene graph&lt;br /&gt;
for a model and replacing nodes (osg::Geode) that have state sets with&lt;br /&gt;
node that uses an effect instead. Again, a small effect is created&lt;br /&gt;
with parameters extracted from OSG objects; this effect inherits, by&lt;br /&gt;
default, from Effects/model-default.eff. A larger set of parameters is&lt;br /&gt;
created for model effects than for terrain because there is more&lt;br /&gt;
variation possible from the OSG model loaders than from the terrain&lt;br /&gt;
system. The parameters created are: &lt;br /&gt;
&lt;br /&gt;
* material active, ambient, diffuse, specular, emissive, shininess, color mode&lt;br /&gt;
# blend active, source, destination&lt;br /&gt;
# shade-model&lt;br /&gt;
# cull-face&lt;br /&gt;
* rendering-hint&lt;br /&gt;
* texture type, image, filter, wrap-s, wrap-t&lt;br /&gt;
&lt;br /&gt;
== Specifying custom effects ==&lt;br /&gt;
You can specify the effects that will be used by FlightGear as the&lt;br /&gt;
base effect when it creates terrain and model effects.&lt;br /&gt;
&lt;br /&gt;
In the terrain materials.xml, an &amp;quot;effect&amp;quot; property specifies the name&lt;br /&gt;
of the model to use.&lt;br /&gt;
&lt;br /&gt;
Material animations will be implemented by creating a new effect&lt;br /&gt;
that inherits from one in a model, overriding the parameters that&lt;br /&gt;
will be animated.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
The $FGDATA/Effects directory contains the effects definitions; look there for&lt;br /&gt;
examples. Effects/crop.eff is a good example of a complex effect.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
To apply an effect to a model or part of a model use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;effect&amp;gt;&lt;br /&gt;
		&amp;lt;inherits-from&amp;gt;Effects/light-cone&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
		&amp;lt;object-name&amp;gt;Cone&amp;lt;/object-name&amp;gt;&lt;br /&gt;
	&amp;lt;/effect&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;inherits-from&amp;gt; &amp;lt;/inherits-from&amp;gt; contains the path to the effect you want to apply.&lt;br /&gt;
The effect does not need the file extension.&lt;br /&gt;
&lt;br /&gt;
=== Parameters in model file ===&lt;br /&gt;
&lt;br /&gt;
Parameters can be put into the model files effect application as well. But only bool, int, float, string can be used there.&lt;br /&gt;
&lt;br /&gt;
=== Chrome old usage ===&lt;br /&gt;
&lt;br /&gt;
Chrome, although now implemented as an effect, still retains the old method of application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;animation&amp;gt;&lt;br /&gt;
			&amp;lt;type&amp;gt;shader&amp;lt;/type&amp;gt;&lt;br /&gt;
			&amp;lt;shader&amp;gt;chrome&amp;lt;/shader&amp;gt;&lt;br /&gt;
			&amp;lt;texture&amp;gt;glass_shader.png&amp;lt;/texture&amp;gt;&lt;br /&gt;
			&amp;lt;object-name&amp;gt;windscreen&amp;lt;/object-name&amp;gt;&lt;br /&gt;
	&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in order to maintain backward compatibility.&lt;br /&gt;
&lt;br /&gt;
== Reload effects at runtime ==&lt;br /&gt;
To reload an effect applied in a model xml file (e.g. some parameters and what it enherits from) just go into debug menu and select Reload Model.&lt;br /&gt;
&lt;br /&gt;
To reload the entire effect framework including eff files, go into menu and debug and configure development extensions and reload shaders. This is broken in 2020.1 though, but works in earlier FG versions.&lt;br /&gt;
&lt;br /&gt;
== The XML tags of an effect ==&lt;br /&gt;
&lt;br /&gt;
=== name ===&lt;br /&gt;
The name of the effect&lt;br /&gt;
&lt;br /&gt;
=== inherits-from ===&lt;br /&gt;
One feature not fully illustrated in the sample below is that&lt;br /&gt;
effects can inherit from each other. The parent effect is listed in&lt;br /&gt;
the &amp;quot;inherits-from&amp;quot; form. The child effect's property tree is&lt;br /&gt;
overlaid over that of the parent. Nodes that have the same name and&lt;br /&gt;
property index -- set by the &amp;quot;n=&amp;quot; attribute in the property tag --&lt;br /&gt;
are recursively merged. Leaf property nodes from the child have&lt;br /&gt;
precedence.  This means that effects that inherit from the example&lt;br /&gt;
effect below could be very short, listing just new&lt;br /&gt;
parameters and adding nothing to the techniques section;&lt;br /&gt;
alternatively, a technique could be altered or customized in a&lt;br /&gt;
child, listing (for example) a different shader program. An example&lt;br /&gt;
showing inheritance Effects/crop.eff, which inherits some if its&lt;br /&gt;
values from Effects/terrain-default.eff.&lt;br /&gt;
&lt;br /&gt;
FlightGear directly uses effects inheritance to assign effects to 3D&lt;br /&gt;
models and terrain. As described below, at runtime small effects are&lt;br /&gt;
created that contain material and texture values in a &amp;quot;parameters&amp;quot;&lt;br /&gt;
section. These effects inherit from another effect which references&lt;br /&gt;
those parameters in its &amp;quot;techniques&amp;quot; section. The derived effect&lt;br /&gt;
overrides any default values that might be in the base effect's&lt;br /&gt;
parameters section.&lt;br /&gt;
&lt;br /&gt;
=== parameters ===&lt;br /&gt;
Custom parameters that controls the effect.&lt;br /&gt;
&lt;br /&gt;
Note that parameters can use the &amp;lt;use&amp;gt; tags to enable properties to specify the values.&lt;br /&gt;
&lt;br /&gt;
=== generate ===&lt;br /&gt;
&lt;br /&gt;
Often shader effects need tangent vectors to work properly. These &lt;br /&gt;
tangent vectors, usually called tangent and binormal, are computed &lt;br /&gt;
on the CPU and given to the shader as vertex attributes. These &lt;br /&gt;
vectors are computed on demand on the geometry using the effect if &lt;br /&gt;
the 'generate' clause is present in the effect file.&lt;br /&gt;
&lt;br /&gt;
Example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;generate&amp;gt;&lt;br /&gt;
		&amp;lt;tangent type=&amp;quot;int&amp;quot;&amp;gt;6&amp;lt;/tangent&amp;gt;&lt;br /&gt;
		&amp;lt;binormal type=&amp;quot;int&amp;quot;&amp;gt;7&amp;lt;/binormal&amp;gt;&lt;br /&gt;
		&amp;lt;normal type=&amp;quot;int&amp;quot;&amp;gt;8&amp;lt;/normal&amp;gt;&lt;br /&gt;
	&amp;lt;/generate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valid subnodes of 'generate' are 'tangent', 'binormal' or 'normal'.&lt;br /&gt;
The integer value of these subnode is the index of the attribute &lt;br /&gt;
that will hold the value of the vec3 vector.&lt;br /&gt;
&lt;br /&gt;
Normal is really redundant and should not be used, as that is already generated from loading the mesh.&lt;br /&gt;
&lt;br /&gt;
The generate clause is located under PropertyList in the xml file.&lt;br /&gt;
&lt;br /&gt;
In order to be available for the vertex shader, these data should &lt;br /&gt;
be bound to an attribute in the program clause, like this :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;program&amp;gt;&lt;br /&gt;
		&amp;lt;vertex-shader&amp;gt;my_vertex_shader&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;attribute&amp;gt;&lt;br /&gt;
			&amp;lt;name&amp;gt;my_tangent_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
			&amp;lt;index&amp;gt;6&amp;lt;/index&amp;gt;&lt;br /&gt;
		&amp;lt;/attribute&amp;gt;&lt;br /&gt;
		&amp;lt;attribute&amp;gt;&lt;br /&gt;
			&amp;lt;name&amp;gt;my_binormal_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
			&amp;lt;index&amp;gt;7&amp;lt;/index&amp;gt;&lt;br /&gt;
		&amp;lt;/attribute&amp;gt;&lt;br /&gt;
	&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
attribute names are whatever the shader use. The index is the one &lt;br /&gt;
declared in the 'generate' clause. So because generate/tangent has &lt;br /&gt;
value 6 and my_tangent_attribute has index 6, my_tangent_attribute &lt;br /&gt;
holds the tangent value for the vertex.&lt;br /&gt;
&lt;br /&gt;
=== technique ===&lt;br /&gt;
A certain way of rendering this effect. Different pipelines typically have their own techniques.&lt;br /&gt;
&lt;br /&gt;
==== scheme ====&lt;br /&gt;
Used by the [[Compositor]] to choose which implementation of an Effect to render. For example, if a Compositor scene pass specifies the &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; scheme, all techniques that use &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; will be used to render the pass. If an Effect doesn't contain a technique that implements this scheme, the object will be ignored and not rendered on that pass. Techniques with no scheme are considered ''default'' and will be used by scene passes when no explicit scheme has been provided.&lt;br /&gt;
&lt;br /&gt;
==== predicate ====&lt;br /&gt;
A technique can contain a predicate that describes the OpenGL&lt;br /&gt;
functionality required to support the technique. The first&lt;br /&gt;
technique with a valid predicate in the list of techniques is used&lt;br /&gt;
to set up the graphics state of the effect. A technique with no&lt;br /&gt;
predicate is always assumed to be valid. The predicate is written in a&lt;br /&gt;
little expression language that supports the following primitives:&lt;br /&gt;
&lt;br /&gt;
and, or, equal, less, less-equal&lt;br /&gt;
glversion - returns the version number of OpenGL&lt;br /&gt;
extension-supported - returns true if an OpenGL extension is supported&lt;br /&gt;
property - returns the boolean value of a property&lt;br /&gt;
float-property - returns the float value of a property, useful inside equal, less or less-equal nodes&lt;br /&gt;
shader-language - returns the version of GLSL supported, or 0 if there is none.&lt;br /&gt;
&lt;br /&gt;
The proper way to test whether to enable a shader-based technique is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;predicate&amp;gt;&lt;br /&gt;
	  &amp;lt;and&amp;gt;&lt;br /&gt;
		&amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
		&amp;lt;less-equal&amp;gt;&lt;br /&gt;
		  &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;1.0&amp;lt;/value&amp;gt;&lt;br /&gt;
		  &amp;lt;shader-language/&amp;gt;&lt;br /&gt;
		&amp;lt;/less-equal&amp;gt;&lt;br /&gt;
	  &amp;lt;/and&amp;gt;&lt;br /&gt;
	&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is also a property set by the user to indicate what is the level &lt;br /&gt;
of quality desired. This level of quality can be checked in the predicate&lt;br /&gt;
like this :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;predicate&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
        &amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
	&amp;lt;less-equal&amp;gt;&lt;br /&gt;
	  &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
	  &amp;lt;float-property&amp;gt;/sim/rendering/quality-level&amp;lt;/float-property&amp;gt;&lt;br /&gt;
	&amp;lt;/less-equal&amp;gt;&lt;br /&gt;
	&amp;lt;!-- other predicate conditions --&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
    &amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
The range of /sim/rendering/quality-level is [0..5]&lt;br /&gt;
 * 2.0 is the threshold for relief mapping effects,&lt;br /&gt;
 * 4.0 is the threshold for geometry shader usage.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
		&amp;lt;and&amp;gt;&lt;br /&gt;
		  &amp;lt;property&amp;gt;/sim/rendering/shaders/quality-level&amp;lt;/property&amp;gt;&lt;br /&gt;
		  &amp;lt;property&amp;gt;/sim/rendering/shaders/model&amp;lt;/property&amp;gt;&lt;br /&gt;
		  &amp;lt;or&amp;gt;&lt;br /&gt;
			&amp;lt;less-equal&amp;gt;&lt;br /&gt;
			  &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
			  &amp;lt;glversion/&amp;gt;&lt;br /&gt;
			&amp;lt;/less-equal&amp;gt;&lt;br /&gt;
			&amp;lt;and&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_shader_objects&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_shading_language_100&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_vertex_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_fragment_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			&amp;lt;/and&amp;gt;&lt;br /&gt;
		  &amp;lt;/or&amp;gt;&lt;br /&gt;
		&amp;lt;/and&amp;gt;&lt;br /&gt;
	  &amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pass ====&lt;br /&gt;
A technique can consist of several passes. A pass is basically an Open&lt;br /&gt;
Scene Graph StateSet. Ultimately all OpenGL and OSG modes and state&lt;br /&gt;
attributes  will be accessable in techniques. State attributes -- that&lt;br /&gt;
is, technique properties that have children and are not just boolean&lt;br /&gt;
modes -- have an &amp;lt;active&amp;gt; parameter which enables or disables the&lt;br /&gt;
attribute. In this way a technique can declare parameters it needs,&lt;br /&gt;
but not enable the attribute at all if it is not needed; the decision&lt;br /&gt;
can be based on a parameter in the parameters section of the&lt;br /&gt;
effect. For example, effects that support transparent and opaque&lt;br /&gt;
geometry could have as part of a technique:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;blend&amp;gt;&lt;br /&gt;
		&amp;lt;active&amp;gt;&amp;lt;use&amp;gt;blend/active&amp;lt;/use&amp;gt;&amp;lt;/active&amp;gt;&lt;br /&gt;
		&amp;lt;source&amp;gt;src-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
		&amp;lt;destination&amp;gt;one-minus-src-alpha&amp;lt;/destination&amp;gt;&lt;br /&gt;
	  &amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So if the blend/active parameter is true blending will be activated&lt;br /&gt;
using the usual blending equation; otherwise blending is disabled.&lt;br /&gt;
&lt;br /&gt;
Values are assigned to technique properties in several ways:&lt;br /&gt;
&lt;br /&gt;
	* They can appear directly in the techniques section as a&lt;br /&gt;
		constant. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;uniform&amp;gt;&lt;br /&gt;
			&amp;lt;name&amp;gt;ColorsTex&amp;lt;/name&amp;gt;&lt;br /&gt;
			&amp;lt;type&amp;gt;sampler-1d&amp;lt;/type&amp;gt;&lt;br /&gt;
			&amp;lt;value type=&amp;quot;int&amp;quot;&amp;gt;2&amp;lt;/value&amp;gt;&lt;br /&gt;
		&amp;lt;/uniform&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		* The name of a property in the parameters section can be&lt;br /&gt;
		referenced using a &amp;quot;use&amp;quot; clause. For example, in the technique&lt;br /&gt;
		section:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;material&amp;gt;&lt;br /&gt;
			&amp;lt;ambient&amp;gt;&amp;lt;use&amp;gt;material/ambient&amp;lt;/use&amp;gt;&amp;lt;/ambient&amp;gt;&lt;br /&gt;
		&amp;lt;/material&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		Then, in the parameters section of the effect:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;parameters&amp;gt;&lt;br /&gt;
			&amp;lt;material&amp;gt;&lt;br /&gt;
				&amp;lt;ambient type=&amp;quot;vec4d&amp;quot;&amp;gt;0.2 0.2 0.2 1.0&amp;lt;/ambient&amp;gt;&lt;br /&gt;
			&amp;lt;/material&amp;gt;&lt;br /&gt;
		&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		It's worth pointing out that the &amp;quot;material&amp;quot; property in a&lt;br /&gt;
		technique specifies part of OpenGL's state, whereas &amp;quot;material&amp;quot;&lt;br /&gt;
		in the parameters section is just a name, part of a&lt;br /&gt;
		hierarchical namespace.&lt;br /&gt;
&lt;br /&gt;
		* A property in the parameters section doesn't need to contain&lt;br /&gt;
		a constant value; it can also contain a &amp;quot;use&amp;quot; property. Here&lt;br /&gt;
		the value of the use clause is the name of a node in an&lt;br /&gt;
		external property tree which will be used as the source of a&lt;br /&gt;
		value. If the name begins with '/', the node is in&lt;br /&gt;
		FlightGear's global property tree; otherwise, it is in a local&lt;br /&gt;
		property tree, usually belonging to a model [NOT IMPLEMENTED&lt;br /&gt;
		YET]. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;parameters&amp;gt;&lt;br /&gt;
			&amp;lt;chrome-light&amp;gt;&amp;lt;use&amp;gt;/rendering/scene/chrome-light&amp;lt;/use&amp;gt;&amp;lt;/chrome-light&amp;gt;&lt;br /&gt;
		&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		The type is determined by what is expected by the technique&lt;br /&gt;
		attribute that will ultimately receive the value. [There is&lt;br /&gt;
		no way to get vector values out of the main property system&lt;br /&gt;
		yet; this will be fixed shortly.] Values that are declared&lt;br /&gt;
		this way are dynamically updated if the property node&lt;br /&gt;
		changes.&lt;br /&gt;
&lt;br /&gt;
===== lighting =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== material =====&lt;br /&gt;
children: active, ambient, ambient-front, ambient-back, diffuse,&lt;br /&gt;
		 diffuse-front, diffuse-back, specular, specular-front,&lt;br /&gt;
		 specular-back, emissive, emissive-front, emissive-back, shininess,&lt;br /&gt;
		 shininess-front, shininess-back, color-mode&lt;br /&gt;
&lt;br /&gt;
===== blend =====&lt;br /&gt;
Children: active, source, destination, source-rgb, source-alpha, destination-rgb, destination-alpha&lt;br /&gt;
&lt;br /&gt;
Children values: dst-alpha, dst-color, one, one-minus-dst-alpha, one-minus-dst-color, one-minus-src-alpha, one-minus-src-color, src-alpha, src-alpha-saturate, src-color, constant-color, one-minus-constant-color, constant-alpha, one-minus-constant-alpha, zero&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;blend&amp;gt;&lt;br /&gt;
                        &amp;lt;active&amp;gt;true&amp;lt;/active&amp;gt;&lt;br /&gt;
                        &amp;lt;source&amp;gt;one-minus-dst-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
			&amp;lt;destination&amp;gt;src-alpha-saturate&amp;lt;/destination&amp;gt;&lt;br /&gt;
		&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== blend (simple) =====&lt;br /&gt;
A blend tag with 0 will do nothing.&lt;br /&gt;
A blend tag with 1 will do the same as source-alpha: one-minus-dst-alpha, in other words it will enable z transparency using alpha from the fragment shader.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;blend&amp;gt;1&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== shade-model =====&lt;br /&gt;
flat or smooth&lt;br /&gt;
&lt;br /&gt;
===== cull-face =====&lt;br /&gt;
front, back, front-back, off&lt;br /&gt;
&lt;br /&gt;
===== texture-unit =====&lt;br /&gt;
unit: integer denoting which unit it is&lt;br /&gt;
&lt;br /&gt;
image: the texture path&lt;br /&gt;
&lt;br /&gt;
images: multiple texture paths&lt;br /&gt;
&lt;br /&gt;
type: 2d, noise, cubemap, 3d (3d was added in 2020.1 and is used for layers of 2d textures defining a volumetric 3d texture)&lt;br /&gt;
&lt;br /&gt;
filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
mag-filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
wrap: repeat, clamp-to-edge, clamp-to-border, clamp, mirror&lt;br /&gt;
&lt;br /&gt;
internal-format: normalized&lt;br /&gt;
&lt;br /&gt;
environment: mode, color&lt;br /&gt;
:mode: add,blend,decal,modulate,replace&lt;br /&gt;
:color: rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: replace, modulate, add, add-signed, interpolate, subtract, dot3-rgb, dot3-rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: combine-rgb, combine-alpha, source0-rgb, source1-rgb, source2-rgb, source0-alpha, source1-alpha,source2-alpha,operand0-rgb,operand1-rgb,operand2-rgb,operand0-alpha,operand1-alpha,operand2-alpha,scale-rgb,scale-alpha&lt;br /&gt;
&lt;br /&gt;
point-sprite: true, false&lt;br /&gt;
&lt;br /&gt;
mipmap-control functions: auto, average, sum, product, min, max&lt;br /&gt;
&lt;br /&gt;
texgen:&lt;br /&gt;
:mode: object-linear, eye-linear, sphere-map, normal-map, reflection-map&lt;br /&gt;
:planes: s, t, r, q as doubles&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;texture-unit&amp;gt;&lt;br /&gt;
                        &amp;lt;unit&amp;gt;3&amp;lt;/unit&amp;gt;&lt;br /&gt;
			&amp;lt;image&amp;gt;Textures/Terrain/void.png&amp;lt;/image&amp;gt;&lt;br /&gt;
			&amp;lt;type&amp;gt;2d&amp;lt;/type&amp;gt;&lt;br /&gt;
			&amp;lt;filter&amp;gt;linear-mipmap-linear&amp;lt;/filter&amp;gt;&lt;br /&gt;
                        &amp;lt;mag-filter&amp;gt;linear-mipmap-linear&amp;lt;/mag-filter&amp;gt;&lt;br /&gt;
			&amp;lt;wrap-s&amp;gt;repeat&amp;lt;/wrap-s&amp;gt;&lt;br /&gt;
			&amp;lt;wrap-t&amp;gt;repeat&amp;lt;/wrap-t&amp;gt;&lt;br /&gt;
                        &amp;lt;wrap-r&amp;gt;repeat&amp;lt;/wrap-r&amp;gt;&lt;br /&gt;
			&amp;lt;internal-format&amp;gt;normalized&amp;lt;/internal-format&amp;gt;&lt;br /&gt;
                        &amp;lt;mipmap-control&amp;gt;&lt;br /&gt;
                            &amp;lt;function-r&amp;gt;average&amp;lt;/function-r&amp;gt;&lt;br /&gt;
			    &amp;lt;function-g&amp;gt;min&amp;lt;/function-g&amp;gt;&lt;br /&gt;
                            &amp;lt;function-b&amp;gt;sum&amp;lt;/function-b&amp;gt;&lt;br /&gt;
			    &amp;lt;function-a&amp;gt;product&amp;lt;/function-a&amp;gt;&lt;br /&gt;
                        &amp;lt;/mipmap-control&amp;gt;&lt;br /&gt;
                        &amp;lt;environment&amp;gt;&lt;br /&gt;
                            &amp;lt;mode&amp;gt;decal&amp;lt;/mode&amp;gt; &lt;br /&gt;
                            &amp;lt;color&amp;gt;0.0 0.1 0.6 1.0&amp;lt;/color&amp;gt;&lt;br /&gt;
                        &amp;lt;/environment&amp;gt;&lt;br /&gt;
                        &amp;lt;point-sprite&amp;gt;true&amp;lt;/point-sprite&amp;gt;&lt;br /&gt;
                        &amp;lt;texenv-combine&amp;gt;operand0-rgb&amp;lt;/texenv-combine&amp;gt;&lt;br /&gt;
                        &amp;lt;texgen&amp;gt;&lt;br /&gt;
                            &amp;lt;mode&amp;gt;S&amp;lt;/mode&amp;gt;&lt;br /&gt;
                            &amp;lt;planes&amp;gt;0.075, 0.0, 0.0, 0.5&amp;lt;/planes&amp;gt;&lt;br /&gt;
                        &amp;lt;/texgen&amp;gt;&lt;br /&gt;
		&amp;lt;/texture-unit&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Textures of type 3d has to be packed on the x axis. Here is an example: [https://raw.githubusercontent.com/sebh/TileableVolumeNoise/master/Examples/noiseErosionPacked.jpg noiseErosionPacked.jpg]&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-two-side =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== polygon-mode =====&lt;br /&gt;
children: front, back&lt;br /&gt;
&lt;br /&gt;
Valid values:  fill, line, point&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-point-size =====&lt;br /&gt;
true, false&lt;br /&gt;
&lt;br /&gt;
===== uniform =====&lt;br /&gt;
Data accessible by shaders.&lt;br /&gt;
&lt;br /&gt;
name: the name&lt;br /&gt;
&lt;br /&gt;
type: bool, int, float, float-vec3, float-vec4, sampler-1d, sampler-2d, sampler-3d, sampler-1d-shadow, sampler-2d-shadow, sampler-cube&lt;br /&gt;
&lt;br /&gt;
===== alpha-test =====&lt;br /&gt;
&lt;br /&gt;
active: true, false&lt;br /&gt;
&lt;br /&gt;
comparison: never, less, equal, lequal, greater, notequal, gequal, always&lt;br /&gt;
&lt;br /&gt;
reference: 0 to 1&lt;br /&gt;
&lt;br /&gt;
===== render-bin =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
bin-number: This is an integer defining the order stuff will be rendered in, it can be negative also.&lt;br /&gt;
&lt;br /&gt;
bin-name: RenderBin, DepthSortedBin&lt;br /&gt;
&lt;br /&gt;
===== rendering-hint =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
default, opaque, transparent&lt;br /&gt;
&lt;br /&gt;
This basically just sets Renderbin:&lt;br /&gt;
&lt;br /&gt;
opaque = bin 10, depthsortedbin&lt;br /&gt;
&lt;br /&gt;
transparent = bin 0, renderbin&lt;br /&gt;
&lt;br /&gt;
default = inherit renderbin details from parent node&lt;br /&gt;
&lt;br /&gt;
===== depth =====&lt;br /&gt;
&lt;br /&gt;
* function: Specifies the depth comparison function. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthFunc.xhtml &amp;lt;tt&amp;gt;glDepthFunc&amp;lt;/tt&amp;gt;].&lt;br /&gt;
* near, far: Specify the mapping of depth values from normalized device coordinates to window coordinates. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml &amp;lt;tt&amp;gt;glDepthRange&amp;lt;/tt&amp;gt;]&lt;br /&gt;
* write-mask: Whether to write to the depth buffer or not.&lt;br /&gt;
* enabled: Whether depth testing is enabled or not.&lt;br /&gt;
&lt;br /&gt;
===== define =====&lt;br /&gt;
&lt;br /&gt;
Injects a &amp;lt;tt&amp;gt;#define&amp;lt;/tt&amp;gt; preprocessor directive into the shaders used in this pass. It is then possible to create logic around this define using conventional preprocessor directives like &amp;lt;tt&amp;gt;#ifdef&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;#endif&amp;lt;/tt&amp;gt;, etc. Keep in mind that shaders must import the define before being able to use it. For example, for a define named &amp;lt;tt&amp;gt;USE_TEXTUREMAPPING&amp;lt;/tt&amp;gt;, the following GLSL code must be placed right after the &amp;lt;tt&amp;gt;#version&amp;lt;/tt&amp;gt; directive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
#pragma import_defines(USE_TEXTUREMAPPING)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* name: Name of the define.&lt;br /&gt;
* value: Value of the define (optional).&lt;br /&gt;
&lt;br /&gt;
===== program =====&lt;br /&gt;
* vertex-shader&lt;br /&gt;
* geometry-shader&lt;br /&gt;
* fragment-shader&lt;br /&gt;
* attribute&lt;br /&gt;
* geometry-vertices-out: integer, max number of vertices emitted by geometry shader&lt;br /&gt;
* geometry-input-type: points, lines, lines-adjacency, triangles, triangles-adjacency&lt;br /&gt;
* geometry-output-type: points, line-strip, triangle-strip&lt;br /&gt;
* uniform-block-binding: has name and index (since 2020.1)&lt;br /&gt;
&lt;br /&gt;
example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
				&amp;lt;vertex-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;1&amp;quot;&amp;gt;Shaders/noise.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;2&amp;quot;&amp;gt;Shaders/filters-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
example for clustered lightning in compositor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
				&amp;lt;vertex-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;1&amp;quot;&amp;gt;Shaders/noise.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;2&amp;quot;&amp;gt;Shaders/filters-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
                                &amp;lt;fragment-shader n=&amp;quot;3&amp;quot;&amp;gt;Shaders/ALS/clustered-include.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
                                &amp;lt;uniform-block-binding&amp;gt;&lt;br /&gt;
		                   &amp;lt;name&amp;gt;PointLightBlock&amp;lt;/name&amp;gt;&lt;br /&gt;
		                   &amp;lt;index&amp;gt;5&amp;lt;/index&amp;gt;&lt;br /&gt;
		                &amp;lt;/uniform-block-binding&amp;gt;&lt;br /&gt;
		                &amp;lt;uniform-block-binding&amp;gt;&lt;br /&gt;
		                   &amp;lt;name&amp;gt;SpotLightBlock&amp;lt;/name&amp;gt;&lt;br /&gt;
		                   &amp;lt;index&amp;gt;6&amp;lt;/index&amp;gt;&lt;br /&gt;
		                &amp;lt;/uniform-block-binding&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See this page for more about shaders: [[Howto:Shader programming in FlightGear]]&lt;br /&gt;
&lt;br /&gt;
== Uniforms passed to shaders outside the XML effect framework ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Type&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, view matrix used to transform from world to view space. Same as osg_ViewMatrix, but for fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, view matrix inverse used to transform from view to world space. Same as osg_ViewMatrixInverse but for fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, projection matrix inverse&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionCart&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in cartesian coordinates&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionGeod&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunAmbientColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDiffuseColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunSpecularColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FogColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FogDensity&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ShadowNumber&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ShadowDistances&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_DepthInColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Tells if the depth is stored in a depth texture or a color texture&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Planes&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used to convert the value of the depth buffer to a depth that can be used to compute the eye space position of the fragment&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_BufferSize&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dimensions of the buffer, used to convert gl_FragCoord into the range [0..1][0..1]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG, used only when working on actual geometry. Transforms from world to view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG, used only when working on actual geometry. Transforms from view to world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_SimulationTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_DeltaFrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameNumber&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=37364|title=Application of effects}} - Testing which kind of groups an effect can be applied to and when&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139076</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139076"/>
		<updated>2024-02-07T12:39:14Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001 (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
* Formalize the GLSL version through an env variable in DisplaySettings (setValue). $FG_GLSL_VERSION on every GLSL shader gets replaced by the actual version string&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139075</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139075"/>
		<updated>2024-02-04T21:29:05Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001 (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexMat and make the texture animations an uniform update callback&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139065</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139065"/>
		<updated>2024-02-04T16:03:38Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001 (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
* Remove TexEnv and make the texture animations an uniform update callback.&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=139049</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=139049"/>
		<updated>2024-01-31T00:31:06Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
* Opacity map for environment map. This would allow for more realistic reflections inside the cockpit. We block light coming from everywhere except the windows.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139048</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139048"/>
		<updated>2024-01-30T23:41:42Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Decrease near plane distance to 0.001 (logarithmic depth allows us to do so)&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139047</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139047"/>
		<updated>2024-01-30T23:09:15Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
* Remove all legacy Effects (model-combined, etc.) and their respective HDR implementations&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139009</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139009"/>
		<updated>2024-01-26T23:40:06Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
&lt;br /&gt;
== Classic renderer (non-ALS) ==&lt;br /&gt;
&lt;br /&gt;
* Are we going to keep very low quality shaders that use fixed-function pipeline attributes?&lt;br /&gt;
* What do we do with FGLight and others. C++ code that used to calculate colors and shading. Nowadays this is all done in shaders. Do we keep it?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139008</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139008"/>
		<updated>2024-01-26T22:12:05Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
* EffectGeodes have setMaterial. Probably no longer needed.&lt;br /&gt;
* What to do with default materials from AC3D?&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139007</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139007"/>
		<updated>2024-01-26T21:45:19Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
* Remove redundant stateset stuff in Compositor (mainly CompositorPass). Use effects for that.&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139006</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139006"/>
		<updated>2024-01-26T20:13:41Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** TexEnv and TexGen&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139005</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139005"/>
		<updated>2024-01-26T11:30:51Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;br /&gt;
&lt;br /&gt;
== View and Debug menu rework ==&lt;br /&gt;
&lt;br /&gt;
The menubar is quite organized except for the View and Debug ones.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
&lt;br /&gt;
* Move CompositeViewer menu entries to a separate menu, probably in Debug&lt;br /&gt;
* VR Options stays&lt;br /&gt;
* Stereoscopic View Options. This is probably broken. Check just in case&lt;br /&gt;
* Earthview orbital rendering stays?&lt;br /&gt;
* Instant Replay stays&lt;br /&gt;
* Toggle Glide Slope Tunnel... what to do with this one?&lt;br /&gt;
* Adjust HUD properties. Default HUD is going away. Canvas replacement, where to place its options?&lt;br /&gt;
* Adjust View Position stays&lt;br /&gt;
* Adjust LOD Ranges stays&lt;br /&gt;
* Cockpit View Options stays&lt;br /&gt;
* Rendering Options is the one that's going to require the most amount of work&lt;br /&gt;
* Toggle Fullscreen should go inside Rendering Options, together with other miscellaneous video options&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=139003</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=139003"/>
		<updated>2024-01-26T00:33:47Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
* Opacity map for environment map. This would allow for more realistic reflections inside the cockpit. We block light coming from everywhere except the windows.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139002</id>
		<title>User:Icecode</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Icecode&amp;diff=139002"/>
		<updated>2024-01-26T00:29:01Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mainly interested in the rendering side of things in FlightGear. Currently working on the [[Compositor]], the [[HDR Pipeline]] and miscellaneous effects/shaders.&lt;br /&gt;
&lt;br /&gt;
== Core profile clean-up ==&lt;br /&gt;
&lt;br /&gt;
* Search for all instances of fixed-function pipeline usage in SG and FG&lt;br /&gt;
** GL_FOG&lt;br /&gt;
** GL_LIGHT&lt;br /&gt;
** GL_LIGHTING&lt;br /&gt;
* Search for all instances of osg::StateSet in SG and FG&lt;br /&gt;
** Do we need to apply an effect instead of manually creating the stateset?&lt;br /&gt;
** Are we assigning any fixed-pipeline state to the stateset?&lt;br /&gt;
* Remove hardcoded redout effect by deleting $FG_SRC/Scenery/redout.cxx/hxx&lt;br /&gt;
* Clean renderer.cxx from useless stuff: specular highlights, horizon effect, fog, etc.&lt;br /&gt;
* Clean Effects from fixed-pipeline attributes&lt;br /&gt;
** alpha-test&lt;br /&gt;
** lighting&lt;br /&gt;
** material&lt;br /&gt;
** shade-model&lt;br /&gt;
** See list of attributes [[Effect_framework#The_XML_tags_of_an_effect|here]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138991</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138991"/>
		<updated>2024-01-21T23:57:46Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138986</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138986"/>
		<updated>2024-01-19T17:34:50Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Add support for PBR material animations. Instead of ambient/diffuse/specular material animations, we should allow base color/metallic/roughness animations.&lt;br /&gt;
* Make life easier for aircraft developers when it comes to supporting both ALS and HDR. Give proper guidelines on how to develop an aircraft for HDR using modern PBR conventions.&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138985</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138985"/>
		<updated>2024-01-19T16:58:59Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Add proper support for osgText.&lt;br /&gt;
* Make life easier for aircraft developers when it comes to supporting both ALS and HDR. Give proper guidelines on how to develop an aircraft for HDR using modern PBR conventions.&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138940</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138940"/>
		<updated>2024-01-09T11:49:13Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Add proper support for osgText.&lt;br /&gt;
* Make life easier for aircraft developers when it comes to supporting both ALS and HDR. Give proper guidelines on how to develop an aircraft for HDR using modern PBR conventions.&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
* Add support for texture animations.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138684</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138684"/>
		<updated>2023-11-17T11:55:32Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Add proper support for osgText.&lt;br /&gt;
* Make life easier for aircraft developers when it comes to supporting both ALS and HDR. Give proper guidelines on how to develop an aircraft for HDR using modern PBR conventions.&lt;br /&gt;
* Integrate the fog and aerosols system with [[local weather]].&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
* Add support for texture animations.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138678</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138678"/>
		<updated>2023-11-13T21:07:36Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Add proper support for osgText.&lt;br /&gt;
* Make life easier for aircraft developers when it comes to supporting both ALS and HDR. Give proper guidelines on how to develop an aircraft for HDR using modern PBR conventions.&lt;br /&gt;
* Integrate the fog and aerosols system with [[local weather]].&lt;br /&gt;
* Create a new particle system that can use custom shaders.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138615</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138615"/>
		<updated>2023-11-06T21:27:49Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
* Fix depth precision issues. This will involve using a reversed depth buffer.&lt;br /&gt;
* Add support for [[procedural texturing]] in the WS 3.0 shaders.&lt;br /&gt;
* Add shaders for scenery lights.&lt;br /&gt;
* Fix random buildings crashing on some systems. Hopefully this will probably go away by itself once we switch to the core profile.&lt;br /&gt;
* Add proper support for osgText.&lt;br /&gt;
* Make life easier for aircraft developers when it comes to supporting both ALS and HDR. Give proper guidelines on how to develop an aircraft for HDR using modern PBR conventions.&lt;br /&gt;
* Integrate the fog and aerosols system with [[local weather]].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138614</id>
		<title>HDR Pipeline</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=HDR_Pipeline&amp;diff=138614"/>
		<updated>2023-11-06T21:20:01Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
&lt;br /&gt;
{{infobox subsystem&lt;br /&gt;
|image       = HDR pipeline c172p over TFFF.png&lt;br /&gt;
|name        = HDR Pipeline&lt;br /&gt;
|started     = 04/2021&lt;br /&gt;
|description = A modern rendering pipeline that targets relatively powerful systems&lt;br /&gt;
|status      = In development&lt;br /&gt;
|developers  = Fernando García Liñán &amp;lt;ref&amp;gt;https://sourceforge.net/u/fgarlin/profile/&amp;lt;/ref&amp;gt;&lt;br /&gt;
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss&lt;br /&gt;
|folders = &lt;br /&gt;
* {{fgdata file|Compositor/HDR}}&lt;br /&gt;
* {{fgdata file|Effects/HDR}}&lt;br /&gt;
* {{fgdata file|Shaders/HDR}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
&lt;br /&gt;
The '''HDR Pipeline''' is a [[Compositor]]-based rendering pipeline that attempts to bring modern rendering techniques to FlightGear, namely {{wikipedia|High dynamic range|high dynamic range (HDR)}} and {{wikipedia|Physically based rendering|physically based rendering (PBR)}}. It is implemented entirely in [[$FG_ROOT]] using XML for the Compositor pipeline definition and [[Effects]], and GLSL for shaders. The pipeline can be enabled with the command line argument &amp;lt;code&amp;gt;--compositor=Compositor/HDR/hdr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
The [[Classic Pipeline]] relies on legacy [[OpenGL]] features, so rather than improving or reworking it, the idea of creating an entirely separate rendering pipeline from scratch started taking shape. The [[Compositor]] played the biggest role in enabling this effort as it allows the creation of new rendering pipelines entirely in FGData space without any C++ changes whatsoever, greatly reducing the amount of work that had to be done and making the iterative process of testing and debugging much faster.&lt;br /&gt;
&lt;br /&gt;
== Status ==&lt;br /&gt;
'''Last updated: 11/2023'''&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline is more or less stable, and is currently available on &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; for anyone adventurous enough to try it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the HDR pipeline might not work in your system until we finish [[FlightGear and OpenGL Core Profile|moving to the OpenGL core profile]]. AMD graphics cards (regardless of age) and Intel integrated GPUs are known to be problematic.&lt;br /&gt;
&lt;br /&gt;
== Notes for aircraft developers ==&lt;br /&gt;
&lt;br /&gt;
The HDR pipeline handles lighting in a completely different manner compared to [[Atmospheric light scattering|ALS]]. The pipeline will attempt to &amp;quot;translate&amp;quot; classic Effects so they display correctly by making some assumptions. These assumptions are not always correct, so your aircraft might not display correctly under the HDR pipeline. In this section we describe some steps you can follow to leverage all the power of the HDR pipeline.&lt;br /&gt;
&lt;br /&gt;
=== PBR and glTF ===&lt;br /&gt;
&lt;br /&gt;
Physically-based rendering (PBR) refers to the concept of using realistic shading/lighting models along with measured surface values to accurately represent real-world materials. See this [https://marmoset.co/posts/physically-based-rendering-and-you-can-too/ webpage] for an extensive introduction to PBR and how you can create physically-based assets for your aircraft.&lt;br /&gt;
&lt;br /&gt;
This pipeline introduces a PBR Effect ({{fgdata file|Effects/model-pbr.eff}}). However, you don't need to assign this Effect manually. You can export your model from Blender to the [[glTF]] format and use it directly. The Blender exporter will take care of exporting the necessary textures and the FlightGear parser will automatically assign the PBR Effect to your model. Your model XML file would contain something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;PropertyList&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;my-aircraft.gltf&amp;lt;/path&amp;gt;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although '''not recommended''', the PBR effect can be assigned as usual by adding an &amp;lt;tt&amp;gt;&amp;lt;effect&amp;gt;&amp;lt;/tt&amp;gt; tag in the model XML and configuring it like you would configure [[Model-combined effect|model-combined]].&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
Lights are defined using the [[Compositor#Lights|Compositor syntax]]. However, since we are dealing with physically-based values, the ambient/diffuse/specular values are ignored and the &amp;lt;tt&amp;gt;color&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;intensity&amp;lt;/tt&amp;gt; parameters are used instead. The &amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt; parameter is also ignored.&lt;br /&gt;
&lt;br /&gt;
It is possible to have a light definition that is compatible with both ALS and HDR by defining all parameters at the same time. This might be troublesome though because the same values might yield different results under each pipeline.&lt;br /&gt;
&lt;br /&gt;
An example light definition is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;light&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;my-spotlight&amp;lt;/name&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;spot&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;position&amp;gt;&lt;br /&gt;
    &amp;lt;x-m&amp;gt;-7.7476&amp;lt;/x-m&amp;gt;&lt;br /&gt;
    &amp;lt;y-m&amp;gt;0&amp;lt;/y-m&amp;gt;&lt;br /&gt;
    &amp;lt;z-m&amp;gt;-1.7990&amp;lt;/z-m&amp;gt;&lt;br /&gt;
  &amp;lt;/position&amp;gt;&lt;br /&gt;
  &amp;lt;direction&amp;gt;&lt;br /&gt;
    &amp;lt;x&amp;gt;-1.0&amp;lt;/x&amp;gt;&lt;br /&gt;
    &amp;lt;y&amp;gt;0&amp;lt;/y&amp;gt;&lt;br /&gt;
    &amp;lt;z&amp;gt;-0.013&amp;lt;/z&amp;gt;&lt;br /&gt;
  &amp;lt;/direction&amp;gt;&lt;br /&gt;
  &amp;lt;color&amp;gt;&lt;br /&gt;
    &amp;lt;r&amp;gt;1.0&amp;lt;/r&amp;gt;&lt;br /&gt;
    &amp;lt;g&amp;gt;0.0&amp;lt;/g&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;0.0&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;/color&amp;gt;&lt;br /&gt;
  &amp;lt;intensity&amp;gt;10&amp;lt;/intensity&amp;gt;&lt;br /&gt;
  &amp;lt;spot-exponent&amp;gt;5&amp;lt;/spot-exponent&amp;gt;&lt;br /&gt;
  &amp;lt;spot-cutoff&amp;gt;40&amp;lt;/spot-cutoff&amp;gt;&lt;br /&gt;
  &amp;lt;range-m&amp;gt;50&amp;lt;/range-m&amp;gt;&lt;br /&gt;
&amp;lt;/light&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Compositor]]&lt;br /&gt;
* [[glTF]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Compositor Pipelines]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Virtual_FSweekend_Hackathon_2023&amp;diff=138435</id>
		<title>Virtual FSweekend Hackathon 2023</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Virtual_FSweekend_Hackathon_2023&amp;diff=138435"/>
		<updated>2023-09-26T00:45:08Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Normally in mid-November a group of FlightGear enthusiasts participate in [[FSWeekend]] in [https://www.aviodrome.nl/ Aviodrome] at the [https://www.lelystadairport.nl/ Lelystad Airport] in the Netherlands. Over the years this has been a focal point for both finishing existing development/releases and a catalyst for new ideas in FlightGear, as well as an opportunity for FlightGear enthusiasts to share a beer. This year the [https://www.aviodrome.nl/evenementen/flight-simulator/?_gl=1*1hh597t*_up*MQ..&amp;amp;gclid=EAIaIQobChMIhdjmndaLgQMVKpiDBx3wFwOwEAAYASAAEgI64vD_BwE Flight Simulator Weekend] has been re-scheduled to March 16/17 2024.&lt;br /&gt;
&lt;br /&gt;
To keep the spirit alive and repeat the successful execution of the [[Virtual_FSweekend_Hackathon_2020|Virtual FSweekend Hackathon 2020]] and [[Virtual_FSweekend_Hackathon_2021|Virtual FSweekend Hackathon 2021]], we are planning to hold another Virtual FSweekend Hackathon on the weekend of {{{days_string|10/11/12}}} November {{{year|2023}}} (in {{days from now|{{{year|2023}}}|11|10}}).&lt;br /&gt;
&lt;br /&gt;
== Hackathon? ==&lt;br /&gt;
For those who have not participated in a hackathon before, the broad idea is to get people from a wide variety of experience and backgrounds together to solve problems over a short period of time - typically 24 or 48 hours. Details vary, but typically at the start of the event, people pitch ideas and groups form organically based on what people are interested in. The groups then work together intensively, often fueled by pizza and caffeine etc. At the end of the hackathon the groups present their work and there are often prizes for the best hacks.&lt;br /&gt;
&lt;br /&gt;
The general idea of virtual FSWeekend hackathons is to encourage existing and new contributors to collaborate over the course of a weekend to create new and exciting features for FlightGear in the broadest sense. The core developers would particularly like to use it as an opportunity to encourage people to get their hands dirty in the core code, so they will be primarily there to help/coach people rather than hacking themselves, but anything is possible :)&lt;br /&gt;
&lt;br /&gt;
No prior development experience is necessary - there might be run some education sessions ahead of the weekend so people can hit the ground running (otherwise you will learn during the hackathon). Also, do not feel you have to commit to coding the entire weekend to the exclusion of all else. We think participants will still get real value if they can just commit to one day and some late evenings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Only Core Development? ==&lt;br /&gt;
While the core of the hackathon incl. support previously has been dedicated to development in the very core of FlightGear (mostly C++, [[Nasal_scripting_language|Nasal]] and xml), you are also welcome to participate if you are developing stuff, which contributes to the general FlightGear ecosystem (e.g. [[Addon]], visual artwork or [[Osm2city.py|osm2city]]). However, in that case you might need to provide your own support.&lt;br /&gt;
&lt;br /&gt;
== Sign up ==&lt;br /&gt;
{{Note|There is space for many participants, so don't be shy. {{{organizer|Rick}}} is happy for people to register right up to the Friday night, but we will not be able to help out with getting builds and git working if you leave it that late!}}&lt;br /&gt;
&lt;br /&gt;
To register your participation, please contact {{{organizer|Rick}}} either on the {{forum link|t=41662|text=forum post}}, by PM on the [https://discord.gg/rzuV2DR FlightGear Discord server] or via the [https://sourceforge.net/p/flightgear/mailman/message/37890811/ devel list].  &lt;br /&gt;
&lt;br /&gt;
Confirmed participants (in alphabetical order):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
! aka.&lt;br /&gt;
! Role&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
|Nia&lt;br /&gt;
|[https://forum.flightgear.org/memberlist.php?mode=viewprofile&amp;amp;u=21618 merspieler], Nia on [https://matrix.to/#/#flightgear-jsbsim:hacklab.fi FG Matrix]&lt;br /&gt;
|Infra provider, ask if you've got issues with Mattermost or Jitsi&lt;br /&gt;
|Can help with osm2city data processing (worldbuild stuff)&lt;br /&gt;
|-&lt;br /&gt;
|Rick Gruber-Riemer&lt;br /&gt;
|[https://forum.flightgear.org/memberlist.php?mode=viewprofile&amp;amp;u=9140 vanosten], HB-VANO on FG Discord&lt;br /&gt;
|Organiser/mentor&lt;br /&gt;
|Can coach osm2city and OSM data processing&lt;br /&gt;
|-&lt;br /&gt;
|Stuart Buchanan&lt;br /&gt;
|[[User:Stuart|stuart]]&lt;br /&gt;
|Mentor&lt;br /&gt;
|Can coach on most part of FlightGear.  Particularly interested in WS3.0 at the moment.&lt;br /&gt;
|-&lt;br /&gt;
|Fernando García Liñán&lt;br /&gt;
|[[User:Icecode|icecode]]&lt;br /&gt;
|Mentor&lt;br /&gt;
|Can coach on most of FlightGear, mainly graphics-related stuff. Mainly interested in [[Compositor]] and [[HDR]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ahead of the Hackathon ==&lt;br /&gt;
There are a couple of key activities ahead of the weekend in {{{year|2023}}}.&lt;br /&gt;
&lt;br /&gt;
=== Getting started ===&lt;br /&gt;
So we can hit the ground running, we really want everyone participating to already have:&lt;br /&gt;
* SourceForge credentials&lt;br /&gt;
* A working build environment with [[OpenSceneGraph|OSG]], [[PLIB]] etc.&lt;br /&gt;
* A Git checkout of simgear/flightgear (cf. [[FlightGear_Git]])&lt;br /&gt;
* A Git checkout of fgdata&lt;br /&gt;
* Some experience with [https://git-scm.com/ Git]&lt;br /&gt;
&lt;br /&gt;
At the very least you should be able to work with a [[FlightGear_build_server|nightly version]] of FlightGear.&lt;br /&gt;
&lt;br /&gt;
Before the Hackathon consider having a look into the dedicated [[:Category:Hackathon Materials|Hackathon Materials]] category for articles, which might help get you going.&lt;br /&gt;
&lt;br /&gt;
=== Logistics ===&lt;br /&gt;
Being completely remote, we need the ability to collaborate in teams as well as video conference as a group.&lt;br /&gt;
&lt;br /&gt;
There will be a [https://mattermost.com/ Mattermost] server for the weekend.  We'll be using that for organization, discussion and collaboration.&lt;br /&gt;
&lt;br /&gt;
We'll be using a [https://jitsi.org/ Jitsi] Server for video conferencing and demos.&lt;br /&gt;
&lt;br /&gt;
To use the server, please start the Jitsi calls from within Mattermost (click on that power plug symbol in the top bar next to the search). Preferably use an app or Chrome/Chromium.&lt;br /&gt;
&lt;br /&gt;
=== Ideation ===&lt;br /&gt;
The core of the Hackathon!  These are the projects, ideas and problems that participants will be working on during the weekend. In the weeks before the Hackathon itself, participants can, and should, propose things to work on. Simply create a wiki page describing your idea, and encourage people to contribute and get interested.&lt;br /&gt;
&lt;br /&gt;
Check out the [[:Category:Hackathon {{{year|2023}}} Ideas|Hackathon {{{year|2023}}} Ideas]] category page for a how-to as well as links to existing proposals. &lt;br /&gt;
&lt;br /&gt;
You can also take a look at proposals from the previous years.&lt;br /&gt;
&lt;br /&gt;
Not having an idea?  No problem!  Have a look at the proposed ideas, leave a comment on the Discussion page, and add yourself as an Interested Party for those ideas you consider working on during the Hackathon.  There is no commitment until the start of the Hackathon on Friday evening.&lt;br /&gt;
&lt;br /&gt;
== Schedule ==&lt;br /&gt;
With (hopefully) a world-wide group of participants, and varying real life constraints, at any given time over the weekend there will hopefully be a couple of people active.  &lt;br /&gt;
&lt;br /&gt;
We will have two big get-togethers:&lt;br /&gt;
&lt;br /&gt;
=== {{{kick-off-totd-utc|Friday 10th November 2000-2200 UTC.}}} Kick-off ===&lt;br /&gt;
* General welcome&lt;br /&gt;
* Introductions &lt;br /&gt;
* Hack pitches&lt;br /&gt;
* Team formation&lt;br /&gt;
&lt;br /&gt;
This is the point at which participants will decide, which Hacks they want to work on. The sponsors of each of the Hacks proposed ahead of time will be invited to give a 5 minutes pitch to the group, with some questions from the audience. Slides/screenshots optional.&lt;br /&gt;
&lt;br /&gt;
After all the Hacks have been pitched, we will have a little break for people to chat and work out which Hack they want to work on. &lt;br /&gt;
&lt;br /&gt;
If a Hack ends up with fewer than 2 people wanting to work on it (including the sponsor), then it will normally be dropped.  This is to encourage people to work in groups - larger teams can get more done in the time, and have more opportunities to learn from each other, plus it is more sociable!&lt;br /&gt;
&lt;br /&gt;
=== {{{wrap-up-totd-utc|Sunday 12th November 2000-2200 UTC.}}}  Wrap up and demos ===&lt;br /&gt;
At the end of the hackathon we will have a get together and have each team present the results of their hack.  &lt;br /&gt;
&lt;br /&gt;
Depending on the number of hacks, each team will have 5-15 minutes to demonstrate their hack, describe what they have learned, and what their next steps are.&lt;br /&gt;
&lt;br /&gt;
We will finish with voting for the best hack of the weekend.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
'''Q''': What is the aim of the Hackathon?&amp;lt;br /&amp;gt;&lt;br /&gt;
'''A''': To learn and have fun hacking FlightGear.  Encourage people to get their hands dirty and modify code.  Try out new ideas.  Working with other people.  Ultimately to increase the number of core developers.&lt;br /&gt;
&lt;br /&gt;
'''Q''': What can participants expect to get out of the weekend?&amp;lt;br /&amp;gt;&lt;br /&gt;
'''A''': The primary goal is for people to learn through experimentation.  To try out new ideas and in the process learn about the internals of FlightGear.  James, Stuart and Fernando will be be providing coaching over the course of the weekend.&lt;br /&gt;
&lt;br /&gt;
'''Q''': What organization will be provided?&amp;lt;br /&amp;gt;&lt;br /&gt;
'''A''': We will provide tools for collaboration, and organize a couple of meetings, but not much more.  The idea behind hackathons is that participants largely self organize - teams form around interesting ideas on Friday evening and organize themselves.  Participants will need to provide their own computers, pizza, Haribo, beer.  The last three are traditional, but optional.&lt;br /&gt;
&lt;br /&gt;
'''Q''': How much time do I need to commit?&amp;lt;br /&amp;gt;&lt;br /&gt;
'''A''': The more the better.  A traditional hackathon would be 24-48 hours of solid work with sleep optional.  That is not realistic for most people, but 20 hours over the weekend would be a good amount to aim for.  Certainly if you can only commit to a couple of evenings you may not get much out of Hackathon.&lt;br /&gt;
&lt;br /&gt;
'''Q''': What skills do I need?&amp;lt;br /&amp;gt;&lt;br /&gt;
'''A''': It depends on what you want to do.  You need to know C/C++ already to be able to hack the core of FlightGear.  The Hackathon is not a good place to learn C++ for the first time.  However, there are lot of interesting projects using Python, Nasal etc.  &lt;br /&gt;
&lt;br /&gt;
'''Q''': I have got a great idea for the Hackathon.  What do I do?&amp;lt;br /&amp;gt;&lt;br /&gt;
'''A''': Great!  Create a wiki page describing it to enthuse other people and collect comments (see [[#Ideation]] section above), and post a link to the Ideation section above so everyone can see it.&lt;br /&gt;
&lt;br /&gt;
[[Category:Hackathon Materials]]&lt;br /&gt;
[[Category:Hackathons]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=137635</id>
		<title>Effect framework</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Effect_framework&amp;diff=137635"/>
		<updated>2023-05-05T04:53:23Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{forum|47|Effects &amp;amp; Shaders}}&lt;br /&gt;
{{Rendering}}&lt;br /&gt;
The '''Effect framework''' as per FlightGear version 2020.3&lt;br /&gt;
&lt;br /&gt;
Effects describe the graphical appearance of 3D objects and scenery in&lt;br /&gt;
FlightGear. The main motivation for effects is to support OpenGL&lt;br /&gt;
shaders and to provide different implementations for graphics hardware&lt;br /&gt;
of varying capabilities. Effects are similar to DirectX effects files&lt;br /&gt;
and Ogre3D material scripts.&lt;br /&gt;
&lt;br /&gt;
An effect is a property list. The property list syntax is extended&lt;br /&gt;
with new &amp;quot;vec3d&amp;quot; and &amp;quot;vec4d&amp;quot; types to support common computer graphics&lt;br /&gt;
values. Effects are read from files with a &amp;quot;.eff&amp;quot; extension or can be&lt;br /&gt;
created on-the-fly by FlightGear at runtime.  An effect consists of a&lt;br /&gt;
&amp;quot;parameters&amp;quot; section followed by &amp;quot;technique&amp;quot; descriptions.  The&lt;br /&gt;
&amp;quot;parameters&amp;quot; section is a tree of values that describe, abstractly,&lt;br /&gt;
the graphical characteristics of objects that use the effect. Techniques&lt;br /&gt;
refer to these parameters and use them to set OpenGL state or to set&lt;br /&gt;
parameters for shader programs. The names of properties in the&lt;br /&gt;
parameter section can be whatever the effects author chooses, although&lt;br /&gt;
some standard parameters  are set by FlightGear itself. On the other&lt;br /&gt;
hand, the properties in the techniques section are all defined by the&lt;br /&gt;
FlightGear. &lt;br /&gt;
&lt;br /&gt;
== Default effects in terrain materials and models ==&lt;br /&gt;
Effects for terrain work in this way: for each material type in&lt;br /&gt;
materials.xml an effect is created that inherits from a single default&lt;br /&gt;
terrain effect, Effects/terrain-default.eff. The parameters section of&lt;br /&gt;
the effect is filled in using the ambient, diffuse, specular,&lt;br /&gt;
emissive, shininess, and transparent fields of the material. The&lt;br /&gt;
parameters image, filter, wrap-s, and wrap-t are also initialized from&lt;br /&gt;
the material xml. Seperate effects are created for each texture&lt;br /&gt;
variant of a material.&lt;br /&gt;
&lt;br /&gt;
Model effects are created by walking the OpenSceneGraph scene graph&lt;br /&gt;
for a model and replacing nodes (osg::Geode) that have state sets with&lt;br /&gt;
node that uses an effect instead. Again, a small effect is created&lt;br /&gt;
with parameters extracted from OSG objects; this effect inherits, by&lt;br /&gt;
default, from Effects/model-default.eff. A larger set of parameters is&lt;br /&gt;
created for model effects than for terrain because there is more&lt;br /&gt;
variation possible from the OSG model loaders than from the terrain&lt;br /&gt;
system. The parameters created are: &lt;br /&gt;
&lt;br /&gt;
* material active, ambient, diffuse, specular, emissive, shininess, color mode&lt;br /&gt;
# blend active, source, destination&lt;br /&gt;
# shade-model&lt;br /&gt;
# cull-face&lt;br /&gt;
* rendering-hint&lt;br /&gt;
* texture type, image, filter, wrap-s, wrap-t&lt;br /&gt;
&lt;br /&gt;
== Specifying custom effects ==&lt;br /&gt;
You can specify the effects that will be used by FlightGear as the&lt;br /&gt;
base effect when it creates terrain and model effects.&lt;br /&gt;
&lt;br /&gt;
In the terrain materials.xml, an &amp;quot;effect&amp;quot; property specifies the name&lt;br /&gt;
of the model to use.&lt;br /&gt;
&lt;br /&gt;
Material animations will be implemented by creating a new effect&lt;br /&gt;
that inherits from one in a model, overriding the parameters that&lt;br /&gt;
will be animated.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
The $FGDATA/Effects directory contains the effects definitions; look there for&lt;br /&gt;
examples. Effects/crop.eff is a good example of a complex effect.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
To apply an effect to a model or part of a model use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;effect&amp;gt;&lt;br /&gt;
		&amp;lt;inherits-from&amp;gt;Effects/light-cone&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
		&amp;lt;object-name&amp;gt;Cone&amp;lt;/object-name&amp;gt;&lt;br /&gt;
	&amp;lt;/effect&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;inherits-from&amp;gt; &amp;lt;/inherits-from&amp;gt; contains the path to the effect you want to apply.&lt;br /&gt;
The effect does not need the file extension.&lt;br /&gt;
&lt;br /&gt;
=== Parameters in model file ===&lt;br /&gt;
&lt;br /&gt;
Parameters can be put into the model files effect application as well. But only bool, int, float, string can be used there.&lt;br /&gt;
&lt;br /&gt;
=== Chrome old usage ===&lt;br /&gt;
&lt;br /&gt;
Chrome, although now implemented as an effect, still retains the old method of application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;animation&amp;gt;&lt;br /&gt;
			&amp;lt;type&amp;gt;shader&amp;lt;/type&amp;gt;&lt;br /&gt;
			&amp;lt;shader&amp;gt;chrome&amp;lt;/shader&amp;gt;&lt;br /&gt;
			&amp;lt;texture&amp;gt;glass_shader.png&amp;lt;/texture&amp;gt;&lt;br /&gt;
			&amp;lt;object-name&amp;gt;windscreen&amp;lt;/object-name&amp;gt;&lt;br /&gt;
	&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in order to maintain backward compatibility.&lt;br /&gt;
&lt;br /&gt;
== Reload effects at runtime ==&lt;br /&gt;
To reload an effect applied in a model xml file (e.g. some parameters and what it enherits from) just go into debug menu and select Reload Model.&lt;br /&gt;
&lt;br /&gt;
To reload the entire effect framework including eff files, go into menu and debug and configure development extensions and reload shaders. This is broken in 2020.1 though, but works in earlier FG versions.&lt;br /&gt;
&lt;br /&gt;
== The XML tags of an effect ==&lt;br /&gt;
&lt;br /&gt;
=== name ===&lt;br /&gt;
The name of the effect&lt;br /&gt;
&lt;br /&gt;
=== inherits-from ===&lt;br /&gt;
One feature not fully illustrated in the sample below is that&lt;br /&gt;
effects can inherit from each other. The parent effect is listed in&lt;br /&gt;
the &amp;quot;inherits-from&amp;quot; form. The child effect's property tree is&lt;br /&gt;
overlaid over that of the parent. Nodes that have the same name and&lt;br /&gt;
property index -- set by the &amp;quot;n=&amp;quot; attribute in the property tag --&lt;br /&gt;
are recursively merged. Leaf property nodes from the child have&lt;br /&gt;
precedence.  This means that effects that inherit from the example&lt;br /&gt;
effect below could be very short, listing just new&lt;br /&gt;
parameters and adding nothing to the techniques section;&lt;br /&gt;
alternatively, a technique could be altered or customized in a&lt;br /&gt;
child, listing (for example) a different shader program. An example&lt;br /&gt;
showing inheritance Effects/crop.eff, which inherits some if its&lt;br /&gt;
values from Effects/terrain-default.eff.&lt;br /&gt;
&lt;br /&gt;
FlightGear directly uses effects inheritance to assign effects to 3D&lt;br /&gt;
models and terrain. As described below, at runtime small effects are&lt;br /&gt;
created that contain material and texture values in a &amp;quot;parameters&amp;quot;&lt;br /&gt;
section. These effects inherit from another effect which references&lt;br /&gt;
those parameters in its &amp;quot;techniques&amp;quot; section. The derived effect&lt;br /&gt;
overrides any default values that might be in the base effect's&lt;br /&gt;
parameters section.&lt;br /&gt;
&lt;br /&gt;
=== parameters ===&lt;br /&gt;
Custom parameters that controls the effect.&lt;br /&gt;
&lt;br /&gt;
Note that parameters can use the &amp;lt;use&amp;gt; tags to enable properties to specify the values.&lt;br /&gt;
&lt;br /&gt;
=== generate ===&lt;br /&gt;
&lt;br /&gt;
Often shader effects need tangent vectors to work properly. These &lt;br /&gt;
tangent vectors, usually called tangent and binormal, are computed &lt;br /&gt;
on the CPU and given to the shader as vertex attributes. These &lt;br /&gt;
vectors are computed on demand on the geometry using the effect if &lt;br /&gt;
the 'generate' clause is present in the effect file.&lt;br /&gt;
&lt;br /&gt;
Example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;generate&amp;gt;&lt;br /&gt;
		&amp;lt;tangent type=&amp;quot;int&amp;quot;&amp;gt;6&amp;lt;/tangent&amp;gt;&lt;br /&gt;
		&amp;lt;binormal type=&amp;quot;int&amp;quot;&amp;gt;7&amp;lt;/binormal&amp;gt;&lt;br /&gt;
		&amp;lt;normal type=&amp;quot;int&amp;quot;&amp;gt;8&amp;lt;/normal&amp;gt;&lt;br /&gt;
	&amp;lt;/generate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valid subnodes of 'generate' are 'tangent', 'binormal' or 'normal'.&lt;br /&gt;
The integer value of these subnode is the index of the attribute &lt;br /&gt;
that will hold the value of the vec3 vector.&lt;br /&gt;
&lt;br /&gt;
Normal is really redundant and should not be used, as that is already generated from loading the mesh.&lt;br /&gt;
&lt;br /&gt;
The generate clause is located under PropertyList in the xml file.&lt;br /&gt;
&lt;br /&gt;
In order to be available for the vertex shader, these data should &lt;br /&gt;
be bound to an attribute in the program clause, like this :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;program&amp;gt;&lt;br /&gt;
		&amp;lt;vertex-shader&amp;gt;my_vertex_shader&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;attribute&amp;gt;&lt;br /&gt;
			&amp;lt;name&amp;gt;my_tangent_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
			&amp;lt;index&amp;gt;6&amp;lt;/index&amp;gt;&lt;br /&gt;
		&amp;lt;/attribute&amp;gt;&lt;br /&gt;
		&amp;lt;attribute&amp;gt;&lt;br /&gt;
			&amp;lt;name&amp;gt;my_binormal_attribute&amp;lt;/name&amp;gt;&lt;br /&gt;
			&amp;lt;index&amp;gt;7&amp;lt;/index&amp;gt;&lt;br /&gt;
		&amp;lt;/attribute&amp;gt;&lt;br /&gt;
	&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
attribute names are whatever the shader use. The index is the one &lt;br /&gt;
declared in the 'generate' clause. So because generate/tangent has &lt;br /&gt;
value 6 and my_tangent_attribute has index 6, my_tangent_attribute &lt;br /&gt;
holds the tangent value for the vertex.&lt;br /&gt;
&lt;br /&gt;
=== technique ===&lt;br /&gt;
A certain way of rendering this effect. Different pipelines typically have their own techniques.&lt;br /&gt;
&lt;br /&gt;
==== scheme ====&lt;br /&gt;
Used by the [[Compositor]] to choose which implementation of an Effect to render. For example, if a Compositor scene pass specifies the &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; scheme, all techniques that use &amp;lt;code&amp;gt;test-scheme&amp;lt;/code&amp;gt; will be used to render the pass. If an Effect doesn't contain a technique that implements this scheme, the object will be ignored and not rendered on that pass. Techniques with no scheme are considered ''default'' and will be used by scene passes when no explicit scheme has been provided.&lt;br /&gt;
&lt;br /&gt;
==== predicate ====&lt;br /&gt;
A technique can contain a predicate that describes the OpenGL&lt;br /&gt;
functionality required to support the technique. The first&lt;br /&gt;
technique with a valid predicate in the list of techniques is used&lt;br /&gt;
to set up the graphics state of the effect. A technique with no&lt;br /&gt;
predicate is always assumed to be valid. The predicate is written in a&lt;br /&gt;
little expression language that supports the following primitives:&lt;br /&gt;
&lt;br /&gt;
and, or, equal, less, less-equal&lt;br /&gt;
glversion - returns the version number of OpenGL&lt;br /&gt;
extension-supported - returns true if an OpenGL extension is supported&lt;br /&gt;
property - returns the boolean value of a property&lt;br /&gt;
float-property - returns the float value of a property, useful inside equal, less or less-equal nodes&lt;br /&gt;
shader-language - returns the version of GLSL supported, or 0 if there is none.&lt;br /&gt;
&lt;br /&gt;
The proper way to test whether to enable a shader-based technique is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;predicate&amp;gt;&lt;br /&gt;
	  &amp;lt;and&amp;gt;&lt;br /&gt;
		&amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
		&amp;lt;less-equal&amp;gt;&lt;br /&gt;
		  &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;1.0&amp;lt;/value&amp;gt;&lt;br /&gt;
		  &amp;lt;shader-language/&amp;gt;&lt;br /&gt;
		&amp;lt;/less-equal&amp;gt;&lt;br /&gt;
	  &amp;lt;/and&amp;gt;&lt;br /&gt;
	&amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is also a property set by the user to indicate what is the level &lt;br /&gt;
of quality desired. This level of quality can be checked in the predicate&lt;br /&gt;
like this :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;predicate&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
        &amp;lt;property&amp;gt;/sim/rendering/shader-effects&amp;lt;/property&amp;gt;&lt;br /&gt;
	&amp;lt;less-equal&amp;gt;&lt;br /&gt;
	  &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
	  &amp;lt;float-property&amp;gt;/sim/rendering/quality-level&amp;lt;/float-property&amp;gt;&lt;br /&gt;
	&amp;lt;/less-equal&amp;gt;&lt;br /&gt;
	&amp;lt;!-- other predicate conditions --&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
    &amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
The range of /sim/rendering/quality-level is [0..5]&lt;br /&gt;
 * 2.0 is the threshold for relief mapping effects,&lt;br /&gt;
 * 4.0 is the threshold for geometry shader usage.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;predicate&amp;gt;&lt;br /&gt;
		&amp;lt;and&amp;gt;&lt;br /&gt;
		  &amp;lt;property&amp;gt;/sim/rendering/shaders/quality-level&amp;lt;/property&amp;gt;&lt;br /&gt;
		  &amp;lt;property&amp;gt;/sim/rendering/shaders/model&amp;lt;/property&amp;gt;&lt;br /&gt;
		  &amp;lt;or&amp;gt;&lt;br /&gt;
			&amp;lt;less-equal&amp;gt;&lt;br /&gt;
			  &amp;lt;value type=&amp;quot;float&amp;quot;&amp;gt;2.0&amp;lt;/value&amp;gt;&lt;br /&gt;
			  &amp;lt;glversion/&amp;gt;&lt;br /&gt;
			&amp;lt;/less-equal&amp;gt;&lt;br /&gt;
			&amp;lt;and&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_shader_objects&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_shading_language_100&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_vertex_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			  &amp;lt;extension-supported&amp;gt;GL_ARB_fragment_shader&amp;lt;/extension-supported&amp;gt;&lt;br /&gt;
			&amp;lt;/and&amp;gt;&lt;br /&gt;
		  &amp;lt;/or&amp;gt;&lt;br /&gt;
		&amp;lt;/and&amp;gt;&lt;br /&gt;
	  &amp;lt;/predicate&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== pass ====&lt;br /&gt;
A technique can consist of several passes. A pass is basically an Open&lt;br /&gt;
Scene Graph StateSet. Ultimately all OpenGL and OSG modes and state&lt;br /&gt;
attributes  will be accessable in techniques. State attributes -- that&lt;br /&gt;
is, technique properties that have children and are not just boolean&lt;br /&gt;
modes -- have an &amp;lt;active&amp;gt; parameter which enables or disables the&lt;br /&gt;
attribute. In this way a technique can declare parameters it needs,&lt;br /&gt;
but not enable the attribute at all if it is not needed; the decision&lt;br /&gt;
can be based on a parameter in the parameters section of the&lt;br /&gt;
effect. For example, effects that support transparent and opaque&lt;br /&gt;
geometry could have as part of a technique:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;blend&amp;gt;&lt;br /&gt;
		&amp;lt;active&amp;gt;&amp;lt;use&amp;gt;blend/active&amp;lt;/use&amp;gt;&amp;lt;/active&amp;gt;&lt;br /&gt;
		&amp;lt;source&amp;gt;src-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
		&amp;lt;destination&amp;gt;one-minus-src-alpha&amp;lt;/destination&amp;gt;&lt;br /&gt;
	  &amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So if the blend/active parameter is true blending will be activated&lt;br /&gt;
using the usual blending equation; otherwise blending is disabled.&lt;br /&gt;
&lt;br /&gt;
Values are assigned to technique properties in several ways:&lt;br /&gt;
&lt;br /&gt;
	* They can appear directly in the techniques section as a&lt;br /&gt;
		constant. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;uniform&amp;gt;&lt;br /&gt;
			&amp;lt;name&amp;gt;ColorsTex&amp;lt;/name&amp;gt;&lt;br /&gt;
			&amp;lt;type&amp;gt;sampler-1d&amp;lt;/type&amp;gt;&lt;br /&gt;
			&amp;lt;value type=&amp;quot;int&amp;quot;&amp;gt;2&amp;lt;/value&amp;gt;&lt;br /&gt;
		&amp;lt;/uniform&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		* The name of a property in the parameters section can be&lt;br /&gt;
		referenced using a &amp;quot;use&amp;quot; clause. For example, in the technique&lt;br /&gt;
		section:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;material&amp;gt;&lt;br /&gt;
			&amp;lt;ambient&amp;gt;&amp;lt;use&amp;gt;material/ambient&amp;lt;/use&amp;gt;&amp;lt;/ambient&amp;gt;&lt;br /&gt;
		&amp;lt;/material&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		Then, in the parameters section of the effect:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;parameters&amp;gt;&lt;br /&gt;
			&amp;lt;material&amp;gt;&lt;br /&gt;
				&amp;lt;ambient type=&amp;quot;vec4d&amp;quot;&amp;gt;0.2 0.2 0.2 1.0&amp;lt;/ambient&amp;gt;&lt;br /&gt;
			&amp;lt;/material&amp;gt;&lt;br /&gt;
		&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		It's worth pointing out that the &amp;quot;material&amp;quot; property in a&lt;br /&gt;
		technique specifies part of OpenGL's state, whereas &amp;quot;material&amp;quot;&lt;br /&gt;
		in the parameters section is just a name, part of a&lt;br /&gt;
		hierarchical namespace.&lt;br /&gt;
&lt;br /&gt;
		* A property in the parameters section doesn't need to contain&lt;br /&gt;
		a constant value; it can also contain a &amp;quot;use&amp;quot; property. Here&lt;br /&gt;
		the value of the use clause is the name of a node in an&lt;br /&gt;
		external property tree which will be used as the source of a&lt;br /&gt;
		value. If the name begins with '/', the node is in&lt;br /&gt;
		FlightGear's global property tree; otherwise, it is in a local&lt;br /&gt;
		property tree, usually belonging to a model [NOT IMPLEMENTED&lt;br /&gt;
		YET]. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;parameters&amp;gt;&lt;br /&gt;
			&amp;lt;chrome-light&amp;gt;&amp;lt;use&amp;gt;/rendering/scene/chrome-light&amp;lt;/use&amp;gt;&amp;lt;/chrome-light&amp;gt;&lt;br /&gt;
		&amp;lt;/parameters&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		The type is determined by what is expected by the technique&lt;br /&gt;
		attribute that will ultimately receive the value. [There is&lt;br /&gt;
		no way to get vector values out of the main property system&lt;br /&gt;
		yet; this will be fixed shortly.] Values that are declared&lt;br /&gt;
		this way are dynamically updated if the property node&lt;br /&gt;
		changes.&lt;br /&gt;
&lt;br /&gt;
===== lighting =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== material =====&lt;br /&gt;
children: active, ambient, ambient-front, ambient-back, diffuse,&lt;br /&gt;
		 diffuse-front, diffuse-back, specular, specular-front,&lt;br /&gt;
		 specular-back, emissive, emissive-front, emissive-back, shininess,&lt;br /&gt;
		 shininess-front, shininess-back, color-mode&lt;br /&gt;
&lt;br /&gt;
===== blend =====&lt;br /&gt;
Children: active, source, destination, source-rgb, source-alpha, destination-rgb, destination-alpha&lt;br /&gt;
&lt;br /&gt;
Children values: dst-alpha, dst-color, one, one-minus-dst-alpha, one-minus-dst-color, one-minus-src-alpha, one-minus-src-color, src-alpha, src-alpha-saturate, src-color, constant-color, one-minus-constant-color, constant-alpha, one-minus-constant-alpha, zero&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;blend&amp;gt;&lt;br /&gt;
                        &amp;lt;active&amp;gt;true&amp;lt;/active&amp;gt;&lt;br /&gt;
                        &amp;lt;source&amp;gt;one-minus-dst-alpha&amp;lt;/source&amp;gt;&lt;br /&gt;
			&amp;lt;destination&amp;gt;src-alpha-saturate&amp;lt;/destination&amp;gt;&lt;br /&gt;
		&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== blend (simple) =====&lt;br /&gt;
A blend tag with 0 will do nothing.&lt;br /&gt;
A blend tag with 1 will do the same as source-alpha: one-minus-dst-alpha, in other words it will enable z transparency using alpha from the fragment shader.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;blend&amp;gt;1&amp;lt;/blend&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== shade-model =====&lt;br /&gt;
flat or smooth&lt;br /&gt;
&lt;br /&gt;
===== cull-face =====&lt;br /&gt;
front, back, front-back, off&lt;br /&gt;
&lt;br /&gt;
===== texture-unit =====&lt;br /&gt;
unit: integer denoting which unit it is&lt;br /&gt;
&lt;br /&gt;
image: the texture path&lt;br /&gt;
&lt;br /&gt;
images: multiple texture paths&lt;br /&gt;
&lt;br /&gt;
type: 2d, noise, cubemap, 3d (3d was added in 2020.1 and is used for layers of 2d textures defining a volumetric 3d texture)&lt;br /&gt;
&lt;br /&gt;
filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
mag-filter: linear, linear-mipmap-linear, linear-mipmap-nearest&amp;quot;, nearest, nearest-mipmap-linear, nearest-mipmap-nearest&lt;br /&gt;
&lt;br /&gt;
wrap: repeat, clamp-to-edge, clamp-to-border, clamp, mirror&lt;br /&gt;
&lt;br /&gt;
internal-format: normalized&lt;br /&gt;
&lt;br /&gt;
environment: mode, color&lt;br /&gt;
:mode: add,blend,decal,modulate,replace&lt;br /&gt;
:color: rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: replace, modulate, add, add-signed, interpolate, subtract, dot3-rgb, dot3-rgba&lt;br /&gt;
&lt;br /&gt;
texenv-combine: combine-rgb, combine-alpha, source0-rgb, source1-rgb, source2-rgb, source0-alpha, source1-alpha,source2-alpha,operand0-rgb,operand1-rgb,operand2-rgb,operand0-alpha,operand1-alpha,operand2-alpha,scale-rgb,scale-alpha&lt;br /&gt;
&lt;br /&gt;
point-sprite: true, false&lt;br /&gt;
&lt;br /&gt;
mipmap-control functions: auto, average, sum, product, min, max&lt;br /&gt;
&lt;br /&gt;
texgen:&lt;br /&gt;
:mode: object-linear, eye-linear, sphere-map, normal-map, reflection-map&lt;br /&gt;
:planes: s, t, r, q as doubles&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;texture-unit&amp;gt;&lt;br /&gt;
                        &amp;lt;unit&amp;gt;3&amp;lt;/unit&amp;gt;&lt;br /&gt;
			&amp;lt;image&amp;gt;Textures/Terrain/void.png&amp;lt;/image&amp;gt;&lt;br /&gt;
			&amp;lt;type&amp;gt;2d&amp;lt;/type&amp;gt;&lt;br /&gt;
			&amp;lt;filter&amp;gt;linear-mipmap-linear&amp;lt;/filter&amp;gt;&lt;br /&gt;
                        &amp;lt;mag-filter&amp;gt;linear-mipmap-linear&amp;lt;/mag-filter&amp;gt;&lt;br /&gt;
			&amp;lt;wrap-s&amp;gt;repeat&amp;lt;/wrap-s&amp;gt;&lt;br /&gt;
			&amp;lt;wrap-t&amp;gt;repeat&amp;lt;/wrap-t&amp;gt;&lt;br /&gt;
                        &amp;lt;wrap-r&amp;gt;repeat&amp;lt;/wrap-r&amp;gt;&lt;br /&gt;
			&amp;lt;internal-format&amp;gt;normalized&amp;lt;/internal-format&amp;gt;&lt;br /&gt;
                        &amp;lt;mipmap-control&amp;gt;&lt;br /&gt;
                            &amp;lt;function-r&amp;gt;average&amp;lt;/function-r&amp;gt;&lt;br /&gt;
			    &amp;lt;function-g&amp;gt;min&amp;lt;/function-g&amp;gt;&lt;br /&gt;
                            &amp;lt;function-b&amp;gt;sum&amp;lt;/function-b&amp;gt;&lt;br /&gt;
			    &amp;lt;function-a&amp;gt;product&amp;lt;/function-a&amp;gt;&lt;br /&gt;
                        &amp;lt;/mipmap-control&amp;gt;&lt;br /&gt;
                        &amp;lt;environment&amp;gt;&lt;br /&gt;
                            &amp;lt;mode&amp;gt;decal&amp;lt;/mode&amp;gt; &lt;br /&gt;
                            &amp;lt;color&amp;gt;0.0 0.1 0.6 1.0&amp;lt;/color&amp;gt;&lt;br /&gt;
                        &amp;lt;/environment&amp;gt;&lt;br /&gt;
                        &amp;lt;point-sprite&amp;gt;true&amp;lt;/point-sprite&amp;gt;&lt;br /&gt;
                        &amp;lt;texenv-combine&amp;gt;operand0-rgb&amp;lt;/texenv-combine&amp;gt;&lt;br /&gt;
                        &amp;lt;texgen&amp;gt;&lt;br /&gt;
                            &amp;lt;mode&amp;gt;S&amp;lt;/mode&amp;gt;&lt;br /&gt;
                            &amp;lt;planes&amp;gt;0.075, 0.0, 0.0, 0.5&amp;lt;/planes&amp;gt;&lt;br /&gt;
                        &amp;lt;/texgen&amp;gt;&lt;br /&gt;
		&amp;lt;/texture-unit&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Textures of type 3d has to be packed on the x axis. Here is an example: [https://raw.githubusercontent.com/sebh/TileableVolumeNoise/master/Examples/noiseErosionPacked.jpg noiseErosionPacked.jpg]&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-two-side =====&lt;br /&gt;
true or false&lt;br /&gt;
&lt;br /&gt;
===== polygon-mode =====&lt;br /&gt;
children: front, back&lt;br /&gt;
&lt;br /&gt;
Valid values:  fill, line, point&lt;br /&gt;
&lt;br /&gt;
===== vertex-program-point-size =====&lt;br /&gt;
true, false&lt;br /&gt;
&lt;br /&gt;
===== uniform =====&lt;br /&gt;
Data accessible by shaders.&lt;br /&gt;
&lt;br /&gt;
name: the name&lt;br /&gt;
&lt;br /&gt;
type: bool, int, float, float-vec3, float-vec4, sampler-1d, sampler-2d, sampler-3d, sampler-1d-shadow, sampler-2d-shadow, sampler-cube&lt;br /&gt;
&lt;br /&gt;
===== alpha-test =====&lt;br /&gt;
&lt;br /&gt;
active: true, false&lt;br /&gt;
&lt;br /&gt;
comparison: never, less, equal, lequal, greater, notequal, gequal, always&lt;br /&gt;
&lt;br /&gt;
reference: 0 to 1&lt;br /&gt;
&lt;br /&gt;
===== render-bin =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
bin-number: This is an integer defining the order stuff will be rendered in, it can be negative also.&lt;br /&gt;
&lt;br /&gt;
bin-name: RenderBin, DepthSortedBin&lt;br /&gt;
&lt;br /&gt;
===== rendering-hint =====&lt;br /&gt;
Sent to OSG.&lt;br /&gt;
&lt;br /&gt;
default, opaque, transparent&lt;br /&gt;
&lt;br /&gt;
This basically just sets Renderbin:&lt;br /&gt;
&lt;br /&gt;
opaque = bin 10, depthsortedbin&lt;br /&gt;
&lt;br /&gt;
transparent = bin 0, renderbin&lt;br /&gt;
&lt;br /&gt;
default = inherit renderbin details from parent node&lt;br /&gt;
&lt;br /&gt;
===== depth =====&lt;br /&gt;
&lt;br /&gt;
* function: Specifies the depth comparison function. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthFunc.xhtml &amp;lt;tt&amp;gt;glDepthFunc&amp;lt;/tt&amp;gt;].&lt;br /&gt;
* near, far: Specify the mapping of depth values from normalized device coordinates to window coordinates. Equivalent to [https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml &amp;lt;tt&amp;gt;glDepthRange&amp;lt;/tt&amp;gt;]&lt;br /&gt;
* write-mask: Whether to write to the depth buffer or not.&lt;br /&gt;
* enabled: Whether depth testing is enabled or not.&lt;br /&gt;
&lt;br /&gt;
===== program =====&lt;br /&gt;
* vertex-shader&lt;br /&gt;
* geometry-shader&lt;br /&gt;
* fragment-shader&lt;br /&gt;
* attribute&lt;br /&gt;
* geometry-vertices-out: integer, max number of vertices emitted by geometry shader&lt;br /&gt;
* geometry-input-type: points, lines, lines-adjacency, triangles, triangles-adjacency&lt;br /&gt;
* geometry-output-type: points, line-strip, triangle-strip&lt;br /&gt;
* uniform-block-binding: has name and index (since 2020.1)&lt;br /&gt;
&lt;br /&gt;
example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
				&amp;lt;vertex-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;1&amp;quot;&amp;gt;Shaders/noise.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;2&amp;quot;&amp;gt;Shaders/filters-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
example for clustered lightning in compositor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;program&amp;gt;&lt;br /&gt;
				&amp;lt;vertex-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;0&amp;quot;&amp;gt;Shaders/lcd.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;1&amp;quot;&amp;gt;Shaders/noise.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
				&amp;lt;fragment-shader n=&amp;quot;2&amp;quot;&amp;gt;Shaders/filters-ALS.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
                                &amp;lt;fragment-shader n=&amp;quot;3&amp;quot;&amp;gt;Shaders/ALS/clustered-include.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
                                &amp;lt;uniform-block-binding&amp;gt;&lt;br /&gt;
		                   &amp;lt;name&amp;gt;PointLightBlock&amp;lt;/name&amp;gt;&lt;br /&gt;
		                   &amp;lt;index&amp;gt;5&amp;lt;/index&amp;gt;&lt;br /&gt;
		                &amp;lt;/uniform-block-binding&amp;gt;&lt;br /&gt;
		                &amp;lt;uniform-block-binding&amp;gt;&lt;br /&gt;
		                   &amp;lt;name&amp;gt;SpotLightBlock&amp;lt;/name&amp;gt;&lt;br /&gt;
		                   &amp;lt;index&amp;gt;6&amp;lt;/index&amp;gt;&lt;br /&gt;
		                &amp;lt;/uniform-block-binding&amp;gt;&lt;br /&gt;
&amp;lt;/program&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See this page for more about shaders: [[Howto:Shader programming in FlightGear]]&lt;br /&gt;
&lt;br /&gt;
== Uniforms passed to shaders outside the XML effect framework ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Type&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, view matrix used to transform from world to view space. Same as osg_ViewMatrix, but for fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, view matrix inverse used to transform from view to world space. Same as osg_ViewMatrixInverse but for fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ProjectionMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In fullscreen pass only, projection matrix inverse&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionCart&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in cartesian coordinates&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_CameraPositionGeod&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunAmbientColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDiffuseColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunSpecularColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_SunDirection&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FogColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_FogDensity&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ShadowNumber&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_ShadowDistances&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_DepthInColor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Tells if the depth is stored in a depth texture or a color texture&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_Planes&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec3&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Used to convert the value of the depth buffer to a depth that can be used to compute the eye space position of the fragment&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;fg_BufferSize&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;vec2&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dimensions of the buffer, used to convert gl_FragCoord into the range [0..1][0..1]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_ViewMatrix&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG, used only when working on actual geometry. Transforms from world to view space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_ViewMatrixInverse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;mat4&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG, used only when working on actual geometry. Transforms from view to world space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_SimulationTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_DeltaFrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameTime&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;osg_FrameNumber&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Defined by OSG&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* {{forum link|t=37364|title=Application of effects}} - Testing which kind of groups an effect can be applied to and when&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=GlTF&amp;diff=137619</id>
		<title>GlTF</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=GlTF&amp;diff=137619"/>
		<updated>2023-04-24T02:48:24Z</updated>

		<summary type="html">&lt;p&gt;Icecode: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''glTF''' (derivative short form of '''Graphics Language Transmission Format''' or '''GL Transmission Format''') is a standard file format for three-dimensional scenes and models. A glTF file uses one of two possible file extensions, .gltf (JSON/ASCII) or .glb (binary). See the [https://en.wikipedia.org/wiki/GlTF Wikipedia article] on the subject for more information. In FlightGear glTF can be used in place of the [[AC3D file format]] to load 3D models.&lt;br /&gt;
&lt;br /&gt;
== glTF vs. AC3D ==&lt;br /&gt;
&lt;br /&gt;
glTF does not deprecate the AC3D file format as both can be used interchangeably, although each one has its own advantages and disadvantages. Choosing which one to use for your project will depend on your requirements.&lt;br /&gt;
&lt;br /&gt;
The main advantage of glTF is that PBR materials are handled automatically. glTF files contain PBR material information that is used by FlightGear to avoid messing with [[Effects]] manually like in the case of AC3D files. This allows 3D models to have a consistent look across all software, i.e. what you see in [[Blender]] is exactly what you will see in FlightGear. However, this advantage can also be a disadvantage. The glTF specification is quite specific about how a material is defined, so it's not possible to add custom Effects to glTF models. If your project uses custom shaders or requires special effects that cannot be handled by the standard PBR scheme (albedo/metalness/roughness), then you should be using AC3D files with custom Effects.&lt;br /&gt;
&lt;br /&gt;
== Unsupported Features ==&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 glTF 2.0 specification] is the best resource when it comes to glTF. All parameters and their default values are very well defined. FlightGear tries to adhere to the specification as much as possible, but there are some exceptions:&lt;br /&gt;
&lt;br /&gt;
* Embedded textures are not loaded, so all textures must be saved to external files.&lt;br /&gt;
* All parameters related to animations are ignored. This includes skinning information like joints and weights, as well as the animation keyframes themselves. FlightGear provides its own system for animating objects, see [[Howto:Animate models]].&lt;br /&gt;
* Instanced geometry is not supported.&lt;br /&gt;
* Cameras and punctual lights are not supported.&lt;br /&gt;
* When no material has been specified for a mesh, the glTF spec suggests using a 50% emissive grey material. FlightGear uses a different default material, which is specified in {{fgdata file|Effects/model-pbr.eff}}.&lt;br /&gt;
&lt;br /&gt;
== Usage notes for content developers ==&lt;br /&gt;
&lt;br /&gt;
In XML you can treat glTF models the same way you treat AC3D, with a few exceptions. As described earlier, Effects can't be assigned to glTF models because they use a predefined Effect that implements the material description of the glTF specification. [[Howto:Animate models#Material animation|Material animations]] don't work either for the same reason. If you want to change the material parameters, you should do so in your 3D modelling software of choice (or manually editing the glTF file).&lt;br /&gt;
&lt;br /&gt;
=== Blender ===&lt;br /&gt;
&lt;br /&gt;
[[File:Blender glTF export menu.png|thumb|Blender glTF exporter menu location.]]&lt;br /&gt;
[[File:Blender glTF exporter example settings.png|thumb|Example settings for exporting a glTF model in Blender.]]&lt;br /&gt;
&lt;br /&gt;
The latest versions of Blender support glTF out of the box. You need to use a Principled BSDF to setup your materials so they can displayed correctly by FlightGear. All textures attached to this node will also be exported correctly. See the [https://docs.blender.org/manual/en/2.80/addons/io_scene_gltf2.html reference documentation] in the Blender manual for more information about Blender and glTF.&lt;br /&gt;
&lt;br /&gt;
Some important settings for the exporter include:&lt;br /&gt;
&lt;br /&gt;
; Format&lt;br /&gt;
: &amp;lt;tt&amp;gt;glTF Separate (.gltf + .bin + textures)&amp;lt;/tt&amp;gt; has to be selected because FlightGear does not support loading embedded assets.&lt;br /&gt;
; Textures&lt;br /&gt;
: Optional directory where textures will be placed. If none is selected, the textures will be in the same directory as the &amp;lt;tt&amp;gt;.gltf&amp;lt;/tt&amp;gt; file.&lt;br /&gt;
; Limit to&lt;br /&gt;
: These parameters can be used to select which objects of your Blender scene will be exported.&lt;br /&gt;
; Data&lt;br /&gt;
: FlightGear does not support glTF cameras or punctual light sources, so you can disable eveything here.&lt;br /&gt;
; +Y up&lt;br /&gt;
: Make sure to keep this '''OFF'''. Blender uses a +Z up convention like FlightGear, so we do not adhere to the glTF standard (+Y up).&lt;br /&gt;
; Apply Modifiers&lt;br /&gt;
: If you have any unapplied modifiers (like a Subdivision Surface Modifier), they will applied before exporting.&lt;br /&gt;
; UVs&lt;br /&gt;
: Whether to export UV texture coordinates or not. You should keep this '''ON'''.&lt;br /&gt;
; Normals&lt;br /&gt;
: Whether to export normals or not. You should keep this '''ON''' as disabling them will force FlightGear to calculate them at runtime.&lt;br /&gt;
; Tangents&lt;br /&gt;
: Whether to export the tangent vectors or not. You should keep this '''OFF''' as FlightGear will calculate the tangent and binormal vectors at runtime anyway.&lt;br /&gt;
; Vertex Colors&lt;br /&gt;
: Whether to export the vertex colors or not. FlightGear will use the PBR information of the Principled BSDF to light the model, so vertex colors will be ignored by most Compositor pipelines. You can keep this '''OFF''' in most cases.&lt;br /&gt;
; Attributes&lt;br /&gt;
: You can keep this '''OFF'''.&lt;br /&gt;
; Materials&lt;br /&gt;
: Whether to export materials or not. You should keep this on &amp;lt;tt&amp;gt;Export&amp;lt;/tt&amp;gt;.&lt;br /&gt;
; Images&lt;br /&gt;
: &amp;lt;tt&amp;gt;Automatic&amp;lt;/tt&amp;gt; will automatically choose between PNG and JPEG when saving textures. &amp;lt;tt&amp;gt;JPEG format (.jpg)&amp;lt;/tt&amp;gt; will force saving as JPEG for every texture. In general JPEG provides a decent save in storage space at the cost of a negligible quality loss, so you should be using JPEG whenever possible (transparency requires PNG). Keep in mind that JPEG textures are lossy though, so you might want to keep a lossless copy for development purposes in PNG or XCF format.&lt;br /&gt;
; PBR Extensions&lt;br /&gt;
: You can keep this '''OFF'''.&lt;br /&gt;
; Lighting&lt;br /&gt;
: Does not matter what you choose here as FlightGear completely ignores glTF lights.&lt;br /&gt;
; Animation&lt;br /&gt;
: Disable everything here as FlightGear completely ignores glTF animations.&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
&lt;br /&gt;
* [[HDR Pipeline]]&lt;br /&gt;
* [[AC3D file format]]&lt;/div&gt;</summary>
		<author><name>Icecode</name></author>
	</entry>
</feed>