<?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=Fredb</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=Fredb"/>
	<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/Special:Contributions/Fredb"/>
	<updated>2026-05-19T08:39:32Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Fredb&amp;diff=58076</id>
		<title>User:Fredb</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Fredb&amp;diff=58076"/>
		<updated>2013-02-20T11:13:50Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{User&lt;br /&gt;
|name = Frédéric Bouvier&lt;br /&gt;
|location = France}}&lt;br /&gt;
[[Building using CMake - Windows]]&lt;br /&gt;
&lt;br /&gt;
[[Project Rembrandt]]&lt;br /&gt;
&lt;br /&gt;
==Development plan:==&lt;br /&gt;
* Restore near/far camera using depth range instead of clear to work with Rembrandt.&amp;lt;br /&amp;gt;Distance to viewer computation will change to cope with the two ranges.&amp;lt;br /&amp;gt;fg_Planes uniform need to convey three planes instead of two. Maybe fg_Planes_n and fg_Planes_f will be created (note: middle plane needs different parameters for the two ranges).&lt;br /&gt;
* Use geometry shader and instancing to compute shadow map to a texture array. Capitalize on OGL 4 features. (Seen in the OpenGL Insights book)&lt;br /&gt;
* Use geometry shader and instancing to compute multiple shadow maps for additional light sources.&lt;br /&gt;
&lt;br /&gt;
[[Category: FlightGear Core developers]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=56961</id>
		<title>Fr/Projet Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=56961"/>
		<updated>2013-01-06T11:25:22Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Pipeline configurable */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Pourquoi ce nom? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] était un peintre hollandais du XVIIème siècle, maître incontesté du [http://en.wikipedia.org/wiki/Chiaroscuro &amp;quot;clair-obscur&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Ce projet a pour but de changer la manière de rendre les lumières et les [[Shadows|ombres]] qu'utilise [[FlightGear]], et d'essayer d'imiter le style de Rembrandt dans FG.&lt;br /&gt;
&lt;br /&gt;
== De quoi s'agit-il ? ==&lt;br /&gt;
L'idée maîtresse du projet est d'implémenter le [http://en.wikipedia.org/wiki/Deferred_shading rendu différé] au sein de FlightGear.&lt;br /&gt;
Depuis le début, FlightGear utilise un moteur de rendu classique, &amp;quot;en avant&amp;quot;, qui affiche toutes les propriétés d'un objet en une fois (ombre, éclairage, brouillard, ...), ce qui rend difficile le rendu d'un ombrage plus sophistiqué (voir le [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) du fait que tous les paramètres de [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ l'équation lumineuse] doivent être traités en une seule fois.&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Vue principale avec le contenu des buffers affichés dans les coins]]&lt;br /&gt;
Au contraire, le rendu différé cherche à séparer les opérations en étapes simplifiées, et à collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par les étapes suivantes.&lt;br /&gt;
&lt;br /&gt;
;Le premier stade est celui de la Géométrie:&lt;br /&gt;
: nous rendons la scène entière dans 4 textures, en utilisant le rendu multi-cibles pour les traiter en un seul passage: un pour le buffer de profondeur, un pour les normals (en bas à gauche de l'image), un pour les couleurs &amp;quot;diffuses&amp;quot; (en bas à gauche) et un pour les couleurs &amp;quot;spéculaires&amp;quot; (en haut à droite).&lt;br /&gt;
&lt;br /&gt;
;Le stade suivant est celui de l'ombre :&lt;br /&gt;
: nous rendons encore la scène dans une texture profondeur concernant les éclairages. Il y aura une texture pour chaque lumière diffusant des ombres.&lt;br /&gt;
&lt;br /&gt;
;Ensuite, c'est le stade de la lumière, avec plusieurs sous-stades :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: Le ciel est dessiné d'abord selon la méthode classique.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: la mémoire-tampon &amp;quot;diffuse&amp;quot; est modulée avec la couleur ambiante de la scène, et est dessinée comme un quad texturé aligné sur l'écran&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: Un second quad aligné à l'écran est dessiné et un shader examine la position pour calculer sa couleur &amp;quot;diffuse&amp;quot; et &amp;quot;specular&amp;quot; en utilisant le &amp;quot;normal&amp;quot; stocké dans le premier stade. La couleur résultante et mélangée avec la passe précédente. Les ombres sont examinées ici par comparaison de la position du pixel avec la position du cache lumière stockée dans la carte shadows&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: un nouvel écran quad est dessiné et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat de la phase précédente  &lt;br /&gt;
:*&amp;lt;u&amp;gt;stade de la lumière additionnelle&amp;lt;/u&amp;gt;: le scene graph sera traversé une autre fois pour afficher les volumes de lumière (cône ou tronc de cône pour les taches de lumière, sphère pour les lumières omni directionnelles), et leur shader ajoutera la lumière composée uniquement par les pixels éclairés.&lt;br /&gt;
:*&amp;lt;u&amp;gt;stade brouillard&amp;lt;/u&amp;gt;: un nouveau quad aligné sur l'écran est dessiné, et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat du stade précédent.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Stade des objets transparents&amp;lt;/u&amp;gt;: les objets transparents (et les nuages) sont enfin rendus en utilisant la méthode classique.&lt;br /&gt;
&lt;br /&gt;
:Tous les données de lumière sont accumulées dans une seule mémoire tampon, qui sera utilisée pour le dernier stade en addition au stade Géométrie.&lt;br /&gt;
&lt;br /&gt;
;A la fin, le stade affichage, avec l'option effet post-traitement :&lt;br /&gt;
:Les résultats des précédents tampons sont poussés dans le tampon principal pour être affichés, optionnellement modifiés pour montrer Glow, Motion blur, HDR, redout ou blackout, occlusion ambiante de l'espace écran, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
Dans FG, on termine le pipeline du rendu par l'affichage du [[Menubar|GUI]] et du [[HUD]].&lt;br /&gt;
&lt;br /&gt;
Tous ces phases sont plus précisément décrites dans [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] c'est la base du code actuel, avec quelques ajouts ou modifications.&lt;br /&gt;
&lt;br /&gt;
== Avertissements ==&lt;br /&gt;
Le rendu différé n'affiche pas la transparence. Pour le moment, les nuages doivent être éclairés et ombrés par eux-mêmes. Les surfaces transparentes sont alpha-testées et non mélangées. Elles doivent être amenées dans leur propre bac sur l'image composite.&lt;br /&gt;
&lt;br /&gt;
La partition profondeur ne marche pas non plus, à cause de la mémoire tampon profondeur, qui doit être gardée pour retenir la position de zone de vue, et, pour le moment, z-fighting est tout à fait visible. La partition profondeur sans rangée de profondeur superposée pourrait être la solution, et devrait être essayée.&lt;br /&gt;
&lt;br /&gt;
Le passage de la lumière peut rendre certains MFD illisibles (ce qui utilisent une couleur émissive) car flous. Ils devront être traités comme transparents.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mise en œuvre ==&lt;br /&gt;
=== Répertoires ===&lt;br /&gt;
Le code est la principale branche du [[FlightGear and Git|répertoire officiel]]. Aucune autre localisation n'existe.&lt;br /&gt;
&lt;br /&gt;
=== Rendu des surfaces transparentes ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Surfaces transparentes desssinées d'après des objets opaques]]&lt;br /&gt;
Les surfaces transparentes sont détectées par les plugins OSG loader et reçoivent des suggestions de rendu TRANSPARENT_BIN&lt;br /&gt;
 Au stade collection, le collecteur commande les surfaces transparentes dans le le bac transparent. Dans un retour, attaché à la caméra Géometry, après la traversée scénographe, les bacs transparent sont enlevés de la phase rendu et sauvegardés dans un espace temporaire. Dans un retour attaché  la caméra Éclairage, après la traversée sceneraph, les bacs transparents sauvegardent au prochain stade, sont ajoutés  au stade rendu de la caméra éclairageavec un numéro d'ordre. Ainsi, les surfaces transparentes sont dessinées au sommet de la scene éclairée à partir de G-buffer .&lt;br /&gt;
&lt;br /&gt;
=== Consommation de mémoire ===&lt;br /&gt;
Pour chaque caméra définie du groupe, il y a une carte d'ombre séparée, de telle sorte que l'utilisation de la mémoire vidéo soit:&lt;br /&gt;
* G-tampon et tampon lumière: 20 bytes par pixel. Pour un écran HD (1920x1080) la mémoire requise est de 40 Mb&lt;br /&gt;
* Carte d'ombre 3 x taille_carte_ombre x shadow_map_size bytes (si la taille est 8192, la taille totale de la mémoire est 192 Mb&lt;br /&gt;
Ne pas compter les textures, liste d'affichage ou tampons vertex pour modèles et terrains&lt;br /&gt;
&lt;br /&gt;
3 écrans HD ont besoin de 120 Mb de mémoire pour les tampons (ombre exclue), il vous faut  3x8192x8192x3 = 576 Mb (megabytes) de mémoire pour les seuls shadows.&lt;br /&gt;
&lt;br /&gt;
Si vous voyez des messages d'erreur pendant le démarrage, ou si FlightGear ne démarre pas bien, c'est probablement parceque vous n'avez pas assez de mémoire vidéo libre. Réduisez la taille de la carte d'ombre dans préférences.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Et mettez 4096 ou 2048 à la place.Vous pouvez aussi utiliser un paramètre de démarrage: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Pipeline configurable  ===&lt;br /&gt;
&lt;br /&gt;
Le rendu Rembrandt utilise un fichier XML  pour installer son pipeline pour chaque fenêtre décrite dans le groupe de cameras. Ce fichier décrit la façon dont les tampons intermédiaires sont établis, et comment les différentes étapes du rendu sont agencées. Le schéma général du fichier pipeline est le suivant :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ere définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ère définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Tampons (Buffers)====&lt;br /&gt;
Un tampon est une texture utilisée comme zone de stockage dans le GPU. Sa taille est habituellement un multiple de la taille de l'écran, mais une taille fixe est prise en charge ( typique pour la carte d'ombres). La description d'un tampon suit :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Phases ====&lt;br /&gt;
Une phase est une unité de rendu d'un groupe de tampons. La plupart des phases sont pré-définies et leur type n'est pas libre. Quand un type n'est pas spécifié, le nom est utilisé? Les types de phases sont :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|La phase geometry initialise la plupart des tampons et agit sur les objets réels et la géométrie. Les objets transparents sont placés à côté, et seront utilisés tels quels dans la phase lumière. Le reste de la géométrie opaque  est rendu avec les effets standard, permettant de mettre la donnée sensible dans les tampons.&lt;br /&gt;
|-&lt;br /&gt;
|ombre&lt;br /&gt;
|Dans cette phase, la géométrie est rendue dans la carte normale à partir de la perspective du soleil.&lt;br /&gt;
|-&lt;br /&gt;
|lumière&lt;br /&gt;
|Cette phase utilise les tampons remplis par les phases précédrntes pour éclairer  chaque pixel de la scène. Le résultat est rendu dans un autre tampon pour permettre des effets ultérieurs.&lt;br /&gt;
|-&lt;br /&gt;
|plein écran&lt;br /&gt;
|Les phases de ce type sont utilisés pour changer la scène entière, ou transformer une donnée à partir d'un tampon particulier.&lt;br /&gt;
|-&lt;br /&gt;
|affichage&lt;br /&gt;
|Le rendu final de la scène à l'écran est jugé à l'écran, ou la texture est définie dans le groupe caméra .&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ci-dessous, une description de phase :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optionnel si le nom est l'un des types prédéfinis sauf plein écran  --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Les phases sont rendues dans les tampons (sauf pur la phase affichage). Les pièces jointes disent quels tampons sony affectés par chaque phase.&lt;br /&gt;
&lt;br /&gt;
===== Pièces jointes =====&lt;br /&gt;
La pièce jointe décrit la liaison entre tampon et poit d'attachement :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissions(passes) =====&lt;br /&gt;
Les Passes sont seulement disponibles dans la phase &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt;. trois sortes de phases sont autorisées :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Rendus de la voûte céleste, solei, lune, planète, étoiles et nuages&lt;br /&gt;
|-&lt;br /&gt;
|lumières&lt;br /&gt;
|Rendus des taches additionnelles et points lumineux &lt;br /&gt;
|-&lt;br /&gt;
|plein écran&lt;br /&gt;
|Le pass fullscreen analogue à une phase fullscreen sauf qu'il est rendu dans des tampons attachés à la phase lumière&lt;br /&gt;
|}&lt;br /&gt;
Un pass est défini ci-dessous :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optionnel si le nom est prédéfini excepté fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une phase lumière typique est une succession de 5 pass:&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour lumière ambiante&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour lumière solaire (et ombres)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour brouillard&lt;br /&gt;
&lt;br /&gt;
Chaque effet attaché au plein écran définit le mélange fait entre le pass et la somme précédente de rendu.&lt;br /&gt;
&lt;br /&gt;
== Démarrage de FlightGear avec Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|dialogue Rembrandt]]&lt;br /&gt;
Le rendu Rembrandt est maintenant intégré dans le répertoire principal, mais doit être activé pour démarrer. Il y a deux façons de l'activer (une seule est nécessaire):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (lorsqu'on utilise [[FGRun]], on peut ajouter ceci derrière le &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; sur la première page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (avec FGRun on peut ajouter ceci via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; sur la dernière page).&lt;br /&gt;
&lt;br /&gt;
Le &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialogue vous permet de  basculer et d'ajuster les différentes options offertes par Rembrandt.&lt;br /&gt;
&lt;br /&gt;
Rembrandt est très gourmand en ressources GPU et son démarrage peut échouer avec les options par défaut. Le symptome le plus fréquent est un message OSG dans la console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
On peut voir aussi :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
Des options additionnelles peuvent éviter ces problèmes :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Certaines vieilles cartes NVidia comme 7600GT, n'ont pas assez de résolution pour la profondeur, et on voit des &amp;quot;rideaux de brouillard&amp;quot; à quelques mètres devant. Une astuce consiste à encoder la profondeur dans une autre texture et donner la valeur correcte ensuite. Cette option permet cela.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Désactive les ombres tout à fait.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Évite le message &amp;quot;error C6013&amp;quot; sur les vieilles cartes en manque de résolution dans le cockpitt. Mettez &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; pour changer la taille de la carte d'ombre. Plus de taille, et moins de résolution (la valeur par défaut est 5 mètres)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Définnissez la taille de la carte d'ombres. Les valeurs utilles sont 1024, 2048, 4096 ou 8192. Peu de cartes supportent 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Définissez le nombre de cascades de la carte ombre. Moins de cascades signifie moins de temps passé à générer la carte shadow, mais aussi signifie une qualité moindre de l'ombre. Mettez entre 1 et 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Définissez la taille de cascade de la carte shadow pour chaque cascade. Les valeurs par défaut sont 5m, 50m, 500m et 5000m pour 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Par défaut, Rembrandt utilise normalement des tampons de 8 bits  (ainsi, la propriété est vraiment définie par défaut). Ceci peut créer des artefacts pour les éclairages specular. Si c'est inacceptable et si le GPU le supporte, mettez false pour avoir une meilleure précision pour les normales et les effets s'appuyant sur une direction normale.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lignes directrices pour les écritures shader ==&lt;br /&gt;
=== Uniformes prédéfinis ===&lt;br /&gt;
Ces uniformes glsl n'ont pas besoin d'être déclarés dans le fichier effet&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Type&lt;br /&gt;
!Objectif&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;
|En pass plein écran seulement, view matrix utilisé our transformer la position écran en direction vue&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;
|En pass plein écran seulement, view matrix inverse employé pour transformer la position écran en direction vue&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;
|En pass plein écran seulement, projection matri inverse employé pour transformer la position écran en direction vue&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 de la caméra en coordonnées cartésiennes&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 de la caméra dans l'espace, exprimé en coordonnées géodésiques (longitude et latitude en radians, élévation en mètres)&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;
|&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;
|&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;
|&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;
|&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;
|Dire si la profondeur est rangée dans une texture profondeur ou une texture couleur&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;
|Utilisé pour convertir la valeur du tampon profondeur en une profondeur qui peut être utilisée pour calculer la position dans l'espace du 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 du tampon, utilisé pour convertir  gl_FragCoord dans la taille [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;
|Definie par OSG, employé seulement lors du travail sur la géométrie réelle&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;
|Definie par OSG, employé seulement lors du travail sur la géométrie réelle&lt;br /&gt;
|}&lt;br /&gt;
.Ils doivent encore être déclarés dans le fragment du vertex shader&lt;br /&gt;
&lt;br /&gt;
=== Fonctions utilitaires ===&lt;br /&gt;
&lt;br /&gt;
Pour faciliter la maintenance des shaders plusieurs fonctions utilitaires sont disponibles pour le fragment shader. Ces fonctions sont placées ensemble dans deux fichiers : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Utilisé pour encoder youtes les valeurs de  G-Buffer dans material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Employé pour compresser normals à l'intérieur de G-Buffer dans material shaders. Normalement appelé de &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit normals à partir de G-Buffer. Employé dans shaders plein écran et shaders lumière&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode les valeurs float dans la taille [0..1] dans les  24 bits d'une couleur. cette fonction est employée par &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; si le &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; est vrai, pour les vieilles cartes qui ne fournissent pas d'information profondeur avec assez de résolution dans les shaders fullscreen ou lumière.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Décode les valeurs float dans la taille [0..1] dans les  24 bits d'une couleur. cette fonction est employée par &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; si le &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; est vrai, pour les vieilles cartes qui ne fournissent pas d'information profondeur avec assez de résolution dans les shaders fullscreen ou lumière.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit la position eye space à partir de la direction view position a partir de la view direction et la profondeur lue du tampon profondeur &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
::Reconstruit la position eye space à partir de la direction view et la profondeur encodée dans une couleur lue du tampon profondeur&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit la position eye space à partir de la direction vue et du tampon profondeur (profondeur réelle ou couleur selon la valeur de &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) à un fragment donné sur l'écran, donné par &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
Pour les shaders material, il faut fournir à la fois  &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; dans le fichier effet, comme suit :&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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
Pour les shaders fullscreen passes, on doit fournir seulement &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt;, comme ceci  :&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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
Dans la principale fonction du shader, les fonctions référencées doivent être écrites en premier. Avec no #include files, le prototype de la fonction entière nécessite d'être typé :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Phase Geometry  ===&lt;br /&gt;
La phase Geometry est là pour remplir le G-tampon.  '''L'ombrage n'intervient pas à cette phase, et le calcul lumière ou brouillard ne doit pas faire partie du shader '''. L'opération requise dans le fragment Shader est de remplir avec une valeur sensible chaque tampon individuel :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|pràfondeur (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment profondeur&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ceci est la couche par défaut attendue par le shader . material Id peut être utilisé pour détecter une couche différente&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pass lumière additionnelle ===&lt;br /&gt;
Il y aura là un seul shader pour chaque type de lumière utilisé. L'objectif est de créer des lumières comme animations dans le fichier model XML.   Le shader lumière retrouvera la scène geometry en combinant la position espace écran en vue de rayon espace par l'inversion de la matrix projection (une fonction plus secourable sera fournie), et le fragment profondeur à cette  position écran lit à partir du tampon profondeur. Avec l'aide du fragment normal, la couleur diffuse et specular et les propriétés de la lumière que le shader introduit, il sera possible d'ajouter au tampon lumière l'apport du rendu lumière.&lt;br /&gt;
&lt;br /&gt;
===Pass brouillard===&lt;br /&gt;
En utilisant le fragment profondeur, il sera possible de calculer une distribution brouillard. Pour le moment, il n'y a que l'équation simple brouillard.&lt;br /&gt;
&lt;br /&gt;
===Pass fleur===&lt;br /&gt;
C'est un effet double pass qui rend flou le tampon lumière dans une petite texture. Cette texture est ensuite ajoutée au tampon lumière lors de la phase affichage.&lt;br /&gt;
&lt;br /&gt;
=== Effets requis ===&lt;br /&gt;
Plusieurs pass sont mis en œuvre pour l'utilisation du système effet. Dans ce but , des effets sont référencés dans le code core utilisant des noms réservés. Ces effets sont:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Type&lt;br /&gt;
!But&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad plein écran&lt;br /&gt;
|Calcule l'occlusion ambiante à partir du tampon normal et du tampon profondeur&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad plein écran &lt;br /&gt;
|Copie le tampon couleur diffuse  multiplié par la lumière ambiante au tampon éclairage. L'occlusion ambiante peut aussi affecter la lumière ambiante .&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur la géométrie réeelle du volume de la lumière&lt;br /&gt;
|Calcule la contribution lumière d'un point lumineux défini dans une animation &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt;ayant un &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; de '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad de plein écran&lt;br /&gt;
|Calcule le brouillard à partir du C-buffer et les paramètres de l'éclairage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad de plein écran&lt;br /&gt;
|Rends l'image finale composite à partir du G-buffer et du buffer éclairage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lignes-guide pour modeleurs ==&lt;br /&gt;
&lt;br /&gt;
=== Portage d'avion ===&lt;br /&gt;
* Rembrandt calcule les ombres =&amp;gt; plus de fausses ombres dans le modèle&lt;br /&gt;
* Rembrandt calcule l'occlusion ambiante =&amp;gt; pas d'occlusion ambiante incluse dans les textures&lt;br /&gt;
* Rembrandt est en lumière =&amp;gt; les cartes lumière static ne sont pas nécéssaires, la couleur émissive pour voir les modèles n'est pas nécessaire, et pourrait interférer&lt;br /&gt;
* Rembrandt est brillant =&amp;gt; les couleurs émissives incorrectement utilisées peuvent rendre flou, et rendre du texte illisible. L'intensité de la lumière devra être réglée&lt;br /&gt;
* Rembrandt a des besoins précis avec les shaders =&amp;gt; les shaders nécessitent un ajustement pour se conformer au nouveau cadre, sinon la vue sera faussée&lt;br /&gt;
* Rembrandt ne peut faire des surfaces transparentes =&amp;gt; les surfaces transparentes doivent être dûment enregistrées pour les atteindre avec le chemin classique&lt;br /&gt;
&lt;br /&gt;
=== Enregistrement de toutes les surfaces translucides ===&lt;br /&gt;
&lt;br /&gt;
Chaque modèle est par défaut rendu en utilisant l'effet  &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt;. Cet effet initialise le G-buffer, en ignorant les surfaces transparentes, en mettant  alpha test et  rendu de toute la geometrie dans la poubelle. Il n'est pas possible de rediriger le rendu vers les bacs transparents lorsque la texture associée a un canal alpha car la plupart des modeles emploient un atlas simple texture et même les parties opaques sont rendues avec texture avec alpha canal.&lt;br /&gt;
&lt;br /&gt;
Si un modèle nécessite des surfaces translucides ou transparentes , ces objets surface doivent être assignés à un effet différent  qui place explicitement le bac rendu à &amp;quot;DepthSortedBin&amp;quot;, ou met la suggestion rendu à &amp;quot;transparent&amp;quot;. Ceci dit au moteur de rendu de rendre cet objet opérant avant le rendu, ainsi, la clarté et le brouillard doivent être activés, et si un programme shader est utilisé, et s'ils ont été calculés en manière classique. Le   &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; peut être utilisé pour enregistrer simlement les surfaces transparentes/translucides. Vous attribuez cet effet à un objet (ou à de multiples objets) comme:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Attention: &amp;lt;Effect&amp;gt; agit seulement sur les objets réels, pas sur des groupes d'objets ou des animations.'''&lt;br /&gt;
&lt;br /&gt;
Si la surface opaque a besoin d'un effet spécial, par exemple appliquer un &amp;quot;bump mapping&amp;quot; (effet de relief sur des textures) cet effet devra utiliser le bac  &amp;quot;RenderBin&amp;quot;, ou le rendu suggéré met à &amp;quot;opaque&amp;quot;, et le G-buffer a besoin d'être initialisé correctement dans la phase Geometry.&lt;br /&gt;
&lt;br /&gt;
=== Soyez sûr que toute la Geometry distribuera l'ombre ===&lt;br /&gt;
&lt;br /&gt;
Pour limiter la quantité de rendu geometry dans la carte shadow, et aussi pour réduire les artefacts (acnée shadow), seulement les faces ne regardant pas le soleil distribuent les ombres. Le test est effectué en utilisant l'orientation normale. Cela veut dire que les polygones à double côté, ou mesh non fermés, seront transparents à la lumière sous certains angles de soleil. Pour éviter ça, les modeleurs peuvent:&lt;br /&gt;
*s'assurer que l'objet est toujours dans l'ombre d'autres objets,&lt;br /&gt;
*fermer leur mesh, ou&lt;br /&gt;
*doubler les polygones avec l'endroit normal à l'opposé&lt;br /&gt;
&lt;br /&gt;
=== Ajouts de lumière à un modèle===&lt;br /&gt;
&lt;br /&gt;
Deux points sont à considérer: l'apparence de la sourceet la zone illuminée. Pour l'apparence de la source lumière, (ce que vous voyez quand vous regardez le bulbe) vous avez besoin d'un modèle avec un emissive material qui produira  l'effet brillant et ceci est visible de nuit.&lt;br /&gt;
&lt;br /&gt;
Pour l'effet de la source dans son environnement (l'aire lumineuse), nous devons avoir dans le modèle 3D (le fichier .ac) un volume qui inclut l'effet (Volume Lumière). Cela peut être un grand cône pour les aires lumineuses ou une spère pour une lumière ponctuelle. Il est important que le volume lumière soit fermé, convexe et les normals orientés vers l'extérieur.&lt;br /&gt;
&lt;br /&gt;
Le volume lumière doit être partie de la geometry du modèle et être référencé dans le fichier animation. Pas besoin d'ajouter une couleur ou un effet à ce volume. Le calcul lumière est seulement fait sur les fragments couverts par le volume lumière, mais n'a aucune influence sur la couleur ou l'atténuation de la lumière .&lt;br /&gt;
&lt;br /&gt;
Toutes les animations disponibles sont possibles sur le volume lumière sauf '''material''' et '''texture'''. Il n'est pas possible de changer couleur et lumières, pour le moment; sauf en se branchant sur une autre animation. L'axe et la position sont dans l'espace objet et sont transformés par les animations qui suivent.&lt;br /&gt;
&lt;br /&gt;
==== Taches lumineuses ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Objectif&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Installe l'animation &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|C'est une lumière &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom donné à cette animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom du volume lumière dans le modèle 3D (typiquement un cône avec un sommet à &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, le long de l'axe &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; si &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; est inférieur à 90 degrés, ou une sphère centrée à  &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; si &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; est supérieur à 90 degrés )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Cache le volume lumière dans  fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace objet, position de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace objet, direction vers le centre de la tache&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur ambiante de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur diffuse de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur specular de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Groupe de paramètres pour contrôler un facteur appliqué en même temps à  ambient, diffuse et specular &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Trois element vector. &amp;lt;c&amp;gt; element est le facteur constant, &amp;lt;l&amp;gt; element est le facteur linéaire et &amp;lt;q&amp;gt; element est le facteur quadratique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation de couleur à distance d est [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplié par &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir étant vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vecteur à partir de la position lumière vers le point, dans l'espace caméra.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance minimum d'influence, à partir de la position, en mètres&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance maximum d'influence, à partir de la position, en mètres&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Points lumineux ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Objectif&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Installe l'animation &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|C'est une lumière &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom donné à cette animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom du volume lumière  dans le modèle 3D ( typiquement une sphère centrée sur &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, avec un rayon de &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Volume lumière cachée dans fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace object , position de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur ambiante de la lumière &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur diffuse de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur specular de la lumièret&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Groupe de paramètres pour contrôler un facteur appliqué à   ambient, diffuse et specular en même temps&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Trois element vector. &amp;lt;c&amp;gt; element est le facteur constant &amp;lt;l&amp;gt; element est le facteur linéaire et &amp;lt;q&amp;gt; element est le facteur quadratiquer.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation de couleur à distance d est [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance minimum d'influence, à partir de la position, en mètres&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance maximum d'influence, à partir de la position, en mètres&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Considérations de performance et de compatibilité ====&lt;br /&gt;
Chaque lumière sur écran équivaut, pour le GPU à redessiner le volume lumière avec un shader, sans recueillir de buffer. Ainsi, chaque lumière vient avec un coût, ce qui est minime individuellement parlant, mais non négligeable quand jl y en a beaucoup. Ce coût augmente  avec la taille du volume lumière&lt;br /&gt;
&lt;br /&gt;
De plus, il est raisonnable de permettre à un modèle de fonctionner avec le moteur de rendu classique qui ne sait rien des lumières et rendrait les volumes lumière comme une autre géométrie. Ainsi, c'est une bonne pratique de compléter chaque animation lumière par une animation sélective vérifiant :&lt;br /&gt;
*si Rembrandt est activé&lt;br /&gt;
*si le mode de qualité choisi correspond avec les possibilités de la lumière&lt;br /&gt;
*si la lumi§re doit être on ou off selon les autres paramètres de la simulation (position du soleil; position de du commutateur, présence de puissance...)&lt;br /&gt;
&lt;br /&gt;
Une bonne propriété est de crèer  un reflet des préférences de l'utilisateur sur  qualité vs performance concernant les lumières, et un curseur dédié est ajouté dans le dialogue shader.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
La propriété à utiliser est:&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
Le curseur qualité va de 0 (pas de lumière) à 4 (pleine lumière). Un simple réverbère d'aéroport apparaît à 1. Quelques lampes de pont à 2. Toutes les lampes de pont simples à 3, et les plus sophistiquées à 4&lt;br /&gt;
&lt;br /&gt;
Exemple:&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutoriels ===&lt;br /&gt;
[[User:F-JJTH|F-JJTH]] a compilé son expérience et celle de l'équipe de la PAF d'amélioration d'avions dans {{fr}} [http://equipe-flightgear.forumactif.com/t1034-howto-adapter-un-appareil-pour-rembrandt this tutorial].&lt;br /&gt;
&lt;br /&gt;
== TODO Liste ==&lt;br /&gt;
&lt;br /&gt;
=== Tâches à compléter ===&lt;br /&gt;
*Fixer le rendu shadow quand on emploie plusieurs liens en  OSG&lt;br /&gt;
*Implementer Cascaded Shadow Map (a besoin d'être optimisée - frustum calculation et nuit)&lt;br /&gt;
*Voir ce qui arrive avec brillance dans le brouillard: une sorte de terrain inconnu crée des patches blancs  dans le buffer emission-problème de génération de scène &lt;br /&gt;
*Test multi-écran (mostly done)&lt;br /&gt;
*Restorer splashscreen&lt;br /&gt;
*Dessiner des objets transparents avec rendu en premier (peut nécessiter la capture du bac transparence à partir de la phase géométrie et le placer dans la phase affichage)  (OK - nécessite une contribution modèle)&lt;br /&gt;
*Trouver une solution pour couleur ambient et emissive de material (peut nécessiter un buffer additionnel)&lt;br /&gt;
*Fournir un shader pour objets transparents qui puisse rendre le buffer emissive infaisable (en utilisant MRT) La phase lumière ne peut utiliser MRT &lt;br /&gt;
*Utiliser un buffer stencil pour limiter la taille lumière (non fait dans shader lumière)&lt;br /&gt;
**nécessaire pour la lumière de cockpit pour réaliser des faux shadowws et éviter d'éclairer le runway de la cabine&lt;br /&gt;
*Utiliser un système effet à la place des shaders lourdement codés&lt;br /&gt;
*Intensités globales de brillance, ou occlusion ambiante via curseur dans le dialogue rendu &lt;br /&gt;
&lt;br /&gt;
=== Tâches à court terme ===&lt;br /&gt;
*Convertir les shaders existants en rendu différé&lt;br /&gt;
*Éviter de redessiner les objets opaques dans la phase lumière. Améliorer le masque node OSG .&lt;br /&gt;
*S'occuper des particules et précipitations&lt;br /&gt;
*Fixer le brouillard sur les nuages &lt;br /&gt;
*Fixer les matrices shadow dans multi-screen&lt;br /&gt;
*IMettre en œuvre un lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Idées à long terme (non classées) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallerie ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendice ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[en:Project Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=56960</id>
		<title>Fr/Projet Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=56960"/>
		<updated>2013-01-06T11:22:24Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* De quoi s'agit-il ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Pourquoi ce nom? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] était un peintre hollandais du XVIIème siècle, maître incontesté du [http://en.wikipedia.org/wiki/Chiaroscuro &amp;quot;clair-obscur&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Ce projet a pour but de changer la manière de rendre les lumières et les [[Shadows|ombres]] qu'utilise [[FlightGear]], et d'essayer d'imiter le style de Rembrandt dans FG.&lt;br /&gt;
&lt;br /&gt;
== De quoi s'agit-il ? ==&lt;br /&gt;
L'idée maîtresse du projet est d'implémenter le [http://en.wikipedia.org/wiki/Deferred_shading rendu différé] au sein de FlightGear.&lt;br /&gt;
Depuis le début, FlightGear utilise un moteur de rendu classique, &amp;quot;en avant&amp;quot;, qui affiche toutes les propriétés d'un objet en une fois (ombre, éclairage, brouillard, ...), ce qui rend difficile le rendu d'un ombrage plus sophistiqué (voir le [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) du fait que tous les paramètres de [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ l'équation lumineuse] doivent être traités en une seule fois.&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Vue principale avec le contenu des buffers affichés dans les coins]]&lt;br /&gt;
Au contraire, le rendu différé cherche à séparer les opérations en étapes simplifiées, et à collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par les étapes suivantes.&lt;br /&gt;
&lt;br /&gt;
;Le premier stade est celui de la Géométrie:&lt;br /&gt;
: nous rendons la scène entière dans 4 textures, en utilisant le rendu multi-cibles pour les traiter en un seul passage: un pour le buffer de profondeur, un pour les normals (en bas à gauche de l'image), un pour les couleurs &amp;quot;diffuses&amp;quot; (en bas à gauche) et un pour les couleurs &amp;quot;spéculaires&amp;quot; (en haut à droite).&lt;br /&gt;
&lt;br /&gt;
;Le stade suivant est celui de l'ombre :&lt;br /&gt;
: nous rendons encore la scène dans une texture profondeur concernant les éclairages. Il y aura une texture pour chaque lumière diffusant des ombres.&lt;br /&gt;
&lt;br /&gt;
;Ensuite, c'est le stade de la lumière, avec plusieurs sous-stades :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: Le ciel est dessiné d'abord selon la méthode classique.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: la mémoire-tampon &amp;quot;diffuse&amp;quot; est modulée avec la couleur ambiante de la scène, et est dessinée comme un quad texturé aligné sur l'écran&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: Un second quad aligné à l'écran est dessiné et un shader examine la position pour calculer sa couleur &amp;quot;diffuse&amp;quot; et &amp;quot;specular&amp;quot; en utilisant le &amp;quot;normal&amp;quot; stocké dans le premier stade. La couleur résultante et mélangée avec la passe précédente. Les ombres sont examinées ici par comparaison de la position du pixel avec la position du cache lumière stockée dans la carte shadows&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: un nouvel écran quad est dessiné et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat de la phase précédente  &lt;br /&gt;
:*&amp;lt;u&amp;gt;stade de la lumière additionnelle&amp;lt;/u&amp;gt;: le scene graph sera traversé une autre fois pour afficher les volumes de lumière (cône ou tronc de cône pour les taches de lumière, sphère pour les lumières omni directionnelles), et leur shader ajoutera la lumière composée uniquement par les pixels éclairés.&lt;br /&gt;
:*&amp;lt;u&amp;gt;stade brouillard&amp;lt;/u&amp;gt;: un nouveau quad aligné sur l'écran est dessiné, et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat du stade précédent.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Stade des objets transparents&amp;lt;/u&amp;gt;: les objets transparents (et les nuages) sont enfin rendus en utilisant la méthode classique.&lt;br /&gt;
&lt;br /&gt;
:Tous les données de lumière sont accumulées dans une seule mémoire tampon, qui sera utilisée pour le dernier stade en addition au stade Géométrie.&lt;br /&gt;
&lt;br /&gt;
;A la fin, le stade affichage, avec l'option effet post-traitement :&lt;br /&gt;
:Les résultats des précédents tampons sont poussés dans le tampon principal pour être affichés, optionnellement modifiés pour montrer Glow, Motion blur, HDR, redout ou blackout, occlusion ambiante de l'espace écran, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
Dans FG, on termine le pipeline du rendu par l'affichage du [[Menubar|GUI]] et du [[HUD]].&lt;br /&gt;
&lt;br /&gt;
Tous ces phases sont plus précisément décrites dans [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] c'est la base du code actuel, avec quelques ajouts ou modifications.&lt;br /&gt;
&lt;br /&gt;
== Avertissements ==&lt;br /&gt;
Le rendu différé n'affiche pas la transparence. Pour le moment, les nuages doivent être éclairés et ombrés par eux-mêmes. Les surfaces transparentes sont alpha-testées et non mélangées. Elles doivent être amenées dans leur propre bac sur l'image composite.&lt;br /&gt;
&lt;br /&gt;
La partition profondeur ne marche pas non plus, à cause de la mémoire tampon profondeur, qui doit être gardée pour retenir la position de zone de vue, et, pour le moment, z-fighting est tout à fait visible. La partition profondeur sans rangée de profondeur superposée pourrait être la solution, et devrait être essayée.&lt;br /&gt;
&lt;br /&gt;
Le passage de la lumière peut rendre certains MFD illisibles (ce qui utilisent une couleur émissive) car flous. Ils devront être traités comme transparents.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mise en œuvre ==&lt;br /&gt;
=== Répertoires ===&lt;br /&gt;
Le code est la principale branche du [[FlightGear and Git|répertoire officiel]]. Aucune autre localisation n'existe.&lt;br /&gt;
&lt;br /&gt;
=== Rendu des surfaces transparentes ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Surfaces transparentes desssinées d'après des objets opaques]]&lt;br /&gt;
Les surfaces transparentes sont détectées par les plugins OSG loader et reçoivent des suggestions de rendu TRANSPARENT_BIN&lt;br /&gt;
 Au stade collection, le collecteur commande les surfaces transparentes dans le le bac transparent. Dans un retour, attaché à la caméra Géometry, après la traversée scénographe, les bacs transparent sont enlevés de la phase rendu et sauvegardés dans un espace temporaire. Dans un retour attaché  la caméra Éclairage, après la traversée sceneraph, les bacs transparents sauvegardent au prochain stade, sont ajoutés  au stade rendu de la caméra éclairageavec un numéro d'ordre. Ainsi, les surfaces transparentes sont dessinées au sommet de la scene éclairée à partir de G-buffer .&lt;br /&gt;
&lt;br /&gt;
=== Consommation de mémoire ===&lt;br /&gt;
Pour chaque caméra définie du groupe, il y a une carte d'ombre séparée, de telle sorte que l'utilisation de la mémoire vidéo soit:&lt;br /&gt;
* G-tampon et tampon lumière: 20 bytes par pixel. Pour un écran HD (1920x1080) la mémoire requise est de 40 Mb&lt;br /&gt;
* Carte d'ombre 3 x taille_carte_ombre x shadow_map_size bytes (si la taille est 8192, la taille totale de la mémoire est 192 Mb&lt;br /&gt;
Ne pas compter les textures, liste d'affichage ou tampons vertex pour modèles et terrains&lt;br /&gt;
&lt;br /&gt;
3 écrans HD ont besoin de 120 Mb de mémoire pour les tampons (ombre exclue), il vous faut  3x8192x8192x3 = 576 Mb (megabytes) de mémoire pour les seuls shadows.&lt;br /&gt;
&lt;br /&gt;
Si vous voyez des messages d'erreur pendant le démarrage, ou si FlightGear ne démarre pas bien, c'est probablement parceque vous n'avez pas assez de mémoire vidéo libre. Réduisez la taille de la carte d'ombre dans préférences.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Et mettez 4096 ou 2048 à la place.Vous pouvez aussi utiliser un paramètre de démarrage: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Pipeline configurable  ===&lt;br /&gt;
&lt;br /&gt;
Le rendu Rembrandt utilise un fichier XML  pour installer son pipeline pour chaque fenêtre décrite dans le groupe de cameras. Ce fichier mntre la façon dont les tampons intermédiaires sont établis, et comment les différentes étapes du rendu sont agencés. Le schéma général du fichier pipeline est le suivant :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ere définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ère définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Tampons (Buffers)====&lt;br /&gt;
Un tampon est une texture utilisée comme zone de stockage dans le GPU. Sa taille est habituellement un multiple de la taille de l'écran, mais une taille fixe est prise en charge ( typique pour la carte d'ombres). La description d'un tampon suit :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Phases ====&lt;br /&gt;
Une phase est une unité de rendu d'un groupe de tampons. La plupart des phases sont pré-définies et leur type n'est pas libre. Quand un type n'est pas spécifié, le nom est utilisé? Les types de phases sont :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|La phase geometry initialise la plupart des tampons et agit sur les objets réels et la géométrie. Les objets transparents sont placés à côté, et seront utilisés tels quels dans la phase lumière. Le reste de la géométrie opaque  est rendu avec les effets standard, permettant de mettre la donnée sensible dans les tampons.&lt;br /&gt;
|-&lt;br /&gt;
|ombre&lt;br /&gt;
|Dans cette phase, la géométrie est rendue dans la carte normale à partir de la perspective du soleil.&lt;br /&gt;
|-&lt;br /&gt;
|lumière&lt;br /&gt;
|Cette phase utilise les tampons remplis par les phases précédrntes pour éclairer  chaque pixel de la scène. Le résultat est rendu dans un autre tampon pour permettre des effets ultérieurs.&lt;br /&gt;
|-&lt;br /&gt;
|plein écran&lt;br /&gt;
|Les phases de ce type sont utilisés pour changer la scène entière, ou transformer une donnée à partir d'un tampon particulier.&lt;br /&gt;
|-&lt;br /&gt;
|affichage&lt;br /&gt;
|Le rendu final de la scène à l'écran est jugé à l'écran, ou la texture est définie dans le groupe caméra .&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ci-dessous, une description de phase :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optionnel si le nom est l'un des types prédéfinis sauf plein écran  --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Les phases sont rendues dans les tampons (sauf pur la phase affichage). Les pièces jointes disent quels tampons sony affectés par chaque phase.&lt;br /&gt;
&lt;br /&gt;
===== Pièces jointes =====&lt;br /&gt;
La pièce jointe décrit la liaison entre tampon et poit d'attachement :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissions(passes) =====&lt;br /&gt;
Les Passes sont seulement disponibles dans la phase &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt;. trois sortes de phases sont autorisées :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Rendus de la voûte céleste, solei, lune, planète, étoiles et nuages&lt;br /&gt;
|-&lt;br /&gt;
|lumières&lt;br /&gt;
|Rendus des taches additionnelles et points lumineux &lt;br /&gt;
|-&lt;br /&gt;
|plein écran&lt;br /&gt;
|Le pass fullscreen analogue à une phase fullscreen sauf qu'il est rendu dans des tampons attachés à la phase lumière&lt;br /&gt;
|}&lt;br /&gt;
Un pass est défini ci-dessous :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optionnel si le nom est prédéfini excepté fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une phase lumière typique est une succession de 5 pass:&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour lumière ambiante&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour lumière solaire (et ombres)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour brouillard&lt;br /&gt;
&lt;br /&gt;
Chaque effet attaché au plein écran définit le mélange fait entre le pass et la somme précédente de rendu.&lt;br /&gt;
&lt;br /&gt;
== Démarrage de FlightGear avec Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|dialogue Rembrandt]]&lt;br /&gt;
Le rendu Rembrandt est maintenant intégré dans le répertoire principal, mais doit être activé pour démarrer. Il y a deux façons de l'activer (une seule est nécessaire):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (lorsqu'on utilise [[FGRun]], on peut ajouter ceci derrière le &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; sur la première page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (avec FGRun on peut ajouter ceci via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; sur la dernière page).&lt;br /&gt;
&lt;br /&gt;
Le &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialogue vous permet de  basculer et d'ajuster les différentes options offertes par Rembrandt.&lt;br /&gt;
&lt;br /&gt;
Rembrandt est très gourmand en ressources GPU et son démarrage peut échouer avec les options par défaut. Le symptome le plus fréquent est un message OSG dans la console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
On peut voir aussi :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
Des options additionnelles peuvent éviter ces problèmes :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Certaines vieilles cartes NVidia comme 7600GT, n'ont pas assez de résolution pour la profondeur, et on voit des &amp;quot;rideaux de brouillard&amp;quot; à quelques mètres devant. Une astuce consiste à encoder la profondeur dans une autre texture et donner la valeur correcte ensuite. Cette option permet cela.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Désactive les ombres tout à fait.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Évite le message &amp;quot;error C6013&amp;quot; sur les vieilles cartes en manque de résolution dans le cockpitt. Mettez &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; pour changer la taille de la carte d'ombre. Plus de taille, et moins de résolution (la valeur par défaut est 5 mètres)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Définnissez la taille de la carte d'ombres. Les valeurs utilles sont 1024, 2048, 4096 ou 8192. Peu de cartes supportent 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Définissez le nombre de cascades de la carte ombre. Moins de cascades signifie moins de temps passé à générer la carte shadow, mais aussi signifie une qualité moindre de l'ombre. Mettez entre 1 et 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Définissez la taille de cascade de la carte shadow pour chaque cascade. Les valeurs par défaut sont 5m, 50m, 500m et 5000m pour 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Par défaut, Rembrandt utilise normalement des tampons de 8 bits  (ainsi, la propriété est vraiment définie par défaut). Ceci peut créer des artefacts pour les éclairages specular. Si c'est inacceptable et si le GPU le supporte, mettez false pour avoir une meilleure précision pour les normales et les effets s'appuyant sur une direction normale.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lignes directrices pour les écritures shader ==&lt;br /&gt;
=== Uniformes prédéfinis ===&lt;br /&gt;
Ces uniformes glsl n'ont pas besoin d'être déclarés dans le fichier effet&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Type&lt;br /&gt;
!Objectif&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;
|En pass plein écran seulement, view matrix utilisé our transformer la position écran en direction vue&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;
|En pass plein écran seulement, view matrix inverse employé pour transformer la position écran en direction vue&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;
|En pass plein écran seulement, projection matri inverse employé pour transformer la position écran en direction vue&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 de la caméra en coordonnées cartésiennes&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 de la caméra dans l'espace, exprimé en coordonnées géodésiques (longitude et latitude en radians, élévation en mètres)&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;
|&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;
|&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;
|&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;
|&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;
|Dire si la profondeur est rangée dans une texture profondeur ou une texture couleur&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;
|Utilisé pour convertir la valeur du tampon profondeur en une profondeur qui peut être utilisée pour calculer la position dans l'espace du 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 du tampon, utilisé pour convertir  gl_FragCoord dans la taille [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;
|Definie par OSG, employé seulement lors du travail sur la géométrie réelle&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;
|Definie par OSG, employé seulement lors du travail sur la géométrie réelle&lt;br /&gt;
|}&lt;br /&gt;
.Ils doivent encore être déclarés dans le fragment du vertex shader&lt;br /&gt;
&lt;br /&gt;
=== Fonctions utilitaires ===&lt;br /&gt;
&lt;br /&gt;
Pour faciliter la maintenance des shaders plusieurs fonctions utilitaires sont disponibles pour le fragment shader. Ces fonctions sont placées ensemble dans deux fichiers : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Utilisé pour encoder youtes les valeurs de  G-Buffer dans material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Employé pour compresser normals à l'intérieur de G-Buffer dans material shaders. Normalement appelé de &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit normals à partir de G-Buffer. Employé dans shaders plein écran et shaders lumière&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode les valeurs float dans la taille [0..1] dans les  24 bits d'une couleur. cette fonction est employée par &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; si le &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; est vrai, pour les vieilles cartes qui ne fournissent pas d'information profondeur avec assez de résolution dans les shaders fullscreen ou lumière.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Décode les valeurs float dans la taille [0..1] dans les  24 bits d'une couleur. cette fonction est employée par &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; si le &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; est vrai, pour les vieilles cartes qui ne fournissent pas d'information profondeur avec assez de résolution dans les shaders fullscreen ou lumière.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit la position eye space à partir de la direction view position a partir de la view direction et la profondeur lue du tampon profondeur &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
::Reconstruit la position eye space à partir de la direction view et la profondeur encodée dans une couleur lue du tampon profondeur&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit la position eye space à partir de la direction vue et du tampon profondeur (profondeur réelle ou couleur selon la valeur de &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) à un fragment donné sur l'écran, donné par &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
Pour les shaders material, il faut fournir à la fois  &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; dans le fichier effet, comme suit :&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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
Pour les shaders fullscreen passes, on doit fournir seulement &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt;, comme ceci  :&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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
Dans la principale fonction du shader, les fonctions référencées doivent être écrites en premier. Avec no #include files, le prototype de la fonction entière nécessite d'être typé :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Phase Geometry  ===&lt;br /&gt;
La phase Geometry est là pour remplir le G-tampon.  '''L'ombrage n'intervient pas à cette phase, et le calcul lumière ou brouillard ne doit pas faire partie du shader '''. L'opération requise dans le fragment Shader est de remplir avec une valeur sensible chaque tampon individuel :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|pràfondeur (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment profondeur&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ceci est la couche par défaut attendue par le shader . material Id peut être utilisé pour détecter une couche différente&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pass lumière additionnelle ===&lt;br /&gt;
Il y aura là un seul shader pour chaque type de lumière utilisé. L'objectif est de créer des lumières comme animations dans le fichier model XML.   Le shader lumière retrouvera la scène geometry en combinant la position espace écran en vue de rayon espace par l'inversion de la matrix projection (une fonction plus secourable sera fournie), et le fragment profondeur à cette  position écran lit à partir du tampon profondeur. Avec l'aide du fragment normal, la couleur diffuse et specular et les propriétés de la lumière que le shader introduit, il sera possible d'ajouter au tampon lumière l'apport du rendu lumière.&lt;br /&gt;
&lt;br /&gt;
===Pass brouillard===&lt;br /&gt;
En utilisant le fragment profondeur, il sera possible de calculer une distribution brouillard. Pour le moment, il n'y a que l'équation simple brouillard.&lt;br /&gt;
&lt;br /&gt;
===Pass fleur===&lt;br /&gt;
C'est un effet double pass qui rend flou le tampon lumière dans une petite texture. Cette texture est ensuite ajoutée au tampon lumière lors de la phase affichage.&lt;br /&gt;
&lt;br /&gt;
=== Effets requis ===&lt;br /&gt;
Plusieurs pass sont mis en œuvre pour l'utilisation du système effet. Dans ce but , des effets sont référencés dans le code core utilisant des noms réservés. Ces effets sont:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Type&lt;br /&gt;
!But&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad plein écran&lt;br /&gt;
|Calcule l'occlusion ambiante à partir du tampon normal et du tampon profondeur&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad plein écran &lt;br /&gt;
|Copie le tampon couleur diffuse  multiplié par la lumière ambiante au tampon éclairage. L'occlusion ambiante peut aussi affecter la lumière ambiante .&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur la géométrie réeelle du volume de la lumière&lt;br /&gt;
|Calcule la contribution lumière d'un point lumineux défini dans une animation &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt;ayant un &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; de '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad de plein écran&lt;br /&gt;
|Calcule le brouillard à partir du C-buffer et les paramètres de l'éclairage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad de plein écran&lt;br /&gt;
|Rends l'image finale composite à partir du G-buffer et du buffer éclairage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lignes-guide pour modeleurs ==&lt;br /&gt;
&lt;br /&gt;
=== Portage d'avion ===&lt;br /&gt;
* Rembrandt calcule les ombres =&amp;gt; plus de fausses ombres dans le modèle&lt;br /&gt;
* Rembrandt calcule l'occlusion ambiante =&amp;gt; pas d'occlusion ambiante incluse dans les textures&lt;br /&gt;
* Rembrandt est en lumière =&amp;gt; les cartes lumière static ne sont pas nécéssaires, la couleur émissive pour voir les modèles n'est pas nécessaire, et pourrait interférer&lt;br /&gt;
* Rembrandt est brillant =&amp;gt; les couleurs émissives incorrectement utilisées peuvent rendre flou, et rendre du texte illisible. L'intensité de la lumière devra être réglée&lt;br /&gt;
* Rembrandt a des besoins précis avec les shaders =&amp;gt; les shaders nécessitent un ajustement pour se conformer au nouveau cadre, sinon la vue sera faussée&lt;br /&gt;
* Rembrandt ne peut faire des surfaces transparentes =&amp;gt; les surfaces transparentes doivent être dûment enregistrées pour les atteindre avec le chemin classique&lt;br /&gt;
&lt;br /&gt;
=== Enregistrement de toutes les surfaces translucides ===&lt;br /&gt;
&lt;br /&gt;
Chaque modèle est par défaut rendu en utilisant l'effet  &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt;. Cet effet initialise le G-buffer, en ignorant les surfaces transparentes, en mettant  alpha test et  rendu de toute la geometrie dans la poubelle. Il n'est pas possible de rediriger le rendu vers les bacs transparents lorsque la texture associée a un canal alpha car la plupart des modeles emploient un atlas simple texture et même les parties opaques sont rendues avec texture avec alpha canal.&lt;br /&gt;
&lt;br /&gt;
Si un modèle nécessite des surfaces translucides ou transparentes , ces objets surface doivent être assignés à un effet différent  qui place explicitement le bac rendu à &amp;quot;DepthSortedBin&amp;quot;, ou met la suggestion rendu à &amp;quot;transparent&amp;quot;. Ceci dit au moteur de rendu de rendre cet objet opérant avant le rendu, ainsi, la clarté et le brouillard doivent être activés, et si un programme shader est utilisé, et s'ils ont été calculés en manière classique. Le   &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; peut être utilisé pour enregistrer simlement les surfaces transparentes/translucides. Vous attribuez cet effet à un objet (ou à de multiples objets) comme:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Attention: &amp;lt;Effect&amp;gt; agit seulement sur les objets réels, pas sur des groupes d'objets ou des animations.'''&lt;br /&gt;
&lt;br /&gt;
Si la surface opaque a besoin d'un effet spécial, par exemple appliquer un &amp;quot;bump mapping&amp;quot; (effet de relief sur des textures) cet effet devra utiliser le bac  &amp;quot;RenderBin&amp;quot;, ou le rendu suggéré met à &amp;quot;opaque&amp;quot;, et le G-buffer a besoin d'être initialisé correctement dans la phase Geometry.&lt;br /&gt;
&lt;br /&gt;
=== Soyez sûr que toute la Geometry distribuera l'ombre ===&lt;br /&gt;
&lt;br /&gt;
Pour limiter la quantité de rendu geometry dans la carte shadow, et aussi pour réduire les artefacts (acnée shadow), seulement les faces ne regardant pas le soleil distribuent les ombres. Le test est effectué en utilisant l'orientation normale. Cela veut dire que les polygones à double côté, ou mesh non fermés, seront transparents à la lumière sous certains angles de soleil. Pour éviter ça, les modeleurs peuvent:&lt;br /&gt;
*s'assurer que l'objet est toujours dans l'ombre d'autres objets,&lt;br /&gt;
*fermer leur mesh, ou&lt;br /&gt;
*doubler les polygones avec l'endroit normal à l'opposé&lt;br /&gt;
&lt;br /&gt;
=== Ajouts de lumière à un modèle===&lt;br /&gt;
&lt;br /&gt;
Deux points sont à considérer: l'apparence de la sourceet la zone illuminée. Pour l'apparence de la source lumière, (ce que vous voyez quand vous regardez le bulbe) vous avez besoin d'un modèle avec un emissive material qui produira  l'effet brillant et ceci est visible de nuit.&lt;br /&gt;
&lt;br /&gt;
Pour l'effet de la source dans son environnement (l'aire lumineuse), nous devons avoir dans le modèle 3D (le fichier .ac) un volume qui inclut l'effet (Volume Lumière). Cela peut être un grand cône pour les aires lumineuses ou une spère pour une lumière ponctuelle. Il est important que le volume lumière soit fermé, convexe et les normals orientés vers l'extérieur.&lt;br /&gt;
&lt;br /&gt;
Le volume lumière doit être partie de la geometry du modèle et être référencé dans le fichier animation. Pas besoin d'ajouter une couleur ou un effet à ce volume. Le calcul lumière est seulement fait sur les fragments couverts par le volume lumière, mais n'a aucune influence sur la couleur ou l'atténuation de la lumière .&lt;br /&gt;
&lt;br /&gt;
Toutes les animations disponibles sont possibles sur le volume lumière sauf '''material''' et '''texture'''. Il n'est pas possible de changer couleur et lumières, pour le moment; sauf en se branchant sur une autre animation. L'axe et la position sont dans l'espace objet et sont transformés par les animations qui suivent.&lt;br /&gt;
&lt;br /&gt;
==== Taches lumineuses ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Objectif&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Installe l'animation &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|C'est une lumière &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom donné à cette animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom du volume lumière dans le modèle 3D (typiquement un cône avec un sommet à &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, le long de l'axe &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; si &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; est inférieur à 90 degrés, ou une sphère centrée à  &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; si &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; est supérieur à 90 degrés )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Cache le volume lumière dans  fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace objet, position de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace objet, direction vers le centre de la tache&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur ambiante de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur diffuse de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur specular de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Groupe de paramètres pour contrôler un facteur appliqué en même temps à  ambient, diffuse et specular &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Trois element vector. &amp;lt;c&amp;gt; element est le facteur constant, &amp;lt;l&amp;gt; element est le facteur linéaire et &amp;lt;q&amp;gt; element est le facteur quadratique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation de couleur à distance d est [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplié par &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir étant vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vecteur à partir de la position lumière vers le point, dans l'espace caméra.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance minimum d'influence, à partir de la position, en mètres&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance maximum d'influence, à partir de la position, en mètres&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Points lumineux ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Objectif&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Installe l'animation &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|C'est une lumière &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom donné à cette animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom du volume lumière  dans le modèle 3D ( typiquement une sphère centrée sur &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, avec un rayon de &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Volume lumière cachée dans fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace object , position de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur ambiante de la lumière &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur diffuse de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur specular de la lumièret&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Groupe de paramètres pour contrôler un facteur appliqué à   ambient, diffuse et specular en même temps&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Trois element vector. &amp;lt;c&amp;gt; element est le facteur constant &amp;lt;l&amp;gt; element est le facteur linéaire et &amp;lt;q&amp;gt; element est le facteur quadratiquer.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation de couleur à distance d est [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance minimum d'influence, à partir de la position, en mètres&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance maximum d'influence, à partir de la position, en mètres&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Considérations de performance et de compatibilité ====&lt;br /&gt;
Chaque lumière sur écran équivaut, pour le GPU à redessiner le volume lumière avec un shader, sans recueillir de buffer. Ainsi, chaque lumière vient avec un coût, ce qui est minime individuellement parlant, mais non négligeable quand jl y en a beaucoup. Ce coût augmente  avec la taille du volume lumière&lt;br /&gt;
&lt;br /&gt;
De plus, il est raisonnable de permettre à un modèle de fonctionner avec le moteur de rendu classique qui ne sait rien des lumières et rendrait les volumes lumière comme une autre géométrie. Ainsi, c'est une bonne pratique de compléter chaque animation lumière par une animation sélective vérifiant :&lt;br /&gt;
*si Rembrandt est activé&lt;br /&gt;
*si le mode de qualité choisi correspond avec les possibilités de la lumière&lt;br /&gt;
*si la lumi§re doit être on ou off selon les autres paramètres de la simulation (position du soleil; position de du commutateur, présence de puissance...)&lt;br /&gt;
&lt;br /&gt;
Une bonne propriété est de crèer  un reflet des préférences de l'utilisateur sur  qualité vs performance concernant les lumières, et un curseur dédié est ajouté dans le dialogue shader.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
La propriété à utiliser est:&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
Le curseur qualité va de 0 (pas de lumière) à 4 (pleine lumière). Un simple réverbère d'aéroport apparaît à 1. Quelques lampes de pont à 2. Toutes les lampes de pont simples à 3, et les plus sophistiquées à 4&lt;br /&gt;
&lt;br /&gt;
Exemple:&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutoriels ===&lt;br /&gt;
[[User:F-JJTH|F-JJTH]] a compilé son expérience et celle de l'équipe de la PAF d'amélioration d'avions dans {{fr}} [http://equipe-flightgear.forumactif.com/t1034-howto-adapter-un-appareil-pour-rembrandt this tutorial].&lt;br /&gt;
&lt;br /&gt;
== TODO Liste ==&lt;br /&gt;
&lt;br /&gt;
=== Tâches à compléter ===&lt;br /&gt;
*Fixer le rendu shadow quand on emploie plusieurs liens en  OSG&lt;br /&gt;
*Implementer Cascaded Shadow Map (a besoin d'être optimisée - frustum calculation et nuit)&lt;br /&gt;
*Voir ce qui arrive avec brillance dans le brouillard: une sorte de terrain inconnu crée des patches blancs  dans le buffer emission-problème de génération de scène &lt;br /&gt;
*Test multi-écran (mostly done)&lt;br /&gt;
*Restorer splashscreen&lt;br /&gt;
*Dessiner des objets transparents avec rendu en premier (peut nécessiter la capture du bac transparence à partir de la phase géométrie et le placer dans la phase affichage)  (OK - nécessite une contribution modèle)&lt;br /&gt;
*Trouver une solution pour couleur ambient et emissive de material (peut nécessiter un buffer additionnel)&lt;br /&gt;
*Fournir un shader pour objets transparents qui puisse rendre le buffer emissive infaisable (en utilisant MRT) La phase lumière ne peut utiliser MRT &lt;br /&gt;
*Utiliser un buffer stencil pour limiter la taille lumière (non fait dans shader lumière)&lt;br /&gt;
**nécessaire pour la lumière de cockpit pour réaliser des faux shadowws et éviter d'éclairer le runway de la cabine&lt;br /&gt;
*Utiliser un système effet à la place des shaders lourdement codés&lt;br /&gt;
*Intensités globales de brillance, ou occlusion ambiante via curseur dans le dialogue rendu &lt;br /&gt;
&lt;br /&gt;
=== Tâches à court terme ===&lt;br /&gt;
*Convertir les shaders existants en rendu différé&lt;br /&gt;
*Éviter de redessiner les objets opaques dans la phase lumière. Améliorer le masque node OSG .&lt;br /&gt;
*S'occuper des particules et précipitations&lt;br /&gt;
*Fixer le brouillard sur les nuages &lt;br /&gt;
*Fixer les matrices shadow dans multi-screen&lt;br /&gt;
*IMettre en œuvre un lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Idées à long terme (non classées) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallerie ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendice ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[en:Project Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=56959</id>
		<title>Fr/Projet Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=56959"/>
		<updated>2013-01-06T11:20:47Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* De quoi s'agit-il ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Pourquoi ce nom? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] était un peintre hollandais du XVIIème siècle, maître incontesté du [http://en.wikipedia.org/wiki/Chiaroscuro &amp;quot;clair-obscur&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Ce projet a pour but de changer la manière de rendre les lumières et les [[Shadows|ombres]] qu'utilise [[FlightGear]], et d'essayer d'imiter le style de Rembrandt dans FG.&lt;br /&gt;
&lt;br /&gt;
== De quoi s'agit-il ? ==&lt;br /&gt;
L'idée maîtresse du projet est d'implémenter le [http://en.wikipedia.org/wiki/Deferred_shading rendu différé] au sein de FlightGear.&lt;br /&gt;
Depuis le début, FlightGear utilise un moteur de rendu classique, &amp;quot;en avant&amp;quot;, qui affiche toutes les propriétés d'un objet en une fois (ombre, éclairage, brouillard, ...), ce qui rend difficile le rendu d'un ombrage plus sophistiqué (voir le [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) du fait que tous les paramètres de [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ l'équation lumineuse] doivent être traités en une seule fois.&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Vue principale avec le contenu des buffers affichés dans les coins]]&lt;br /&gt;
Au contraire, le rendu différé cherche à séparer les opérations en étapes simplifiées, et à collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par la prochain étape.&lt;br /&gt;
&lt;br /&gt;
;Le premier stade est celui de la Géométrie:&lt;br /&gt;
: nous rendons la scène entière dans 4 textures, en utilisant le rendu multi-cibles pour les traiter en un seul passage: un pour le buffer de profondeur, un pour les normals (en bas à gauche de l'image), un pour les couleurs &amp;quot;diffuses&amp;quot; (en bas à gauche) et un pour les couleurs &amp;quot;spéculaires&amp;quot; (en haut à droite).&lt;br /&gt;
&lt;br /&gt;
;Le stade suivant est celui de l'ombre :&lt;br /&gt;
: nous rendons encore la scène dans une texture profondeur concernant les éclairages. Il y aura une texture pour chaque lumière diffusant des ombres.&lt;br /&gt;
&lt;br /&gt;
;Ensuite, c'est le stade de la lumière, avec plusieurs sous-stades :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: Le ciel est dessiné d'abord selon la méthode classique.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: la mémoire-tampon &amp;quot;diffuse&amp;quot; est modulée avec la couleur ambiante de la scène, et est dessinée comme un quad texturé aligné sur l'écran&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: Un second quad aligné à l'écran est dessiné et un shader examine la position pour calculer sa couleur &amp;quot;diffuse&amp;quot; et &amp;quot;specular&amp;quot; en utilisant le &amp;quot;normal&amp;quot; stocké dans le premier stade. La couleur résultante et mélangée avec la passe précédente. Les ombres sont examinées ici par comparaison de la position du pixel avec la position du cache lumière stockée dans la carte shadows&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: un nouvel écran quad est dessiné et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat de la phase précédente  &lt;br /&gt;
:*&amp;lt;u&amp;gt;stade de la lumière additionnelle&amp;lt;/u&amp;gt;: le scene graph sera traversé une autre fois pour afficher les volumes de lumière (cône ou tronc de cône pour les taches de lumière, sphère pour les lumières omni directionnelles), et leur shader ajoutera la lumière composée uniquement par les pixels éclairés.&lt;br /&gt;
:*&amp;lt;u&amp;gt;stade brouillard&amp;lt;/u&amp;gt;: un nouveau quad aligné sur l'écran est dessiné, et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat du stade précédent.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Stade des objets transparents&amp;lt;/u&amp;gt;: les objets transparents (et les nuages) sont enfin rendus en utilisant la méthode classique.&lt;br /&gt;
&lt;br /&gt;
:Tous les données de lumière sont accumulées dans une seule mémoire tampon, qui sera utilisée pour le dernier stade en addition au stade Géométrie.&lt;br /&gt;
&lt;br /&gt;
;A la fin, le stade affichage, avec l'option effet post-traitement :&lt;br /&gt;
:Les résultats des précédents tampons sont poussés dans le tampon principal pour être affichés, optionnellement modifiés pour montrer Glow, Motion blur, HDR, redout ou blackout, occlusion ambiante de l'espace écran, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
Dans FG, on termine le pipeline du rendu par l'affichage du [[Menubar|GUI]] et du [[HUD]].&lt;br /&gt;
&lt;br /&gt;
Tous ces phases sont plus précisément décrites dans [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] c'est la base du code actuel, avec quelques ajouts ou modifications.&lt;br /&gt;
&lt;br /&gt;
== Avertissements ==&lt;br /&gt;
Le rendu différé n'affiche pas la transparence. Pour le moment, les nuages doivent être éclairés et ombrés par eux-mêmes. Les surfaces transparentes sont alpha-testées et non mélangées. Elles doivent être amenées dans leur propre bac sur l'image composite.&lt;br /&gt;
&lt;br /&gt;
La partition profondeur ne marche pas non plus, à cause de la mémoire tampon profondeur, qui doit être gardée pour retenir la position de zone de vue, et, pour le moment, z-fighting est tout à fait visible. La partition profondeur sans rangée de profondeur superposée pourrait être la solution, et devrait être essayée.&lt;br /&gt;
&lt;br /&gt;
Le passage de la lumière peut rendre certains MFD illisibles (ce qui utilisent une couleur émissive) car flous. Ils devront être traités comme transparents.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mise en œuvre ==&lt;br /&gt;
=== Répertoires ===&lt;br /&gt;
Le code est la principale branche du [[FlightGear and Git|répertoire officiel]]. Aucune autre localisation n'existe.&lt;br /&gt;
&lt;br /&gt;
=== Rendu des surfaces transparentes ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Surfaces transparentes desssinées d'après des objets opaques]]&lt;br /&gt;
Les surfaces transparentes sont détectées par les plugins OSG loader et reçoivent des suggestions de rendu TRANSPARENT_BIN&lt;br /&gt;
 Au stade collection, le collecteur commande les surfaces transparentes dans le le bac transparent. Dans un retour, attaché à la caméra Géometry, après la traversée scénographe, les bacs transparent sont enlevés de la phase rendu et sauvegardés dans un espace temporaire. Dans un retour attaché  la caméra Éclairage, après la traversée sceneraph, les bacs transparents sauvegardent au prochain stade, sont ajoutés  au stade rendu de la caméra éclairageavec un numéro d'ordre. Ainsi, les surfaces transparentes sont dessinées au sommet de la scene éclairée à partir de G-buffer .&lt;br /&gt;
&lt;br /&gt;
=== Consommation de mémoire ===&lt;br /&gt;
Pour chaque caméra définie du groupe, il y a une carte d'ombre séparée, de telle sorte que l'utilisation de la mémoire vidéo soit:&lt;br /&gt;
* G-tampon et tampon lumière: 20 bytes par pixel. Pour un écran HD (1920x1080) la mémoire requise est de 40 Mb&lt;br /&gt;
* Carte d'ombre 3 x taille_carte_ombre x shadow_map_size bytes (si la taille est 8192, la taille totale de la mémoire est 192 Mb&lt;br /&gt;
Ne pas compter les textures, liste d'affichage ou tampons vertex pour modèles et terrains&lt;br /&gt;
&lt;br /&gt;
3 écrans HD ont besoin de 120 Mb de mémoire pour les tampons (ombre exclue), il vous faut  3x8192x8192x3 = 576 Mb (megabytes) de mémoire pour les seuls shadows.&lt;br /&gt;
&lt;br /&gt;
Si vous voyez des messages d'erreur pendant le démarrage, ou si FlightGear ne démarre pas bien, c'est probablement parceque vous n'avez pas assez de mémoire vidéo libre. Réduisez la taille de la carte d'ombre dans préférences.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Et mettez 4096 ou 2048 à la place.Vous pouvez aussi utiliser un paramètre de démarrage: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Pipeline configurable  ===&lt;br /&gt;
&lt;br /&gt;
Le rendu Rembrandt utilise un fichier XML  pour installer son pipeline pour chaque fenêtre décrite dans le groupe de cameras. Ce fichier mntre la façon dont les tampons intermédiaires sont établis, et comment les différentes étapes du rendu sont agencés. Le schéma général du fichier pipeline est le suivant :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ere définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ère définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Tampons (Buffers)====&lt;br /&gt;
Un tampon est une texture utilisée comme zone de stockage dans le GPU. Sa taille est habituellement un multiple de la taille de l'écran, mais une taille fixe est prise en charge ( typique pour la carte d'ombres). La description d'un tampon suit :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Phases ====&lt;br /&gt;
Une phase est une unité de rendu d'un groupe de tampons. La plupart des phases sont pré-définies et leur type n'est pas libre. Quand un type n'est pas spécifié, le nom est utilisé? Les types de phases sont :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|La phase geometry initialise la plupart des tampons et agit sur les objets réels et la géométrie. Les objets transparents sont placés à côté, et seront utilisés tels quels dans la phase lumière. Le reste de la géométrie opaque  est rendu avec les effets standard, permettant de mettre la donnée sensible dans les tampons.&lt;br /&gt;
|-&lt;br /&gt;
|ombre&lt;br /&gt;
|Dans cette phase, la géométrie est rendue dans la carte normale à partir de la perspective du soleil.&lt;br /&gt;
|-&lt;br /&gt;
|lumière&lt;br /&gt;
|Cette phase utilise les tampons remplis par les phases précédrntes pour éclairer  chaque pixel de la scène. Le résultat est rendu dans un autre tampon pour permettre des effets ultérieurs.&lt;br /&gt;
|-&lt;br /&gt;
|plein écran&lt;br /&gt;
|Les phases de ce type sont utilisés pour changer la scène entière, ou transformer une donnée à partir d'un tampon particulier.&lt;br /&gt;
|-&lt;br /&gt;
|affichage&lt;br /&gt;
|Le rendu final de la scène à l'écran est jugé à l'écran, ou la texture est définie dans le groupe caméra .&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ci-dessous, une description de phase :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optionnel si le nom est l'un des types prédéfinis sauf plein écran  --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Les phases sont rendues dans les tampons (sauf pur la phase affichage). Les pièces jointes disent quels tampons sony affectés par chaque phase.&lt;br /&gt;
&lt;br /&gt;
===== Pièces jointes =====&lt;br /&gt;
La pièce jointe décrit la liaison entre tampon et poit d'attachement :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissions(passes) =====&lt;br /&gt;
Les Passes sont seulement disponibles dans la phase &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt;. trois sortes de phases sont autorisées :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Rendus de la voûte céleste, solei, lune, planète, étoiles et nuages&lt;br /&gt;
|-&lt;br /&gt;
|lumières&lt;br /&gt;
|Rendus des taches additionnelles et points lumineux &lt;br /&gt;
|-&lt;br /&gt;
|plein écran&lt;br /&gt;
|Le pass fullscreen analogue à une phase fullscreen sauf qu'il est rendu dans des tampons attachés à la phase lumière&lt;br /&gt;
|}&lt;br /&gt;
Un pass est défini ci-dessous :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optionnel si le nom est prédéfini excepté fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- seulement si type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une phase lumière typique est une succession de 5 pass:&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour lumière ambiante&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour lumière solaire (et ombres)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass pour brouillard&lt;br /&gt;
&lt;br /&gt;
Chaque effet attaché au plein écran définit le mélange fait entre le pass et la somme précédente de rendu.&lt;br /&gt;
&lt;br /&gt;
== Démarrage de FlightGear avec Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|dialogue Rembrandt]]&lt;br /&gt;
Le rendu Rembrandt est maintenant intégré dans le répertoire principal, mais doit être activé pour démarrer. Il y a deux façons de l'activer (une seule est nécessaire):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (lorsqu'on utilise [[FGRun]], on peut ajouter ceci derrière le &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; sur la première page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (avec FGRun on peut ajouter ceci via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; sur la dernière page).&lt;br /&gt;
&lt;br /&gt;
Le &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialogue vous permet de  basculer et d'ajuster les différentes options offertes par Rembrandt.&lt;br /&gt;
&lt;br /&gt;
Rembrandt est très gourmand en ressources GPU et son démarrage peut échouer avec les options par défaut. Le symptome le plus fréquent est un message OSG dans la console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
On peut voir aussi :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
Des options additionnelles peuvent éviter ces problèmes :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Certaines vieilles cartes NVidia comme 7600GT, n'ont pas assez de résolution pour la profondeur, et on voit des &amp;quot;rideaux de brouillard&amp;quot; à quelques mètres devant. Une astuce consiste à encoder la profondeur dans une autre texture et donner la valeur correcte ensuite. Cette option permet cela.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Désactive les ombres tout à fait.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Évite le message &amp;quot;error C6013&amp;quot; sur les vieilles cartes en manque de résolution dans le cockpitt. Mettez &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; pour changer la taille de la carte d'ombre. Plus de taille, et moins de résolution (la valeur par défaut est 5 mètres)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Définnissez la taille de la carte d'ombres. Les valeurs utilles sont 1024, 2048, 4096 ou 8192. Peu de cartes supportent 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Définissez le nombre de cascades de la carte ombre. Moins de cascades signifie moins de temps passé à générer la carte shadow, mais aussi signifie une qualité moindre de l'ombre. Mettez entre 1 et 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Définissez la taille de cascade de la carte shadow pour chaque cascade. Les valeurs par défaut sont 5m, 50m, 500m et 5000m pour 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Par défaut, Rembrandt utilise normalement des tampons de 8 bits  (ainsi, la propriété est vraiment définie par défaut). Ceci peut créer des artefacts pour les éclairages specular. Si c'est inacceptable et si le GPU le supporte, mettez false pour avoir une meilleure précision pour les normales et les effets s'appuyant sur une direction normale.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lignes directrices pour les écritures shader ==&lt;br /&gt;
=== Uniformes prédéfinis ===&lt;br /&gt;
Ces uniformes glsl n'ont pas besoin d'être déclarés dans le fichier effet&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Type&lt;br /&gt;
!Objectif&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;
|En pass plein écran seulement, view matrix utilisé our transformer la position écran en direction vue&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;
|En pass plein écran seulement, view matrix inverse employé pour transformer la position écran en direction vue&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;
|En pass plein écran seulement, projection matri inverse employé pour transformer la position écran en direction vue&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 de la caméra en coordonnées cartésiennes&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 de la caméra dans l'espace, exprimé en coordonnées géodésiques (longitude et latitude en radians, élévation en mètres)&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;
|&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;
|&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;
|&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;
|&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;
|Dire si la profondeur est rangée dans une texture profondeur ou une texture couleur&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;
|Utilisé pour convertir la valeur du tampon profondeur en une profondeur qui peut être utilisée pour calculer la position dans l'espace du 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 du tampon, utilisé pour convertir  gl_FragCoord dans la taille [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;
|Definie par OSG, employé seulement lors du travail sur la géométrie réelle&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;
|Definie par OSG, employé seulement lors du travail sur la géométrie réelle&lt;br /&gt;
|}&lt;br /&gt;
.Ils doivent encore être déclarés dans le fragment du vertex shader&lt;br /&gt;
&lt;br /&gt;
=== Fonctions utilitaires ===&lt;br /&gt;
&lt;br /&gt;
Pour faciliter la maintenance des shaders plusieurs fonctions utilitaires sont disponibles pour le fragment shader. Ces fonctions sont placées ensemble dans deux fichiers : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Utilisé pour encoder youtes les valeurs de  G-Buffer dans material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Employé pour compresser normals à l'intérieur de G-Buffer dans material shaders. Normalement appelé de &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit normals à partir de G-Buffer. Employé dans shaders plein écran et shaders lumière&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode les valeurs float dans la taille [0..1] dans les  24 bits d'une couleur. cette fonction est employée par &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; si le &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; est vrai, pour les vieilles cartes qui ne fournissent pas d'information profondeur avec assez de résolution dans les shaders fullscreen ou lumière.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Décode les valeurs float dans la taille [0..1] dans les  24 bits d'une couleur. cette fonction est employée par &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; si le &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; est vrai, pour les vieilles cartes qui ne fournissent pas d'information profondeur avec assez de résolution dans les shaders fullscreen ou lumière.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit la position eye space à partir de la direction view position a partir de la view direction et la profondeur lue du tampon profondeur &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
::Reconstruit la position eye space à partir de la direction view et la profondeur encodée dans une couleur lue du tampon profondeur&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruit la position eye space à partir de la direction vue et du tampon profondeur (profondeur réelle ou couleur selon la valeur de &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) à un fragment donné sur l'écran, donné par &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
Pour les shaders material, il faut fournir à la fois  &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; dans le fichier effet, comme suit :&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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
Pour les shaders fullscreen passes, on doit fournir seulement &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt;, comme ceci  :&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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
Dans la principale fonction du shader, les fonctions référencées doivent être écrites en premier. Avec no #include files, le prototype de la fonction entière nécessite d'être typé :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Phase Geometry  ===&lt;br /&gt;
La phase Geometry est là pour remplir le G-tampon.  '''L'ombrage n'intervient pas à cette phase, et le calcul lumière ou brouillard ne doit pas faire partie du shader '''. L'opération requise dans le fragment Shader est de remplir avec une valeur sensible chaque tampon individuel :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|pràfondeur (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment profondeur&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ceci est la couche par défaut attendue par le shader . material Id peut être utilisé pour détecter une couche différente&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pass lumière additionnelle ===&lt;br /&gt;
Il y aura là un seul shader pour chaque type de lumière utilisé. L'objectif est de créer des lumières comme animations dans le fichier model XML.   Le shader lumière retrouvera la scène geometry en combinant la position espace écran en vue de rayon espace par l'inversion de la matrix projection (une fonction plus secourable sera fournie), et le fragment profondeur à cette  position écran lit à partir du tampon profondeur. Avec l'aide du fragment normal, la couleur diffuse et specular et les propriétés de la lumière que le shader introduit, il sera possible d'ajouter au tampon lumière l'apport du rendu lumière.&lt;br /&gt;
&lt;br /&gt;
===Pass brouillard===&lt;br /&gt;
En utilisant le fragment profondeur, il sera possible de calculer une distribution brouillard. Pour le moment, il n'y a que l'équation simple brouillard.&lt;br /&gt;
&lt;br /&gt;
===Pass fleur===&lt;br /&gt;
C'est un effet double pass qui rend flou le tampon lumière dans une petite texture. Cette texture est ensuite ajoutée au tampon lumière lors de la phase affichage.&lt;br /&gt;
&lt;br /&gt;
=== Effets requis ===&lt;br /&gt;
Plusieurs pass sont mis en œuvre pour l'utilisation du système effet. Dans ce but , des effets sont référencés dans le code core utilisant des noms réservés. Ces effets sont:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Type&lt;br /&gt;
!But&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad plein écran&lt;br /&gt;
|Calcule l'occlusion ambiante à partir du tampon normal et du tampon profondeur&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad plein écran &lt;br /&gt;
|Copie le tampon couleur diffuse  multiplié par la lumière ambiante au tampon éclairage. L'occlusion ambiante peut aussi affecter la lumière ambiante .&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur la géométrie réeelle du volume de la lumière&lt;br /&gt;
|Calcule la contribution lumière d'un point lumineux défini dans une animation &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt;ayant un &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; de '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad de plein écran&lt;br /&gt;
|Calcule le brouillard à partir du C-buffer et les paramètres de l'éclairage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Agit sur un quad de plein écran&lt;br /&gt;
|Rends l'image finale composite à partir du G-buffer et du buffer éclairage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lignes-guide pour modeleurs ==&lt;br /&gt;
&lt;br /&gt;
=== Portage d'avion ===&lt;br /&gt;
* Rembrandt calcule les ombres =&amp;gt; plus de fausses ombres dans le modèle&lt;br /&gt;
* Rembrandt calcule l'occlusion ambiante =&amp;gt; pas d'occlusion ambiante incluse dans les textures&lt;br /&gt;
* Rembrandt est en lumière =&amp;gt; les cartes lumière static ne sont pas nécéssaires, la couleur émissive pour voir les modèles n'est pas nécessaire, et pourrait interférer&lt;br /&gt;
* Rembrandt est brillant =&amp;gt; les couleurs émissives incorrectement utilisées peuvent rendre flou, et rendre du texte illisible. L'intensité de la lumière devra être réglée&lt;br /&gt;
* Rembrandt a des besoins précis avec les shaders =&amp;gt; les shaders nécessitent un ajustement pour se conformer au nouveau cadre, sinon la vue sera faussée&lt;br /&gt;
* Rembrandt ne peut faire des surfaces transparentes =&amp;gt; les surfaces transparentes doivent être dûment enregistrées pour les atteindre avec le chemin classique&lt;br /&gt;
&lt;br /&gt;
=== Enregistrement de toutes les surfaces translucides ===&lt;br /&gt;
&lt;br /&gt;
Chaque modèle est par défaut rendu en utilisant l'effet  &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt;. Cet effet initialise le G-buffer, en ignorant les surfaces transparentes, en mettant  alpha test et  rendu de toute la geometrie dans la poubelle. Il n'est pas possible de rediriger le rendu vers les bacs transparents lorsque la texture associée a un canal alpha car la plupart des modeles emploient un atlas simple texture et même les parties opaques sont rendues avec texture avec alpha canal.&lt;br /&gt;
&lt;br /&gt;
Si un modèle nécessite des surfaces translucides ou transparentes , ces objets surface doivent être assignés à un effet différent  qui place explicitement le bac rendu à &amp;quot;DepthSortedBin&amp;quot;, ou met la suggestion rendu à &amp;quot;transparent&amp;quot;. Ceci dit au moteur de rendu de rendre cet objet opérant avant le rendu, ainsi, la clarté et le brouillard doivent être activés, et si un programme shader est utilisé, et s'ils ont été calculés en manière classique. Le   &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; peut être utilisé pour enregistrer simlement les surfaces transparentes/translucides. Vous attribuez cet effet à un objet (ou à de multiples objets) comme:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Attention: &amp;lt;Effect&amp;gt; agit seulement sur les objets réels, pas sur des groupes d'objets ou des animations.'''&lt;br /&gt;
&lt;br /&gt;
Si la surface opaque a besoin d'un effet spécial, par exemple appliquer un &amp;quot;bump mapping&amp;quot; (effet de relief sur des textures) cet effet devra utiliser le bac  &amp;quot;RenderBin&amp;quot;, ou le rendu suggéré met à &amp;quot;opaque&amp;quot;, et le G-buffer a besoin d'être initialisé correctement dans la phase Geometry.&lt;br /&gt;
&lt;br /&gt;
=== Soyez sûr que toute la Geometry distribuera l'ombre ===&lt;br /&gt;
&lt;br /&gt;
Pour limiter la quantité de rendu geometry dans la carte shadow, et aussi pour réduire les artefacts (acnée shadow), seulement les faces ne regardant pas le soleil distribuent les ombres. Le test est effectué en utilisant l'orientation normale. Cela veut dire que les polygones à double côté, ou mesh non fermés, seront transparents à la lumière sous certains angles de soleil. Pour éviter ça, les modeleurs peuvent:&lt;br /&gt;
*s'assurer que l'objet est toujours dans l'ombre d'autres objets,&lt;br /&gt;
*fermer leur mesh, ou&lt;br /&gt;
*doubler les polygones avec l'endroit normal à l'opposé&lt;br /&gt;
&lt;br /&gt;
=== Ajouts de lumière à un modèle===&lt;br /&gt;
&lt;br /&gt;
Deux points sont à considérer: l'apparence de la sourceet la zone illuminée. Pour l'apparence de la source lumière, (ce que vous voyez quand vous regardez le bulbe) vous avez besoin d'un modèle avec un emissive material qui produira  l'effet brillant et ceci est visible de nuit.&lt;br /&gt;
&lt;br /&gt;
Pour l'effet de la source dans son environnement (l'aire lumineuse), nous devons avoir dans le modèle 3D (le fichier .ac) un volume qui inclut l'effet (Volume Lumière). Cela peut être un grand cône pour les aires lumineuses ou une spère pour une lumière ponctuelle. Il est important que le volume lumière soit fermé, convexe et les normals orientés vers l'extérieur.&lt;br /&gt;
&lt;br /&gt;
Le volume lumière doit être partie de la geometry du modèle et être référencé dans le fichier animation. Pas besoin d'ajouter une couleur ou un effet à ce volume. Le calcul lumière est seulement fait sur les fragments couverts par le volume lumière, mais n'a aucune influence sur la couleur ou l'atténuation de la lumière .&lt;br /&gt;
&lt;br /&gt;
Toutes les animations disponibles sont possibles sur le volume lumière sauf '''material''' et '''texture'''. Il n'est pas possible de changer couleur et lumières, pour le moment; sauf en se branchant sur une autre animation. L'axe et la position sont dans l'espace objet et sont transformés par les animations qui suivent.&lt;br /&gt;
&lt;br /&gt;
==== Taches lumineuses ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Objectif&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Installe l'animation &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|C'est une lumière &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom donné à cette animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom du volume lumière dans le modèle 3D (typiquement un cône avec un sommet à &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, le long de l'axe &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; si &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; est inférieur à 90 degrés, ou une sphère centrée à  &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; si &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; est supérieur à 90 degrés )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Cache le volume lumière dans  fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace objet, position de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace objet, direction vers le centre de la tache&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur ambiante de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur diffuse de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur specular de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Groupe de paramètres pour contrôler un facteur appliqué en même temps à  ambient, diffuse et specular &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Trois element vector. &amp;lt;c&amp;gt; element est le facteur constant, &amp;lt;l&amp;gt; element est le facteur linéaire et &amp;lt;q&amp;gt; element est le facteur quadratique.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation de couleur à distance d est [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplié par &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir étant vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vecteur à partir de la position lumière vers le point, dans l'espace caméra.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance minimum d'influence, à partir de la position, en mètres&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance maximum d'influence, à partir de la position, en mètres&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Points lumineux ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Nom&lt;br /&gt;
!Objectif&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Installe l'animation &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|C'est une lumière &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom donné à cette animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Nom du volume lumière  dans le modèle 3D ( typiquement une sphère centrée sur &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, avec un rayon de &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Volume lumière cachée dans fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Dans espace object , position de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur ambiante de la lumière &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur diffuse de la lumière&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Couleur specular de la lumièret&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Groupe de paramètres pour contrôler un facteur appliqué à   ambient, diffuse et specular en même temps&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Trois element vector. &amp;lt;c&amp;gt; element est le facteur constant &amp;lt;l&amp;gt; element est le facteur linéaire et &amp;lt;q&amp;gt; element est le facteur quadratiquer.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation de couleur à distance d est [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance minimum d'influence, à partir de la position, en mètres&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Distance maximum d'influence, à partir de la position, en mètres&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Considérations de performance et de compatibilité ====&lt;br /&gt;
Chaque lumière sur écran équivaut, pour le GPU à redessiner le volume lumière avec un shader, sans recueillir de buffer. Ainsi, chaque lumière vient avec un coût, ce qui est minime individuellement parlant, mais non négligeable quand jl y en a beaucoup. Ce coût augmente  avec la taille du volume lumière&lt;br /&gt;
&lt;br /&gt;
De plus, il est raisonnable de permettre à un modèle de fonctionner avec le moteur de rendu classique qui ne sait rien des lumières et rendrait les volumes lumière comme une autre géométrie. Ainsi, c'est une bonne pratique de compléter chaque animation lumière par une animation sélective vérifiant :&lt;br /&gt;
*si Rembrandt est activé&lt;br /&gt;
*si le mode de qualité choisi correspond avec les possibilités de la lumière&lt;br /&gt;
*si la lumi§re doit être on ou off selon les autres paramètres de la simulation (position du soleil; position de du commutateur, présence de puissance...)&lt;br /&gt;
&lt;br /&gt;
Une bonne propriété est de crèer  un reflet des préférences de l'utilisateur sur  qualité vs performance concernant les lumières, et un curseur dédié est ajouté dans le dialogue shader.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
La propriété à utiliser est:&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
Le curseur qualité va de 0 (pas de lumière) à 4 (pleine lumière). Un simple réverbère d'aéroport apparaît à 1. Quelques lampes de pont à 2. Toutes les lampes de pont simples à 3, et les plus sophistiquées à 4&lt;br /&gt;
&lt;br /&gt;
Exemple:&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutoriels ===&lt;br /&gt;
[[User:F-JJTH|F-JJTH]] a compilé son expérience et celle de l'équipe de la PAF d'amélioration d'avions dans {{fr}} [http://equipe-flightgear.forumactif.com/t1034-howto-adapter-un-appareil-pour-rembrandt this tutorial].&lt;br /&gt;
&lt;br /&gt;
== TODO Liste ==&lt;br /&gt;
&lt;br /&gt;
=== Tâches à compléter ===&lt;br /&gt;
*Fixer le rendu shadow quand on emploie plusieurs liens en  OSG&lt;br /&gt;
*Implementer Cascaded Shadow Map (a besoin d'être optimisée - frustum calculation et nuit)&lt;br /&gt;
*Voir ce qui arrive avec brillance dans le brouillard: une sorte de terrain inconnu crée des patches blancs  dans le buffer emission-problème de génération de scène &lt;br /&gt;
*Test multi-écran (mostly done)&lt;br /&gt;
*Restorer splashscreen&lt;br /&gt;
*Dessiner des objets transparents avec rendu en premier (peut nécessiter la capture du bac transparence à partir de la phase géométrie et le placer dans la phase affichage)  (OK - nécessite une contribution modèle)&lt;br /&gt;
*Trouver une solution pour couleur ambient et emissive de material (peut nécessiter un buffer additionnel)&lt;br /&gt;
*Fournir un shader pour objets transparents qui puisse rendre le buffer emissive infaisable (en utilisant MRT) La phase lumière ne peut utiliser MRT &lt;br /&gt;
*Utiliser un buffer stencil pour limiter la taille lumière (non fait dans shader lumière)&lt;br /&gt;
**nécessaire pour la lumière de cockpit pour réaliser des faux shadowws et éviter d'éclairer le runway de la cabine&lt;br /&gt;
*Utiliser un système effet à la place des shaders lourdement codés&lt;br /&gt;
*Intensités globales de brillance, ou occlusion ambiante via curseur dans le dialogue rendu &lt;br /&gt;
&lt;br /&gt;
=== Tâches à court terme ===&lt;br /&gt;
*Convertir les shaders existants en rendu différé&lt;br /&gt;
*Éviter de redessiner les objets opaques dans la phase lumière. Améliorer le masque node OSG .&lt;br /&gt;
*S'occuper des particules et précipitations&lt;br /&gt;
*Fixer le brouillard sur les nuages &lt;br /&gt;
*Fixer les matrices shadow dans multi-screen&lt;br /&gt;
*IMettre en œuvre un lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Idées à long terme (non classées) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallerie ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendice ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[en:Project Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_September_2012&amp;diff=54342</id>
		<title>FlightGear Newsletter September 2012</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_September_2012&amp;diff=54342"/>
		<updated>2012-09-23T15:10:11Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Project Rembrandt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{newsletter}}&lt;br /&gt;
{{TOC_right|limit=2}}&lt;br /&gt;
&lt;br /&gt;
''We would like to emphasize that the monthly newsletter can not live without the contributions of FlightGear users and developers. Everyone with a wiki account (free to register) can edit the newsletter and every contribution is welcome. So if you know about any FlightGear related news or projects such as for example updated scenery or aircraft, please do feel invited to add such news to the newsletter.''&lt;br /&gt;
&lt;br /&gt;
== Development news ==&lt;br /&gt;
Note to all developers: Please also copy your newsletter additions to the changelog of the upcoming release: [[Changelog_3.0.0]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- These are currently just a bunch of placeholders for the latest projects (as of 08/2012)  --&amp;gt;&lt;br /&gt;
=== Random Buildings ===&lt;br /&gt;
Shortly after the 2.8 release, a number of users reported severe memory growth issues related to a new feature: [[Random Buildings]].&lt;br /&gt;
&lt;br /&gt;
This was a side-effect of the way in which the buildings were created during tile loading. Stuart has now completely changed the way in which random buildings are generated and displayed to reduce the memory occupancy by using a shader-based scheme similar to random trees.  You should now see significantly lower memory occupancy (500 - 2GB less depending on area and density) when running with random buildings enabled.&lt;br /&gt;
&lt;br /&gt;
=== NavCache ===&lt;br /&gt;
James has pushed a large change to next, which adds a binary cache of most of  the navigation data. The cache is stored in FG_HOME/navdata.cache, and rebuilt if the timestamps on any of the data files change (apt.dat, nav.data, fix.dat and so on). When the cache needs to be rebuilt, startup will take a bit longer  than before, but when the cache is valid, startup is /much/ faster, especially for debug builds:&lt;br /&gt;
&lt;br /&gt;
{{cquote|Memory consumption is also lower, since we don't keep airports / fixes /  taxiways / runways in memory until they're needed.&lt;br /&gt;
&lt;br /&gt;
This is a fairly large change, so please look out for any bugs related to navaids / startup position / GPS / route-manager searches and lookups either getting different results or failing. I've tested here locally and things seem &lt;br /&gt;
sane, and have had positive feedback from various testers on IRC and email, but I still expect to find some edge cases which need further work.&lt;br /&gt;
&lt;br /&gt;
There's future work to move even more data into the cache - eg parking positions - which will further help performance for FMS / map systems since we won't need to parse lots of XML data repeatedly. I'm going to let this change settle down before adding more cached data, however.&amp;lt;ref&amp;gt;{{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg38330.html |title=[Flightgear-devel] Nav-cache|author=James Turner |date=Wed, 19 Sep 2012}}&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Project Rembrandt ===&lt;br /&gt;
The night vision effect, as well as the cinema effects, are now available for 2.8 users. See [http://www.flightgear.org/forums/viewtopic.php?f=47&amp;amp;t=17602| here] for the download links, details and feedback.&lt;br /&gt;
&lt;br /&gt;
=== Canvas System ===&lt;br /&gt;
&amp;lt;!--additions should also be added to:http://wiki.flightgear.org/Changelog_3.0.0#Some_of_the_major_changes_include: --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Work has now started to develop a dedicated Nasal module specifically for [[Canvas Maps|mapping/charting purposes]]. A first proof of concept is available in $FG_ROOT/Nasal/canvas/map.nas, but we expect to commit more changes (and a real API) soon. Initially, we'll be collecting all related features in a single &amp;quot;map.nas&amp;quot; module, and refactor/improve things later on. &lt;br /&gt;
&lt;br /&gt;
In particular, the idea is to have a single Nasal module as the backend for all mapping/charting tasks in FlightGear, so that existing hard-coded features can be unified and re-implemented via a single consistent Nasal module that serves as a shared backend. &lt;br /&gt;
&lt;br /&gt;
Ultimately, this will make it possible to re-implement existing features such as [[ATC-FS]], the [[Map]] dialog and even Brisa's [[Airport Diagram Generator]] or the [[Kelpie Flight Planner]] directly in FlightGear, using Nasal scripting and the [[Canvas]] system, without having to write any C++ code - so that people won't need to use external tools or programming languages to create such applications.&lt;br /&gt;
&lt;br /&gt;
In the long run, we want to come up with a very flexible design so that the &amp;quot;map.nas&amp;quot; module cannot only be used for creating maps used in GUI dialogs, but also for creating moving map displays like the existing hard-coded [[Navigation display]] or the [[TCAS]] and WXRADAR displays (&amp;quot;glass&amp;quot; displays), i.e. as cockpit instruments/avionics.&lt;br /&gt;
This approach would also make it possible to directly show instruments in GUI dialogs or vice versa.&lt;br /&gt;
&lt;br /&gt;
As a first proof of concept, Stuart has added a Canvas-based map to the airport selection dialog, and Hooray has demonstrated that the same technique could be used to add a map widget to the route manager dialog - so that airport selection and route planning could become more intuitive using the [[Canvas]] system. For additional info, please see: [http://flightgear.org/forums/viewtopic.php?f=71&amp;amp;t=17625].&lt;br /&gt;
&lt;br /&gt;
In addition, ShivaVG (the vector drawing engine behind canvas) has been extended to support some kind of a non-zero fill rule. It's not really non-zero because instead of incrementing and decrementing depending on the orientation of the drawn overlapping regions it simply checks if at least a single region covers a pixel. For our use cases it&lt;br /&gt;
should be enough tough.&lt;br /&gt;
&lt;br /&gt;
Some further performance improvements were added: Now the texture is only redrawn if something has changed. So if you don't change the map there shouldn't be any noticeable performance impact anymore.&lt;br /&gt;
&lt;br /&gt;
Also the bounding boxes are now only written to the property tree if they are recalculated. This should take some fair amount of changing properties away.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Seems like now tessellating takes much longer than before due to the amount of data in one single path.&lt;br /&gt;
&lt;br /&gt;
The current problem with zooming is that every position of every path gets recalculated with the updated projection, even though this isn't really needed as the projection doesn't noticeably while just zooming&lt;br /&gt;
and scrolling around at a single airport.&lt;br /&gt;
&lt;br /&gt;
=== Flightplan access via Scripting ===&lt;br /&gt;
In advance of converting the Map and NavDisplay to use the [[Canvas]], James has improved the &amp;quot;flightplan()&amp;quot; extension function of the [[Nasal]] scripting interpreter to expose the full route-path vector for each flight plan leg, as a vector on the leg .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
var fp = flightplan();&lt;br /&gt;
for (var i=0; i&amp;lt;fp.getPlanSize(); i += 1)&lt;br /&gt;
{&lt;br /&gt;
  var leg = fp.getWP(i);&lt;br /&gt;
  debug.dump(leg.path());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With these changes in place, it is already possible to directly show a SVG image for each waypoint and connect them using OpenVG paths, even without separate &amp;quot;icon&amp;quot; support.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
=== FlightGear On Android ===&lt;br /&gt;
&lt;br /&gt;
=== Mailing list digest ===&lt;br /&gt;
&lt;br /&gt;
(by far the easiest option to populate the newsletter with contents is copying/pasting stuff from the forum and the mailing list or the git logs)&lt;br /&gt;
&lt;br /&gt;
=== Usability Improvements ===&lt;br /&gt;
&lt;br /&gt;
[[File:Nasal-console-3.0.png|thumb|The Nasal console in FG 3.0 with copy/paste buttons ]]&lt;br /&gt;
&lt;br /&gt;
There have been a number of improvements made to the GUI this month, all aiming to improve usability.&lt;br /&gt;
&lt;br /&gt;
==== Nasal Console ====&lt;br /&gt;
The built-in [[Nasal Console]] has been updated to also add native copy/paste support, a feature that got implemented as part of the ongoing [[Canvas]] effort (see  [[Howto:Clipboard access using Nasal]] for details ). This feature makes it now possible to easily copy/paste snippets of code FlightGear, without having to use the &amp;quot;dump&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
==== About Dialog ====&lt;br /&gt;
&lt;br /&gt;
[[File:About-dlg-3.0.png|thumb|The about dialog in FG 3.0 with extended graphics information ]]&lt;br /&gt;
&lt;br /&gt;
In addition, the &amp;quot;about&amp;quot; dialog has also been slightly updated so that it now shows a handful of OpenGL-related parameters, this info should make it easier for people to provide useful issue reports, especially related to their system's graphics support. For this very purpose, the dialog box has now also support for copying this info to the clipboard or simply take a screen shot that users can post on the forums.&lt;br /&gt;
&lt;br /&gt;
==== Select Airport ====&lt;br /&gt;
&lt;br /&gt;
[[File:Airport-selection-dialog.png|thumb|The new Airport Selection dialog with Canvas display of the airport]]&lt;br /&gt;
&lt;br /&gt;
The Select Airport and Position on Ground dialogs have been combined.  The combined dialog displays the lon/lat/alt of the selected airport, and also uses [[Canvas]] to display an airport diagram.&lt;br /&gt;
&lt;br /&gt;
==== Aircraft Checklists ====&lt;br /&gt;
&lt;br /&gt;
Aircraft typically have a large number of checklists, covering almost every phase of flight.  Previously, aircraft authors have added checklists to the help text for the aircraft.  This is a bit unwieldy.  To improve matters, there is now an Aircraft Checklists dialog under the Help menu specifically designed to organize and display checklists.  Aircraft authors can create new checklists easily without having to worry about how they will be displayed.  See [[Aircraft Checklists]] for details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Integrated Documentation Browser ====&lt;br /&gt;
&lt;br /&gt;
[[File:Nasal-doc-browser-3.0.png|thumb|New integrated documentation browser]]&lt;br /&gt;
&lt;br /&gt;
Often, especially new FlightGear users are not aware of all the documentation that comes with FlightGear. While the manual is fairly easy to find and pretty accessible (being a PDF file), most of the other documentation in $FG_ROOT/Docs is hardly easy to find and often pretty inaccessible to new users, even though these files are standard text files, because of the non-standard file extensions used by most README* files there. &lt;br /&gt;
That's why we have now added a new built-in dialog to FlightGear which shows most plain text files in $FG_ROOT/Docs directly inside FlightGear, without having to start any other applications.&lt;br /&gt;
&lt;br /&gt;
=== Forum digest ===&lt;br /&gt;
&lt;br /&gt;
=== Git digest ===&lt;br /&gt;
&lt;br /&gt;
=== Getting involved as a programmer ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Howto:Start core development]]&lt;br /&gt;
&lt;br /&gt;
== Release ChangeLog ==&lt;br /&gt;
This section lists changes committed this month that will be available in the next release, these will be copied to the release changelog shortly before a release (for each month), so that we hopefully get a comprehensive list of new features.&lt;br /&gt;
&lt;br /&gt;
== Interview with a contributor (Thorsten Renk) ==&lt;br /&gt;
''In each edition we have an interview with a contributor. Suggestions for possible questions are available on [[interview questions]], you are invited to come up with new questions and interview ideas obviously! Anyone is free to write an interview (with him-/herself or others) for next month's newsletter! If you'd like to help interview a contributor or get interviewed, please do consider adding yourself to the [[list of interview volunteers]]! To keep this going and less awkward, we are currently trying to come up with the convention that former interviewees become next month's interviewers.''&lt;br /&gt;
&lt;br /&gt;
* How long have you been involved in FlightGear?&lt;br /&gt;
&lt;br /&gt;
Since late 2009.&lt;br /&gt;
&lt;br /&gt;
* What are your major interests in FlightGear?&lt;br /&gt;
&lt;br /&gt;
In the broadest sense, modelling of the environment. I've started out modelling clouds and weather, then as I discovered shaders I've also included dust, haze and light scattering effects, and of late I am into improved ways of texturing the terrain.&lt;br /&gt;
&lt;br /&gt;
All these areas are related, so it's actually pretty powerful if the same person knows how to affect all of them - for instance, on a rainy day, we not only see an overcast cloud layer, but also the light beneath the clouds is dimmed, the sunrise has a different color hue, the ground is wet and hence darker than usual and there may be water on the ground. Being able to do all these things with the same environment model is pretty cool.&lt;br /&gt;
&lt;br /&gt;
* What project are you working on right now?&lt;br /&gt;
&lt;br /&gt;
Procedural texturing, i.e. computing the texture mix to be displayed on the terrain inside the shader code - this allows for effects which would be impossible to achieve with the standard way of assigning textures due to the huge memory footprint.&lt;br /&gt;
&lt;br /&gt;
* What do you plan on doing in the future?&lt;br /&gt;
&lt;br /&gt;
Who knows? I have plenty of things I would like to do and in principle know how to do - the problem is just making them run fast enough. It's pretty amazing how fast a graphics card can crunch numbers, but there are limits eventually. And basically every day, looking out of the window and observing the richness in detail on a real sky, I see how inadequate even our most advanced shading models really are. It's amazing how nature solves all the rendering equations in real time.&lt;br /&gt;
&lt;br /&gt;
* Are you happy with the way the FlightGear project is going?&lt;br /&gt;
&lt;br /&gt;
Mostly. I know many people think FlightGear should have a project structure which works more like a commercial project, i.e. with clearly defined project goals and well-defined tasks. Rather, it is a somewhat anarchic collection of different individual projects merged together, often with multiple ways to solve the same problem (we support as many as four different ways to generate clouds for instance) which makes it not always easy for new contributers in need of a feature. But, coming from a research environment, I actually feel quite at home with such a development model - science works the same way, and for instance, while having several independent ways of doing the same thing can be seen as a waste of resources, it can also be seen as a feature - we explore many different ways of doing things which helps us find the best solution.&lt;br /&gt;
&lt;br /&gt;
What I don't like is that there is often a lot of friction - for instance 3-D modellers feel underappreciated since most of the project decisions are made by the coders, there's an ongoing controversy between scripting space (Nasal) and C++ coding, and there are contributors of world scenery vs. custom scenery creators. While some level of discussion seems useful to me, related discussions often reach a point which I find no longer productive.&lt;br /&gt;
&lt;br /&gt;
* What do you enjoy most about developing for FlightGear?&lt;br /&gt;
&lt;br /&gt;
The same thing Tolkien enjoyed about writing 'The Lord of the Rings' - the possibility to do subcreation. The visible FlightGear scenery is a world to explore, and this world is directly and visibly influenced by code I write. I can place myself high up in the air, look down and wave my mouse - and a whole layer of clouds appears. I get to decide what color the sunrise has. That's pretty fascinating as far as that goes.&lt;br /&gt;
&lt;br /&gt;
And actually, I've always enjoyed flying through clouds in flight simulators - in the early ones, they were just so bad, but now I can make them just the way I've always wanted them to be. Flying between two scattered cloud layers is still one of my favourite activities.&lt;br /&gt;
&lt;br /&gt;
* Are there any &amp;quot;hidden features&amp;quot; you have worked on in FlightGear that new users may miss?&lt;br /&gt;
&lt;br /&gt;
Plenty. Several I decided not to release since they are too tricky to control, so flags switch them off. For instance, there's a working model for wave lift in the Advanced Weather code, but there is no code to automatically place it (that's much more tricky to develop), so the wave needs to be placed by hand with a suitable line of Nasal. There are experimental cloud layer definitions which are just too expensive to render on a normal system. Many things I just try, and when I find no good way of implementing them, they stay in the code in a de-activated mode.&lt;br /&gt;
&lt;br /&gt;
* What advice can you give to new developers who want to get started on their first aircraft/new feature/Nasal script?&lt;br /&gt;
&lt;br /&gt;
Be patient. The world doesn't revolve around you, but good work is recognized eventually.&lt;br /&gt;
&lt;br /&gt;
Many people seem to expect that the FlightGear development community is just waiting for their contribution and jump to fill every requirement. But every developer has his own agenda, and the way things actually work is by convincing people that spending their time to support another project is a good idea. For instance, demonstrating that a project is feasible is a good idea before expecting help.&lt;br /&gt;
&lt;br /&gt;
I know it looks pretty unwelcoming if someone wants to contribute and needs to go a long way before getting help. On the other hand, I know the other perspective of investing a lot of work into someone's project, just to see the other person disappear and all that work being lost. So I understand much better that established developers want to see that someone is serious about what he proposes to do before they jump in. &lt;br /&gt;
&lt;br /&gt;
More questions are being collected here: [[Interview questions]].&lt;br /&gt;
&lt;br /&gt;
Stay tuned for next month's interview, featuring FlightGear contributor XXXXXXXX&lt;br /&gt;
&lt;br /&gt;
== Snapshot releases ==&lt;br /&gt;
Every now and then, easy-to-install development snapshots are created (usually, twice montlhy). These snapshos depict a recent state of the development version of FlightGear. By using them users can test out features that will be included in the upcoming release. Testers are encouraged to file bugs at [http://code.google.com/p/flightgear-bugs/ the issue tracker].&lt;br /&gt;
&lt;br /&gt;
The snapshot can be download via the links at the bottom of this page: http://www.flightgear.org/download/. Updates and feedback can be found [http://flightgear.org/forums/viewtopic.php?f=28&amp;amp;t=10488&amp;amp;p=144233&amp;amp;hilit=snapshot#p144233 at the forum].&lt;br /&gt;
&lt;br /&gt;
== Translators required ==&lt;br /&gt;
{|&lt;br /&gt;
|[[File:en.gif]]&lt;br /&gt;
|The FlightGear Wiki still needs help for translating it into various languages. If you are interested in making the FlightGear Wiki multi-language then start at [[Help:Translate]].&lt;br /&gt;
|-&lt;br /&gt;
|[[File:de.gif]]&lt;br /&gt;
|Das FlightGear Wiki benötigt immer noch Hilfe bei der Übersetzung in verschiedene Sprachen. Wenn Du Interesse daran hast, das FlightGear Wiki Mehrsprachig zu machen, dann fang doch mit [[:de:Help:Übersetzen|Help:Übersetzen]] an.&lt;br /&gt;
|-&lt;br /&gt;
|[[File:nl.gif]]&lt;br /&gt;
|De FlightGear Wiki kan nog steed hulp gebruiken bij het vertalen van artikelen. Als je interesse hebt om de wiki meertalig te maken, raden we je aan om een kijkje te nemen bij [[:nl:Help:Vertalen|Help:Vertalen]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Nasal for newbies ==&lt;br /&gt;
&lt;br /&gt;
== New software tools and projects ==&lt;br /&gt;
&lt;br /&gt;
== FlightGear addons and mods ==&lt;br /&gt;
&lt;br /&gt;
== In the hangar ==&lt;br /&gt;
&lt;br /&gt;
All the way back in May 2011, we addopted a new status-rating system for aircraft. So far, only a few have actually been rated, as can be seen in the list 'hockenberry' set up at [https://docs.google.com/spreadsheet/ccc?key=0ApzphjA4w05ndF94Y2F0bzJTbHQ5QTJXZXJRcUVRbWc&amp;amp;hl=en_US Google Docs]. If you're an aircraft developer and your aircraft is/are not on the list, please consider rating their status. All you'll need to know/do is described at [[Formalizing Aircraft Status]]. If you'd just like to get started contributing to FlightGear, this would also seem like an excellent way to get started.&lt;br /&gt;
&lt;br /&gt;
=== New aircraft ===&lt;br /&gt;
&lt;br /&gt;
=== Updated aircraft ===&lt;br /&gt;
&lt;br /&gt;
=== Liveries ===&lt;br /&gt;
&lt;br /&gt;
== Scenery corner ==&lt;br /&gt;
=== OpenStreetMap license change completed ===&lt;br /&gt;
On September 12, [[OpenStreetMap]] (OSM) completed its long expected license change. From now on, OSM data is licensed under the [http://opendatacommons.org/licenses/odbl/ Open Database Licence].&lt;br /&gt;
&lt;br /&gt;
* [[OpenStreetMap import]]&lt;br /&gt;
* [[OpenStreetMap buildings]]&lt;br /&gt;
&lt;br /&gt;
=== TerraGear GUI received new functions ===&lt;br /&gt;
The [[TerraGear GUI]], an user interface to generate FlightGear scenery, received several improvements this month. Besides a couple of (small) bug fixes, two features deserve to be highlighted here:&lt;br /&gt;
* The list of materials to choose from now displays the respective textures. This makes it easier to pick the right material.&lt;br /&gt;
* Elevation data can now be downloaded for the entire world. The GUI does this automatically, all you need to do is specify a bounding box for the to-be-created scenery.&lt;br /&gt;
Feedback is welcome as always!&lt;br /&gt;
&lt;br /&gt;
=== Tools ===&lt;br /&gt;
It is now possible to update the geographical data of static models using our webtools, just like you are now used to to with the shared objects. You just have to select the object corresponding to the 3D model, and then click on &amp;quot;update&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Airports ===&lt;br /&gt;
&lt;br /&gt;
== Aircraft of the month ==&lt;br /&gt;
== Airport of the month ==&lt;br /&gt;
== Screenshot of the month ==&lt;br /&gt;
&lt;br /&gt;
== Suggested flights ==&lt;br /&gt;
== Aircraft reviews ==&lt;br /&gt;
&lt;br /&gt;
== Wiki updates ==&lt;br /&gt;
===New articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===New aircraft articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
  categoryRoot=Aircraft&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===Most popular newsletters===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=hot&lt;br /&gt;
  count=5&lt;br /&gt;
  categoryRoot=FlightGear Newsletter&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community news ==&lt;br /&gt;
=== FlightGear on YouTube ===&lt;br /&gt;
&lt;br /&gt;
=== New tutorials and screencasts ===&lt;br /&gt;
=== Forum news ===&lt;br /&gt;
=== Multiplayer ===&lt;br /&gt;
=== Virtual airlines ===&lt;br /&gt;
=== FlightGear events ===&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
== And finally ... ==&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
One of the regular thoughts expressed on the FlightGear forums is &amp;quot;I'd like to contribute but I don't know how to program, and I don't have the time&amp;quot;. Unfortunately, there is a common mis-conception that contributing requires programming and lots of free time. In fact, there are a huge range of ways to contribute to the project without needing to write code or spending days working on something. &lt;br /&gt;
&lt;br /&gt;
For ideas on starting to contribute to FlightGear, you may want to check out: [[Volunteer]].&lt;br /&gt;
&lt;br /&gt;
To learn more about how the project works, please see [http://flightgear.org/forums/viewtopic.php?f=42&amp;amp;t=15267#p149971 this short essay] written by Thorsten.&lt;br /&gt;
&lt;br /&gt;
=== Call for volunteers ===&lt;br /&gt;
* The [[Flightgear On Android]] team is looking for testers&lt;br /&gt;
* The [[Target4Today]] team is looking for volunteers to help improving FlightGear's combat support&lt;br /&gt;
* The [[OpenRadar]] project is looking for a new maintainer.&lt;br /&gt;
* The [[FGFSPM]] (FlightGear Package Manager) is looking for a new maintainer.&lt;br /&gt;
&lt;br /&gt;
=== Did you know ===&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear Newsletter]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=54094</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=54094"/>
		<updated>2012-09-15T10:20:28Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Appendix */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
The ssao effect provided in v2.8.0 may generate these messages, more often on Mac :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FRAGMENT glCompileShader &amp;quot;/Users/xxxx/Desktop/FlightGear.app/Contents/Resources/../Resources/data/Shaders/ssao.frag&amp;quot; FAILED&lt;br /&gt;
FRAGMENT Shader &amp;quot;/Users/xxxx/Desktop/FlightGear.app/Contents/Resources/../Resources/data/Shaders/ssao.frag&amp;quot; infolog:&lt;br /&gt;
ERROR: 0:20: 'array of 2-component vector of float' : constructor not supported for type&lt;br /&gt;
ERROR: 0:20: 'array of 2-component vector of float' : no matching overloaded function found&lt;br /&gt;
ERROR: 0:20: 'const 2-component vector of float' : cannot declare arrays of this type&lt;br /&gt;
ERROR: 0:20: 'v' : redefinition&lt;br /&gt;
ERROR: 0:55: 'reflect' : no matching overloaded function found&lt;br /&gt;
ERROR: 0:55: '=' :  cannot convert from 'float' to '2-component vector of float'&lt;br /&gt;
&lt;br /&gt;
glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
ERROR: One or more attached shaders not successfully compiled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In that case, disable ambient occlusion with the command :&lt;br /&gt;
&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/ambient-occlusion-buffers=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
Once your aircraft has been ported, please modify its wiki page and add this symbol to it:&lt;br /&gt;
[[File:Rembrandtready.png]].&lt;br /&gt;
&lt;br /&gt;
For a list of converted aircraft, please see [http://flightgear.org/forums/viewtopic.php?f=4&amp;amp;t=17536#p166346].&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Making sure that all geometry will cast shadow ===&lt;br /&gt;
&lt;br /&gt;
To limit the amount of geometry rendered in the shadow map, and also to reduce artifacts (shadow acne), only faces not facing the sun are casting shadows. The test is made using the normal orientation. That means that double-sided polygons, or mesh that are not closed, will be transparent to light at certain sun angles. To avoid that, modelers can either :&lt;br /&gt;
* ensure that the object is always in the shadow of another objects,&lt;br /&gt;
* close their mesh, or,&lt;br /&gt;
* double polygons with the normal set to the opposite.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorials ===&lt;br /&gt;
[[User:F-JJTH|F-JJTH]] compiled his experience and the one acquired by the PAF team converting aircraft in this [http://equipe-flightgear.forumactif.com/t1034-howto-adapter-un-appareil-pour-rembrandt tutorial (in French)]&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
* {{cite web |url=http://publications.dice.se/publications.asp?show_category=yes&amp;amp;which_category=Rendering |author=DICE |title=Publications on rendering |accessdate=15 August 2012 }}&lt;br /&gt;
* {{cite web |url=http://advances.realtimerendering.com/s2012/Epic/The%20Technology%20Behind%20the%20Elemental%20Demo%2016x9.pptx |author=Martin Mittring |title=The Technology behind the Unreal Engine 4 Elemental Demo |accessdate=15 September 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=54093</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=54093"/>
		<updated>2012-09-15T10:13:33Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Guidelines for modelers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
The ssao effect provided in v2.8.0 may generate these messages, more often on Mac :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FRAGMENT glCompileShader &amp;quot;/Users/xxxx/Desktop/FlightGear.app/Contents/Resources/../Resources/data/Shaders/ssao.frag&amp;quot; FAILED&lt;br /&gt;
FRAGMENT Shader &amp;quot;/Users/xxxx/Desktop/FlightGear.app/Contents/Resources/../Resources/data/Shaders/ssao.frag&amp;quot; infolog:&lt;br /&gt;
ERROR: 0:20: 'array of 2-component vector of float' : constructor not supported for type&lt;br /&gt;
ERROR: 0:20: 'array of 2-component vector of float' : no matching overloaded function found&lt;br /&gt;
ERROR: 0:20: 'const 2-component vector of float' : cannot declare arrays of this type&lt;br /&gt;
ERROR: 0:20: 'v' : redefinition&lt;br /&gt;
ERROR: 0:55: 'reflect' : no matching overloaded function found&lt;br /&gt;
ERROR: 0:55: '=' :  cannot convert from 'float' to '2-component vector of float'&lt;br /&gt;
&lt;br /&gt;
glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
ERROR: One or more attached shaders not successfully compiled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In that case, disable ambient occlusion with the command :&lt;br /&gt;
&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/ambient-occlusion-buffers=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
Once your aircraft has been ported, please modify its wiki page and add this symbol to it:&lt;br /&gt;
[[File:Rembrandtready.png]].&lt;br /&gt;
&lt;br /&gt;
For a list of converted aircraft, please see [http://flightgear.org/forums/viewtopic.php?f=4&amp;amp;t=17536#p166346].&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Making sure that all geometry will cast shadow ===&lt;br /&gt;
&lt;br /&gt;
To limit the amount of geometry rendered in the shadow map, and also to reduce artifacts (shadow acne), only faces not facing the sun are casting shadows. The test is made using the normal orientation. That means that double-sided polygons, or mesh that are not closed, will be transparent to light at certain sun angles. To avoid that, modelers can either :&lt;br /&gt;
* ensure that the object is always in the shadow of another objects,&lt;br /&gt;
* close their mesh, or,&lt;br /&gt;
* double polygons with the normal set to the opposite.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tutorials ===&lt;br /&gt;
[[User:F-JJTH|F-JJTH]] compiled his experience and the one acquired by the PAF team converting aircraft in this [http://equipe-flightgear.forumactif.com/t1034-howto-adapter-un-appareil-pour-rembrandt tutorial (in French)]&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
* {{cite web |url=http://publications.dice.se/publications.asp?show_category=yes&amp;amp;which_category=Rendering |author=DICE |title=Publications on rendering |accessdate=15 August 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:Release_plan&amp;diff=53795</id>
		<title>Talk:Release plan</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:Release_plan&amp;diff=53795"/>
		<updated>2012-09-04T12:52:56Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==For the benefit of the unwashed masses...==&lt;br /&gt;
&lt;br /&gt;
Would it be acceptable to discuss this proposition on this page? I've never managed to use the dev list properly - it always ends up being rather messy. --&amp;lt;span style=&amp;quot;text-shadow: Palegreen -0.6em -0.6em -0.1em; class=texhtml&amp;quot;&amp;gt;[[User Talk:Armchair Ace|&amp;lt;font color=&amp;quot;ForestGreen&amp;quot; face=&amp;quot;georgia&amp;quot;&amp;gt;&amp;amp;nbsp;Armchair Ace&amp;lt;/font&amp;gt;]]&amp;lt;/span&amp;gt; 15:00, 23 May 2011 (EDT)&lt;br /&gt;
&lt;br /&gt;
==What about inserting in this cycle a refactory release?==&lt;br /&gt;
&lt;br /&gt;
Hi, I was thinking: wouldn't it sound gound to add a 'refactoring'/performance/bugfixing specific release in this cycle. Maybe use a 3.1 number for instance. This would enable devs and fellow contributors to focus on fixing bugs reported, and try to make performance better on their projects. --&amp;lt;span style=&amp;quot;text-shadow: Palegreen -0.6em -0.6em -0.1em; class=texhtml&amp;quot;&amp;gt;[[User Talk:f-ojac|&amp;lt;font color=&amp;quot;ForestGreen&amp;quot; face=&amp;quot;georgia&amp;quot;&amp;gt;&amp;amp;nbsp;f-ojac&amp;lt;/font&amp;gt;]]&amp;lt;/span&amp;gt; 09:33, 21 August 2012 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Well, I like the idea, but I think it cannot be handled right now - due to the required workload for each release, just look at how people and resources are still the limiting factor here, even with &amp;quot;just 2&amp;quot; releases per year. This is because of all the manual work that's involved here. I don't think we'll see more releases without some serious automation work, like mentioned at [[Release plan#Open_items.2C_questions]]. Only after the release process is largely automated, can we expect more releases. Also, it's worth noting that, strictly speaking, refactoring is very different from improving performance or bugfixing. Bug fixing in particular is meant to be done during the code freeze period already. But, refactoring is all about keeping the existing behavior, while improving the design and the architecture to make it more maintainable. Now, having a &amp;quot;performance&amp;quot; release would be cool for a number of reasons,and FG can really be a resource hog. And FG eating up 14+ gb of RAM is just ridiculous and could have an impact on the project's reputation.--[[User:Hooray|Hooray]] 04:42, 21 August 2012 (EDT)&lt;br /&gt;
&lt;br /&gt;
==FGRun inclusion==&lt;br /&gt;
&lt;br /&gt;
fgrun is now hosted in the fg project, and appears as a submodule of fgmeta in the master branch. A Jenkins task, [http://flightgear.simpits.org:8080/job/Windows-rel-test/ Windows-rel-test], is configured to demonstrated the feasibility of including it in the final build process. What about including it in the release plan (same for maclauncher btw) ? -- [[User:Fredb|Fredb]] 08:52, 4 September 2012 (EDT)&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=53785</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=53785"/>
		<updated>2012-09-03T18:43:43Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Running Flightgear with Rembrandt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
The ssao effect provided in v2.8.0 may generate these messages, more often on Mac :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FRAGMENT glCompileShader &amp;quot;/Users/xxxx/Desktop/FlightGear.app/Contents/Resources/../Resources/data/Shaders/ssao.frag&amp;quot; FAILED&lt;br /&gt;
FRAGMENT Shader &amp;quot;/Users/J2MA/Desktop/FlightGear.app/Contents/Resources/../Resources/data/Shaders/ssao.frag&amp;quot; infolog:&lt;br /&gt;
ERROR: 0:20: 'array of 2-component vector of float' : constructor not supported for type&lt;br /&gt;
ERROR: 0:20: 'array of 2-component vector of float' : no matching overloaded function found&lt;br /&gt;
ERROR: 0:20: 'const 2-component vector of float' : cannot declare arrays of this type&lt;br /&gt;
ERROR: 0:20: 'v' : redefinition&lt;br /&gt;
ERROR: 0:55: 'reflect' : no matching overloaded function found&lt;br /&gt;
ERROR: 0:55: '=' :  cannot convert from 'float' to '2-component vector of float'&lt;br /&gt;
&lt;br /&gt;
glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
ERROR: One or more attached shaders not successfully compiled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In that case, disable ambient occlusion with the command :&lt;br /&gt;
&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/ambient-occlusion-buffers=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Making sure that all geometry will cast shadow ===&lt;br /&gt;
&lt;br /&gt;
To limit the amount of geometry rendered in the shadow map, and also to reduce artifacts (shadow acne), only faces not facing the sun are casting shadows. The test is made using the normal orientation. That means that double-sided polygons, or mesh that are not closed, will be transparent to light at certain sun angles. To avoid that, modelers can either :&lt;br /&gt;
* ensure that the object is always in the shadow of another objects,&lt;br /&gt;
* close their mesh, or,&lt;br /&gt;
* double polygons with the normal set to the opposite.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
* {{cite web |url=http://publications.dice.se/publications.asp?show_category=yes&amp;amp;which_category=Rendering |author=DICE |title=Publications on rendering |accessdate=15 August 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Launch_Control&amp;diff=53774</id>
		<title>FlightGear Launch Control</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Launch_Control&amp;diff=53774"/>
		<updated>2012-09-02T21:51:01Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Software&lt;br /&gt;
| title                  = FlightGear Launch Control&lt;br /&gt;
| image                  = Fgrun-page2.jpg&lt;br /&gt;
| alt                    = The second (aircraft selection) page of FGRun.&lt;br /&gt;
| developedby            = Bernie Bright, Frederic Bouvier&lt;br /&gt;
| initialrelease         = 0.3.2 (October 24, 2003)&lt;br /&gt;
| latestrelease          = 1.6.2 (August 17, 2012)&lt;br /&gt;
| writtenin              = C++&lt;br /&gt;
| os                     = All 32-bit MS Windows (95/98/NT/2000/XP)&amp;lt;br /&amp;gt;All POSIX (Linux/BSD/UNIX-like)&lt;br /&gt;
| developmentstatus      = Active (2002-)&lt;br /&gt;
| license                = [[GNU General Public License]]&lt;br /&gt;
| website                = http://sourceforge.net/projects/fgrun&lt;br /&gt;
}}&lt;br /&gt;
'''FlightGear Launch Control''' ('''FGRun''') is a graphical frontend for [[FlightGear]], distributed and developed separately at [http://sourceforge.net/projects/fgrun] SourceForge. However, it was included in officially distributed binaries for FlightGear, even though it is not technically a part the FlightGear program, like several other frontends (see also [[FlightGear related projects]]). FGRun allows one to choose options more easily than with the [[Command Line Parameters|command line]].&lt;br /&gt;
&lt;br /&gt;
The application has two main parts: &lt;br /&gt;
* a wizard to choose common options&lt;br /&gt;
* an advanced section where all options are available for advanced users.&lt;br /&gt;
&lt;br /&gt;
Options chosen are automatically saved in a file and are reused the next time FGRun is started.&lt;br /&gt;
&lt;br /&gt;
For information on compiling this software see [[Building FlightGear Launch Control]].&lt;br /&gt;
&lt;br /&gt;
== The wizard ==&lt;br /&gt;
The wizard appears to the user when FGRun is started. The first time, when no path are set, the first page is shown, otherwise, it jumps directly to the second page, but the first one is still accessible by hitting the &amp;quot;Prev&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
=== Navigation bar ===&lt;br /&gt;
The bottom of the wizard shows six buttons. From left to right:&lt;br /&gt;
* '''Defaults''' : in case of emergency, clear all options and restore initial path set at installation.&lt;br /&gt;
* '''Load''' : Load a set of options previously saved.&lt;br /&gt;
* '''Save as...''' : Save the current set of options to a file.&lt;br /&gt;
* '''Prev''' : go to previous page of the wizard.&lt;br /&gt;
* '''Next''' : go to next page of the wizard. This button is replaced by the '''Run''' button in the last page, to start FlightGear.&lt;br /&gt;
* '''Quit''' : end the wizard ( and terrasync if it was started by fgrun ).&lt;br /&gt;
&lt;br /&gt;
=== Page One - Paths ===&lt;br /&gt;
[[File:fgrun-page1.jpg|thumb]]&lt;br /&gt;
In the first page, the paths needed by FGRun are recalled and can be set. If FGRun was installed with a binary package, either under Windows or Linux, these paths are normally initialized by the installation procedure.&lt;br /&gt;
&lt;br /&gt;
* '''Executable''': the full path to the FlightGear program (&amp;lt;tt&amp;gt;fgfs&amp;lt;/tt&amp;gt;). One can choose it directly using the file selection dialog that pops up when the folder button is hit.&lt;br /&gt;
* '''[[$FG ROOT|FG_ROOT]]''': the full path to the FlightGear base package (&amp;lt;tt&amp;gt;data/&amp;lt;/tt&amp;gt; directory). If this path is wrong, no [[aircraft]] would be displayed and FlightGear won't run.&lt;br /&gt;
* '''[[$FG_AIRCRAFT|FG_AIRCRAFT]]''': can link to external aircraft packages. Leave empty when all your aircraft are installed in &amp;lt;tt&amp;gt;[[$FG_ROOT]]/Aircraft&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''[[FG SCENERY]]''': the paths to [[scenery]] folders. These folders usually have a 'Terrain', and optionally a 'Objects' , subfolders. You can add a new path with the 'Add...' button. Priorities among folders are managed with the up and down arrows; the top most folder having the highest priority. If there is no scenery for a location in the top folder, FlightGear will look in the next folder etc.&lt;br /&gt;
* '''Airports Cache''': the location of the file that stores the [[:Category:Airports|airport]] ids found in the scenery. It is faster to access that file than to scan scenery directories to build the airport list. It is possible to delete that file if things go wrong. That will force a new scan when the third page will be shown.&lt;br /&gt;
&lt;br /&gt;
'''Hint''': If things go wrong and FlightGear cannot start anymore, and you want to start over with a bare installation, remove or rename the file named 'fgrun.prefs' located in the parent directory of the airport cache file. You will have to reenter path by hand, but the silly options you could have entered will be deleted.&lt;br /&gt;
&lt;br /&gt;
=== Page two - Aircraft Selection ===&lt;br /&gt;
[[File:fgrun-page2.jpg|thumb]]&lt;br /&gt;
The second page, usually the first page seen by users when starting fgrun, is the aircraft selection page. It shows the list of aircraft found in &amp;lt;tt&amp;gt;[[$FG ROOT]]/Aircraft&amp;lt;/tt&amp;gt; and all &amp;lt;tt&amp;gt;FG_AIRCRAFT&amp;lt;/tt&amp;gt; directories, and the model of the selected aircraft.&lt;br /&gt;
&lt;br /&gt;
=== Page three - Airport Selection ===&lt;br /&gt;
[[File:fgrun-page3.jpg|thumb]]&lt;br /&gt;
The third page is the Airport and Runway selection box. It only shows the content of the Airport Cache file, that should be the reflect of the content of the scenery folders. If a new scenery has been installed and doesn't show up, or an old scenery has been deleted and airport are still there, click on the 'Refresh' button to rescan the scenery directories. The scan occurs the first time or when the Airport Cache has been deleted.&lt;br /&gt;
&lt;br /&gt;
The airport's list doesn't seem to appear (or ever worse, it disappears) when the refresh button is pressed. To (re)build this list execute the following line once the FlightGear-data is installed:&lt;br /&gt;
&lt;br /&gt;
 zcat /usr/share/FlightGear/Airports/metar.dat.gz &amp;gt; \${HOME}/.fltk/flightgear.org/fgrun/airports.txt&lt;br /&gt;
&lt;br /&gt;
=== Page four - Options and Run ===&lt;br /&gt;
[[File:fgrun-page4.jpg|thumb]]&lt;br /&gt;
The last page shows common options without the need to go to the Advanced section.&lt;br /&gt;
&lt;br /&gt;
:'''Hint'''&lt;br /&gt;
: Usually, people new to FlightGear should stick there and experience a simple flight before going to the advanced section. This way, it will be easier to diagnose problem if, by accident, FlightGear would not start or run. Often problems come from incoherent options choosen, and there is no fool guard beyond this limit. If FG doen't run anyway, it will be time to look at the hardware setup.&lt;br /&gt;
&lt;br /&gt;
The command line is helpful to people wanting to diagnose a problem.&lt;br /&gt;
&lt;br /&gt;
The 'Run' button starts FlightGear with the options shown in the command line box.&lt;br /&gt;
&lt;br /&gt;
== Advanced Options ==&lt;br /&gt;
The advanced options dialog can be opened through clicking the 'Advanced' button on the last (fourth) page of the launcher.&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
[[File:fgrun-wiki-a01.jpg|thumb|General]]&lt;br /&gt;
* '''FG_SCENERY:''' Where's your [[scenery]] saved on your computer?&lt;br /&gt;
* '''Control:''' Which controller do you use?&lt;br /&gt;
* '''Airport:''' Your start airport.&lt;br /&gt;
* '''Runway:''' Start runway of your airport (see above).&lt;br /&gt;
* '''Aircraft:''' Your flying vehicle/[[aircraft]].&lt;br /&gt;
* '''Language:''' The language of FlightGear.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
[[File:fgrun-wiki-a02.jpg|thumb|Features]]&lt;br /&gt;
* '''Game Mode:''' The full screen game mode.&lt;br /&gt;
* '''Random Objects:''' Enable random [[scenery]] objects.&lt;br /&gt;
* '''Sound:''' Enable sound effects like engine sounds.&lt;br /&gt;
* '''HUD:''' Enable Heads Up Display (HUD).&lt;br /&gt;
* '''AI Traffic:''' Enable [[AI traffic]].&lt;br /&gt;
&lt;br /&gt;
=== Flight Model ===&lt;br /&gt;
[[File:fgrun-wiki-a03.jpg|thumb|Flight Model]]&lt;br /&gt;
&lt;br /&gt;
=== Freeze ===&lt;br /&gt;
[[File:fgrun-wiki-a04.jpg|thumb|Freeze]]&lt;br /&gt;
* '''Freeze:''' Start paused'.&lt;br /&gt;
&lt;br /&gt;
=== Initial Position ===&lt;br /&gt;
[[File:fgrun-wiki-a05.jpg|thumb|Initial Position]]&lt;br /&gt;
* '''Longitude:''' What's your longitude?&lt;br /&gt;
* '''Latitude:''' What's your latitude?&lt;br /&gt;
* '''Altitude:''' What's your altitude?&lt;br /&gt;
* '''Heading:''' The aircraft heading degrees magnetic.&lt;br /&gt;
* '''Airspeed:''' Your airspeed in knots.&lt;br /&gt;
&lt;br /&gt;
=== Rendering ===&lt;br /&gt;
[[File:fgrun-wiki-a06.jpg|thumb|Rendering]]&lt;br /&gt;
* '''Clouds:''' Are there any clouds up in the air?&lt;br /&gt;
* '''3D Clouds:''' Are the clouds 3D?&lt;br /&gt;
* '''Full Screen:''' Want to play on full screen?&lt;br /&gt;
* '''Wireframe:''' Do you wanna see only the wires of the [[scenery]] and the [[aircraft]]?&lt;br /&gt;
* '''Visibility:''' Visibility distance in meters or miles.&lt;br /&gt;
* '''Bpp:''' Color depth in Bits per pixel.&lt;br /&gt;
* '''FOV:''' Field of View angle.&lt;br /&gt;
* '''Materials file:''' The materials XML file (default materials.xml, can be changed to materials-dds.xml for DDS scenery textures).&lt;br /&gt;
&lt;br /&gt;
=== Time ===&lt;br /&gt;
[[File:fgrun-wiki-a07.jpg|thumb|Time]]&lt;br /&gt;
* '''Time match local:''' Synchronisize simulation time with local time.&lt;br /&gt;
* '''Time of day:''' What's the time of the day? &lt;br /&gt;
&lt;br /&gt;
=== Network ===&lt;br /&gt;
[[File:fgrun-wiki-a08.jpg|thumb|Network]]&lt;br /&gt;
* '''Callsign:''' your callsign for the network. This is used to recognize other pilots and for tracking your flights.&lt;br /&gt;
&lt;br /&gt;
'''See:''' [[Multiplayer Howto]]&lt;br /&gt;
&lt;br /&gt;
=== Input/Output ===&lt;br /&gt;
[[File:fgrun-wiki-a09.jpg|thumb|Input/Output]]&lt;br /&gt;
&lt;br /&gt;
=== Avionics ===&lt;br /&gt;
[[File:fgrun-wiki-a10.jpg|thumb|Avionics]]&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
[[File:fgrun-wiki-a11.jpg|thumb|Properties]]&lt;br /&gt;
This is where you could edit or add new property commands. It's same as configuring the [[command line]] with &amp;lt;tt&amp;gt;--prop:...&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
[[File:fgrun-wiki-a12.jpg|thumb|Debugging]]&lt;br /&gt;
* '''Log Level:''' The lower the log level, the less errors you'll see. A higher log level can increase the loading time extremely.&lt;br /&gt;
* '''Trace Read Properties:'''&lt;br /&gt;
* '''Trace Write Properties:'''&lt;br /&gt;
=== Environment ===&lt;br /&gt;
[[File:fgrun-wiki-a13.jpg|thumb|Environment]]&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
[[File:fgrun-wiki-a14.jpg|thumb|Weather]]&lt;br /&gt;
* '''Wind Direction:''' Direction of the wind.&lt;br /&gt;
* '''Heading:''' Directon wind is coming from.&lt;br /&gt;
* '''Speed:''' Wind speed in knots (kts).&lt;br /&gt;
&lt;br /&gt;
=== Clouds ===&lt;br /&gt;
[[File:fgrun-wiki-a15.jpg|thumb|Clouds]]&lt;br /&gt;
* '''Elevation:''' How high (in feet) are the clouds?&lt;br /&gt;
* '''Thickness:''' How thick (in feet) are the clouds?&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[FGo!]], a simple GUI front-end for FlightGear written in Python&lt;br /&gt;
* [[JFlightWizard]], another graphical frontend&lt;br /&gt;
&lt;br /&gt;
== External link ==&lt;br /&gt;
* [https://gitorious.org/fg/fgrun Git repository]&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear front ends]]&lt;br /&gt;
[[Category:GPL software]]&lt;br /&gt;
&lt;br /&gt;
[[de:FlightGear Launch Control]]&lt;br /&gt;
[[fr:FlightGear Launch Control]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Launch_Control&amp;diff=53773</id>
		<title>FlightGear Launch Control</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Launch_Control&amp;diff=53773"/>
		<updated>2012-09-02T21:47:17Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Page two - Aircraft Selection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Software&lt;br /&gt;
| title                  = FlightGear Launch Control&lt;br /&gt;
| image                  = Fgrun-page2.jpg&lt;br /&gt;
| alt                    = The second (aircraft selection) page of FGRun.&lt;br /&gt;
| developedby            = Bernie Bright, Frederic Bouvier&lt;br /&gt;
| initialrelease         = 0.3.2 (October 24, 2003)&lt;br /&gt;
| latestrelease          = 1.5.2 (February 6, 2010)&lt;br /&gt;
| writtenin              = C++&lt;br /&gt;
| os                     = All 32-bit MS Windows (95/98/NT/2000/XP)&amp;lt;br /&amp;gt;All POSIX (Linux/BSD/UNIX-like)&lt;br /&gt;
| developmentstatus      = Active (2002-)&lt;br /&gt;
| license                = [[GNU General Public License]]&lt;br /&gt;
| website                = http://sourceforge.net/projects/fgrun&lt;br /&gt;
}}&lt;br /&gt;
'''FlightGear Launch Control''' ('''FGRun''') is a graphical frontend for [[FlightGear]], distributed and developed separately at [http://sourceforge.net/projects/fgrun] SourceForge. However, it was included in officially distributed binaries for FlightGear, even though it is not technically a part the FlightGear program, like several other frontends (see also [[FlightGear related projects]]). FGRun allows one to choose options more easily than with the [[Command Line Parameters|command line]].&lt;br /&gt;
&lt;br /&gt;
The application has two main parts: &lt;br /&gt;
* a wizard to choose common options&lt;br /&gt;
* an advanced section where all options are available for advanced users.&lt;br /&gt;
&lt;br /&gt;
Options chosen are automatically saved in a file and are reused the next time FGRun is started.&lt;br /&gt;
&lt;br /&gt;
For information on compiling this software see [[Building FlightGear Launch Control]].&lt;br /&gt;
&lt;br /&gt;
== The wizard ==&lt;br /&gt;
The wizard appears to the user when FGRun is started. The first time, when no path are set, the first page is shown, otherwise, it jumps directly to the second page, but the first one is still accessible by hitting the &amp;quot;Prev&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
=== Navigation bar ===&lt;br /&gt;
The bottom of the wizard shows six buttons. From left to right:&lt;br /&gt;
* '''Defaults''' : in case of emergency, clear all options and restore initial path set at installation.&lt;br /&gt;
* '''Load''' : Load a set of options previously saved.&lt;br /&gt;
* '''Save as...''' : Save the current set of options to a file.&lt;br /&gt;
* '''Prev''' : go to previous page of the wizard.&lt;br /&gt;
* '''Next''' : go to next page of the wizard. This button is replaced by the '''Run''' button in the last page, to start FlightGear.&lt;br /&gt;
* '''Quit''' : end the wizard ( and terrasync if it was started by fgrun ).&lt;br /&gt;
&lt;br /&gt;
=== Page One - Paths ===&lt;br /&gt;
[[File:fgrun-page1.jpg|thumb]]&lt;br /&gt;
In the first page, the paths needed by FGRun are recalled and can be set. If FGRun was installed with a binary package, either under Windows or Linux, these paths are normally initialized by the installation procedure.&lt;br /&gt;
&lt;br /&gt;
* '''Executable''': the full path to the FlightGear program (&amp;lt;tt&amp;gt;fgfs&amp;lt;/tt&amp;gt;). One can choose it directly using the file selection dialog that pops up when the folder button is hit.&lt;br /&gt;
* '''[[$FG ROOT|FG_ROOT]]''': the full path to the FlightGear base package (&amp;lt;tt&amp;gt;data/&amp;lt;/tt&amp;gt; directory). If this path is wrong, no [[aircraft]] would be displayed and FlightGear won't run.&lt;br /&gt;
* '''[[$FG_AIRCRAFT|FG_AIRCRAFT]]''': can link to external aircraft packages. Leave empty when all your aircraft are installed in &amp;lt;tt&amp;gt;[[$FG_ROOT]]/Aircraft&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''[[FG SCENERY]]''': the paths to [[scenery]] folders. These folders usually have a 'Terrain', and optionally a 'Objects' , subfolders. You can add a new path with the 'Add...' button. Priorities among folders are managed with the up and down arrows; the top most folder having the highest priority. If there is no scenery for a location in the top folder, FlightGear will look in the next folder etc.&lt;br /&gt;
* '''Airports Cache''': the location of the file that stores the [[:Category:Airports|airport]] ids found in the scenery. It is faster to access that file than to scan scenery directories to build the airport list. It is possible to delete that file if things go wrong. That will force a new scan when the third page will be shown.&lt;br /&gt;
&lt;br /&gt;
'''Hint''': If things go wrong and FlightGear cannot start anymore, and you want to start over with a bare installation, remove or rename the file named 'fgrun.prefs' located in the parent directory of the airport cache file. You will have to reenter path by hand, but the silly options you could have entered will be deleted.&lt;br /&gt;
&lt;br /&gt;
=== Page two - Aircraft Selection ===&lt;br /&gt;
[[File:fgrun-page2.jpg|thumb]]&lt;br /&gt;
The second page, usually the first page seen by users when starting fgrun, is the aircraft selection page. It shows the list of aircraft found in &amp;lt;tt&amp;gt;[[$FG ROOT]]/Aircraft&amp;lt;/tt&amp;gt; and all &amp;lt;tt&amp;gt;FG_AIRCRAFT&amp;lt;/tt&amp;gt; directories, and the model of the selected aircraft.&lt;br /&gt;
&lt;br /&gt;
=== Page three - Airport Selection ===&lt;br /&gt;
[[File:fgrun-page3.jpg|thumb]]&lt;br /&gt;
The third page is the Airport and Runway selection box. It only shows the content of the Airport Cache file, that should be the reflect of the content of the scenery folders. If a new scenery has been installed and doesn't show up, or an old scenery has been deleted and airport are still there, click on the 'Refresh' button to rescan the scenery directories. The scan occurs the first time or when the Airport Cache has been deleted.&lt;br /&gt;
&lt;br /&gt;
The airport's list doesn't seem to appear (or ever worse, it disappears) when the refresh button is pressed. To (re)build this list execute the following line once the FlightGear-data is installed:&lt;br /&gt;
&lt;br /&gt;
 zcat /usr/share/FlightGear/Airports/metar.dat.gz &amp;gt; \${HOME}/.fltk/flightgear.org/fgrun/airports.txt&lt;br /&gt;
&lt;br /&gt;
=== Page four - Options and Run ===&lt;br /&gt;
[[File:fgrun-page4.jpg|thumb]]&lt;br /&gt;
The last page shows common options without the need to go to the Advanced section.&lt;br /&gt;
&lt;br /&gt;
:'''Hint'''&lt;br /&gt;
: Usually, people new to FlightGear should stick there and experience a simple flight before going to the advanced section. This way, it will be easier to diagnose problem if, by accident, FlightGear would not start or run. Often problems come from incoherent options choosen, and there is no fool guard beyond this limit. If FG doen't run anyway, it will be time to look at the hardware setup.&lt;br /&gt;
&lt;br /&gt;
The command line is helpful to people wanting to diagnose a problem.&lt;br /&gt;
&lt;br /&gt;
The 'Run' button starts FlightGear with the options shown in the command line box.&lt;br /&gt;
&lt;br /&gt;
== Advanced Options ==&lt;br /&gt;
The advanced options dialog can be opened through clicking the 'Advanced' button on the last (fourth) page of the launcher.&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
[[File:fgrun-wiki-a01.jpg|thumb|General]]&lt;br /&gt;
* '''FG_SCENERY:''' Where's your [[scenery]] saved on your computer?&lt;br /&gt;
* '''Control:''' Which controller do you use?&lt;br /&gt;
* '''Airport:''' Your start airport.&lt;br /&gt;
* '''Runway:''' Start runway of your airport (see above).&lt;br /&gt;
* '''Aircraft:''' Your flying vehicle/[[aircraft]].&lt;br /&gt;
* '''Language:''' The language of FlightGear.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
[[File:fgrun-wiki-a02.jpg|thumb|Features]]&lt;br /&gt;
* '''Game Mode:''' The full screen game mode.&lt;br /&gt;
* '''Random Objects:''' Enable random [[scenery]] objects.&lt;br /&gt;
* '''Sound:''' Enable sound effects like engine sounds.&lt;br /&gt;
* '''HUD:''' Enable Heads Up Display (HUD).&lt;br /&gt;
* '''AI Traffic:''' Enable [[AI traffic]].&lt;br /&gt;
&lt;br /&gt;
=== Flight Model ===&lt;br /&gt;
[[File:fgrun-wiki-a03.jpg|thumb|Flight Model]]&lt;br /&gt;
&lt;br /&gt;
=== Freeze ===&lt;br /&gt;
[[File:fgrun-wiki-a04.jpg|thumb|Freeze]]&lt;br /&gt;
* '''Freeze:''' Start paused'.&lt;br /&gt;
&lt;br /&gt;
=== Initial Position ===&lt;br /&gt;
[[File:fgrun-wiki-a05.jpg|thumb|Initial Position]]&lt;br /&gt;
* '''Longitude:''' What's your longitude?&lt;br /&gt;
* '''Latitude:''' What's your latitude?&lt;br /&gt;
* '''Altitude:''' What's your altitude?&lt;br /&gt;
* '''Heading:''' The aircraft heading degrees magnetic.&lt;br /&gt;
* '''Airspeed:''' Your airspeed in knots.&lt;br /&gt;
&lt;br /&gt;
=== Rendering ===&lt;br /&gt;
[[File:fgrun-wiki-a06.jpg|thumb|Rendering]]&lt;br /&gt;
* '''Clouds:''' Are there any clouds up in the air?&lt;br /&gt;
* '''3D Clouds:''' Are the clouds 3D?&lt;br /&gt;
* '''Full Screen:''' Want to play on full screen?&lt;br /&gt;
* '''Wireframe:''' Do you wanna see only the wires of the [[scenery]] and the [[aircraft]]?&lt;br /&gt;
* '''Visibility:''' Visibility distance in meters or miles.&lt;br /&gt;
* '''Bpp:''' Color depth in Bits per pixel.&lt;br /&gt;
* '''FOV:''' Field of View angle.&lt;br /&gt;
* '''Materials file:''' The materials XML file (default materials.xml, can be changed to materials-dds.xml for DDS scenery textures).&lt;br /&gt;
&lt;br /&gt;
=== Time ===&lt;br /&gt;
[[File:fgrun-wiki-a07.jpg|thumb|Time]]&lt;br /&gt;
* '''Time match local:''' Synchronisize simulation time with local time.&lt;br /&gt;
* '''Time of day:''' What's the time of the day? &lt;br /&gt;
&lt;br /&gt;
=== Network ===&lt;br /&gt;
[[File:fgrun-wiki-a08.jpg|thumb|Network]]&lt;br /&gt;
* '''Callsign:''' your callsign for the network. This is used to recognize other pilots and for tracking your flights.&lt;br /&gt;
&lt;br /&gt;
'''See:''' [[Multiplayer Howto]]&lt;br /&gt;
&lt;br /&gt;
=== Input/Output ===&lt;br /&gt;
[[File:fgrun-wiki-a09.jpg|thumb|Input/Output]]&lt;br /&gt;
&lt;br /&gt;
=== Avionics ===&lt;br /&gt;
[[File:fgrun-wiki-a10.jpg|thumb|Avionics]]&lt;br /&gt;
&lt;br /&gt;
=== Properties ===&lt;br /&gt;
[[File:fgrun-wiki-a11.jpg|thumb|Properties]]&lt;br /&gt;
This is where you could edit or add new property commands. It's same as configuring the [[command line]] with &amp;lt;tt&amp;gt;--prop:...&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
[[File:fgrun-wiki-a12.jpg|thumb|Debugging]]&lt;br /&gt;
* '''Log Level:''' The lower the log level, the less errors you'll see. A higher log level can increase the loading time extremely.&lt;br /&gt;
* '''Trace Read Properties:'''&lt;br /&gt;
* '''Trace Write Properties:'''&lt;br /&gt;
=== Environment ===&lt;br /&gt;
[[File:fgrun-wiki-a13.jpg|thumb|Environment]]&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
[[File:fgrun-wiki-a14.jpg|thumb|Weather]]&lt;br /&gt;
* '''Wind Direction:''' Direction of the wind.&lt;br /&gt;
* '''Heading:''' Directon wind is coming from.&lt;br /&gt;
* '''Speed:''' Wind speed in knots (kts).&lt;br /&gt;
&lt;br /&gt;
=== Clouds ===&lt;br /&gt;
[[File:fgrun-wiki-a15.jpg|thumb|Clouds]]&lt;br /&gt;
* '''Elevation:''' How high (in feet) are the clouds?&lt;br /&gt;
* '''Thickness:''' How thick (in feet) are the clouds?&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[FGo!]], a simple GUI front-end for FlightGear written in Python&lt;br /&gt;
* [[JFlightWizard]], another graphical frontend&lt;br /&gt;
&lt;br /&gt;
== External link ==&lt;br /&gt;
* [https://gitorious.org/fg/fgrun Git repository]&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear front ends]]&lt;br /&gt;
[[Category:GPL software]]&lt;br /&gt;
&lt;br /&gt;
[[de:FlightGear Launch Control]]&lt;br /&gt;
[[fr:FlightGear Launch Control]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=53727</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=53727"/>
		<updated>2012-09-01T22:18:56Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &amp;quot;error C6013&amp;quot; shouldn't appear because Rembrandt no longer use arrays in fragment shaders for shadows&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Making sure that all geometry will cast shadow ===&lt;br /&gt;
&lt;br /&gt;
To limit the amount of geometry rendered in the shadow map, and also to reduce artifacts (shadow acne), only faces not facing the sun are casting shadows. The test is made using the normal orientation. That means that double-sided polygons, or mesh that are not closed, will be transparent to light at certain sun angles. To avoid that, modelers can either :&lt;br /&gt;
* ensure that the object is always in the shadow of another objects,&lt;br /&gt;
* close their mesh, or,&lt;br /&gt;
* double polygons with the normal set to the opposite.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
* {{cite web |url=http://publications.dice.se/publications.asp?show_category=yes&amp;amp;which_category=Rendering |author=DICE |title=Publications on rendering |accessdate=15 August 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=53726</id>
		<title>Fr/Projet Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=53726"/>
		<updated>2012-09-01T22:14:07Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Pipeline configurable */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Pourquoi ce nom? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] était un peintre hollandais du XVIIème siècle, maître incontesté du [http://en.wikipedia.org/wiki/Chiaroscuro &amp;quot;clair-obscur&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Ce projet a pour but de changer la manière de rendre les éclairages et les [[Shadows|ombres]] qu'utilise [[FlightGear]], et d'essayer d'imiter le style de Rembrandt dans FG.&lt;br /&gt;
&lt;br /&gt;
== De quoi s'agit-il ? ==&lt;br /&gt;
L'idée maîtresse du projet est d'implémenter le [http://en.wikipedia.org/wiki/Deferred_shading rendu différé] au sein de FlightGear.&lt;br /&gt;
Depuis le début, FlightGear utilise un moteur de rendu en avant qui affiche toutes les propriétés d'un objet en une fois (ombre, éclairage, brouillard, ...), ce qui rend difficile le rendu d'un ombrage plus sophistiqué (voir le [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) du fait que tous les paramètres de [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ l'équation lumineuse] doivent être traités en une seule fois.&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Vue principale avec le contenu des buffers affichés dans les coins]]&lt;br /&gt;
Au contraire, le rendu différé cherche à séparer les opérations en étapes simplifiées et à collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par la prochain étape.&lt;br /&gt;
&lt;br /&gt;
;Le premier stade est celui de la Géométrie:&lt;br /&gt;
: nous rendons la scène entière dans 4 textures, en utilisant le rendu multi-cibles pour les traiter en un seul passage: un pour le buffer de profondeur, un pour les normales (en bas à gauche de l'image), un pour les couleurs &amp;quot;diffuses&amp;quot; (en bas à gauche) et un pour les couleurs &amp;quot;spéculaires&amp;quot; (en haut à droite).&lt;br /&gt;
&lt;br /&gt;
;Le stade suivant est celui de l'ombre :&lt;br /&gt;
: nous rendons encore la scène dans une texture profondeur concernant les éclairages. Il y aura une texture pour chaque lumière diffusant des ombres.&lt;br /&gt;
&lt;br /&gt;
;Ensuite, c'est le stade de l'éclairage, avec plusieurs sous-stades :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: Le ciel est dessiné d'abord selon la méthode classique.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: la mémoire-tampon &amp;quot;diffuse&amp;quot; est modulé avec la couleur ambiante de la scène, et est dessiné comme un quad texturé aligné sur l'écran&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: Un second quad aligné à l'écran est dessiné et un shader examine la position pour calculer sa couleur &amp;quot;diffuse&amp;quot; et &amp;quot;specular&amp;quot; en utilisant le &amp;quot;normal&amp;quot; stocké dans le premier stade. La couleur résultante et mélangée avec la passe précédente. Les ombres sont examinées ici par comparaison de la position du pixel avec la position du cache lumière stockée dans la carte shadows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:*&amp;lt;u&amp;gt;stade de la lumière additionnelle&amp;lt;/u&amp;gt;: le scene graph sera traversé une autre fois pour afficher les volumes de lumière (cône ou tronc de cône pour les taches de lumière, sphère pour les lumières omni directionnelles), et leur shader ajoutera la lumière composée uniquement par les pixels éclairés.&lt;br /&gt;
:*&amp;lt;u&amp;gt;stade brouillard&amp;lt;/u&amp;gt;: un nouveau quad aligné sur l'écran est dessiné, et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat du stade précédent.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Stade des objets transparents&amp;lt;/u&amp;gt;: les objets transparents (et les nuages) sont enfin rendus en utilisant la méthode classique.&lt;br /&gt;
&lt;br /&gt;
:Tous les données de lumière sont accumulées dans une seule mémoire tampon, qui sera utilisée pour le dernier stade en addition au stade Géométrie.&lt;br /&gt;
&lt;br /&gt;
;A la fin, le stade affichage, avec l'option effet post-traitement :&lt;br /&gt;
:Les résultats des précédents tampons sont poussés dans le tampon principal pour être affichés, optionnellement modifiés pour montrer Glow, Motion blur, HDR, redout ou blackout, occlusion ambiante de l'espace écran, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
Dans FG, on termine le pipeline du rendu par l'affichage du [[Menubar|GUI]] et du [[HUD]].&lt;br /&gt;
&lt;br /&gt;
Tous ces phases sont plus précisément décrites dans [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] c'est la base du code actuel, avec quelque addition ou modifications.&lt;br /&gt;
&lt;br /&gt;
== Avertissements ==&lt;br /&gt;
Le rendu différé n'affiche pas la transparence. Pour le moment, les nuages doivent être éclairés et ombrés par eux-mêmes. Les surfaces transparentes sont alpha-testées et non mélangées. Elles doivent être amenées dans leur propre bin sur l'image composite.&lt;br /&gt;
&lt;br /&gt;
La partition profondeur ne marche pas non plus, à cause de la mémoire tampon profondeur, qui doit être gardée pour retenir la position de zone de vue, et, pour le moment, z-fighting est tout à fait visible. La partition profondeur sans rangée de profondeur superposée pourrait être la solution, et devrait être essayée.&lt;br /&gt;
&lt;br /&gt;
Le passage de la lumière peut rendre certains MFD illisibles (ce qui utilisent une couleur émissive) car flous. Ils devront être traités comme transparents.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mise en œuvre ==&lt;br /&gt;
=== Répertoires ===&lt;br /&gt;
Le code est la principale branche du [[FlightGear and Git|répertoire officiel]]. Aucune autre localisation n'existe.&lt;br /&gt;
&lt;br /&gt;
=== Rendu des surfaces transparentes ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Surfaces transparentes desssinées d'après des objets opaques]]&lt;br /&gt;
Les surfaces transparentes sont détectées par les plugins OSG loader qui captent la nuance de rendu TRANSPARENT_BIN&lt;br /&gt;
 In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Consommation de mémoire ===&lt;br /&gt;
Pour chaque caméra définie du groupe, il y a une carte d'ombre séparée, de telle sorte que l'utilisation de la mémoire vidéo soit:&lt;br /&gt;
* G-tampon et tampon lumière: 20 bytes par pixel. Pour un écran HD (1920x1080) la mémoire requise est de 40 Mb&lt;br /&gt;
* Carte d'ombre 3 x taille_carte_ombre x shadow_map_size bytes (si la taille est 8192, la taille totale de la mémoire est 192 Mb&lt;br /&gt;
Ne pas compter les textures, liste d'affichage ou tampons vertex pour kes modèles et terrains&lt;br /&gt;
&lt;br /&gt;
3 écrans HD ont besoin de 120 Mb de mémoire pour les tampons (ombre exclue), il vous faut  3x8192x8192x3 = 576 Mb (megabytes) de mémoire pour les seuls shadows.&lt;br /&gt;
&lt;br /&gt;
Si vous voyez des messages d'erreur pendant le démarrage, ou si FlightGear ne démarre pas bien, c'est probablement parceque vous n'avez pas assez de mémoire vidéo libre. Réduisez la taille de la carte d'ombre dans préférences.xml &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Et mettez 4096 ou 2048 à la place.&lt;br /&gt;
Vous pouvez aussi utiliser un paramètre de démarrage: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Pipeline configurable  ===&lt;br /&gt;
&lt;br /&gt;
Le rendu Rembrandt utilise un fichier XML  pour installer son pipeline pour chaque fenêtre décrite dans le groupe de cameras. Ce fichier mntre la façon dont les tampons intermédiaires sont établis, et comment les différentes étapes du rendu sont agencés. Le schéma général du fichier pipeline est le suivant :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ere définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition de tampon --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- 1ère définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- n ème définition d'étape --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Tampons ====&lt;br /&gt;
Un tampon est une texture utilisée comme zone de stockage dans le GPU. Sa taille est habituellement un multiple de la taille de l'écran, mais une taille fixe est prise en charge ( typique pour la carte d'ombres). La description d'un tampon suit :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[en:Project Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=53725</id>
		<title>FlightGear Newsletter August 2012</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=53725"/>
		<updated>2012-09-01T22:07:35Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* FlightGear 2.8.0 Released ! */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{newsletter}}&lt;br /&gt;
{{TOC_right|limit=2}}&lt;br /&gt;
&lt;br /&gt;
''We would like to emphasize that the monthly newsletter can not live without the contributions of FlightGear users and developers. Everyone with a wiki account (free to register) can edit the newsletter and every contribution is welcome. So if you know about any FlightGear related news or projects such as for example updated scenery or aircraft, please do feel invited to add such news to the newsletter.''&lt;br /&gt;
&lt;br /&gt;
== FlightGear 2.8.0 Released ! ==&lt;br /&gt;
&lt;br /&gt;
The FlightGear team is very excited to announce the v2.8.0 Release is now available! I will be brief and simply post the link to the official release announcement.&lt;br /&gt;
&lt;br /&gt;
http://www.flightgear.org/news/flightgear-v2-8-0-released/&lt;br /&gt;
&lt;br /&gt;
Some of the notable changes and improvements include:&lt;br /&gt;
&lt;br /&gt;
Major improvements from v2.6.0 include improved AI aircraft, up to date with all the recent JSBSim flight dynamics model improvements, support for region specific textures, better random 3d buildings, better random object placement, 3d airport signage, in-sim toggling between summer and winter texture sets. The core FlightGear code now supports a flexible 2d rendering system which can be used to accurately model glass cockpit displays and other complex instrumentation. There are many new and improved aircraft to explore. A new automated system is now available for scenery submissions that automatically get rolled into the scenery distribution to be enjoyed by everyone. Version 2.8 has improved atmospheric light scatter modeling, better terrain haze, and improved 3d clouds.&lt;br /&gt;
&lt;br /&gt;
A very exciting new addition is “Project Rembrandt”. This is still considered “experimental” and not enabled by default. But when you turn it on you will get real-time shadows, support for multiple light sources (landing lights, instrument lights, directional ground spotlights, even the rotating beacons illuminate the surrounding correctly.) In addition, Project Rembrandt offers a variety of other visual effects such as night vision, film grain effects, depth of field effects, lens (i.e. fisheye) distortion — all in real time.&lt;br /&gt;
&lt;br /&gt;
For the full change log, please see [[Changelog 2.8.0]].&lt;br /&gt;
&lt;br /&gt;
Enjoy!!!&lt;br /&gt;
&lt;br /&gt;
== Development news ==&lt;br /&gt;
A view of FlightGear core and fgdata activity in [[Git]] since the 2.6.0 release. Each committer on fg and fg-data is shown here, as well as the part of fg where he's been working on. A big thank to all involved for making FG such a nice fireworks!&lt;br /&gt;
{{#ev:youtube|ibO6ruzQ5gM}} {{#ev:youtube|U0Dsgx9-Pbk}}&lt;br /&gt;
&lt;br /&gt;
=== Project Rembrandt ===&lt;br /&gt;
Fred's been working on some fancy new effects, especially useful for our film-making enthusiasts.&lt;br /&gt;
&lt;br /&gt;
The [[Project Rembrandt|Rembrandt renderer]] has a lot of potentiality when it comes to post processing effects. Indeed, the interesting property of a deferred shader is that all stages of rendering are kept into memory. Post-processing is as simple as using a filter on a camera.&lt;br /&gt;
&lt;br /&gt;
So currently the effects added in git are :&lt;br /&gt;
* Night vision including amplification grain and restrained field of view,&lt;br /&gt;
* Cinema effect including :&lt;br /&gt;
** Vignetting,&lt;br /&gt;
** Color shift, with Sepia as default value,&lt;br /&gt;
** Radial distortion (barrel and pincushion distortion, with scale compensation),&lt;br /&gt;
** Lateral chromatic aberration (purple fringing),&lt;br /&gt;
** Film wear simulation.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:Fgfs-rembrandt-old-timer.jpg|thumb|400px|Rembrandt old film style]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-distortion.jpg|thumb|400px|Rembrandt ordinary lens simulation]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-night-vision-2.png|thumb|400px|Rembrandt night vision simulation]]&lt;br /&gt;
|}&lt;br /&gt;
This won't make it for the 2.8 release but it's likely that an add-on will be available as it is contained in the data.&lt;br /&gt;
&lt;br /&gt;
See also :&lt;br /&gt;
{|&lt;br /&gt;
| {{#ev:youtube|tLZzlLjvDRQ}}&lt;br /&gt;
| {{#ev:youtube|_Dm-Xx5tfiE}}&lt;br /&gt;
| {{#ev:youtube|8jBvVyiq-D0}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Unified Weather GUI ===&lt;br /&gt;
As most readers will be aware, FG supports two weather models - Basic Weather which represents METAR data directly, and Local Weather which  models weather more realistically, with more variation.  In 2.8.0 these were configured separately using different UIs.  Stuart Buchanan and Thorsten Renk have been working on unifying the user interfaces to provide a more user-friendly and consistent interface.  This work is now available in git.&lt;br /&gt;
&lt;br /&gt;
=== Joystick Configuration GUI ===&lt;br /&gt;
&lt;br /&gt;
[[File:Joystick Configuration Dialog.jpg|thumb|The new Joystick Configuration Dialog, available in git.]]&lt;br /&gt;
&lt;br /&gt;
A further usability enhancement has been made by Stuart Buchanan to allow configuration of joysticks through a GUI in-sim.  Instead of configuring a joystick using XML, users can now change joystick bindings within the simulator - no XML knowledge required.  The updated joystick configuration takes effect immediately.  This work is also available in git, and should make it much easier for new users (or those with joysticks unknown to FG) to get flying.&lt;br /&gt;
&lt;br /&gt;
=== Canvas News ===&lt;br /&gt;
&amp;lt;!--additions should also be added to:http://wiki.flightgear.org/Changelog_3.0.0#Some_of_the_major_changes_include: --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of 08/2012, the new [[Canvas]] 2D drawing system in FlightGear HEAD has now also support for:&lt;br /&gt;
* using raster images (vector images were already supported previously)&lt;br /&gt;
* nested canvases, where a canvas may contain images created by another canvas texture [[Howto:Using raster images and nested canvases]]&lt;br /&gt;
* creating GUI windows (not just widgets)&lt;br /&gt;
* handling GUI events using osgGA&lt;br /&gt;
* multiplatfom copy/paste support using two new Nasal functions: [[Howto:Clipboard access using Nasal]]&lt;br /&gt;
&lt;br /&gt;
Support for nested canvases will make it possible to also load canvas textures into other canvases, so that you can, for example, easily load an instrument into a GUI dialog, or even use GUI widgets in MFD instruments, which is a feature based on real avionics, i.e. as used in modern airliners like the A320 or the 787.&lt;br /&gt;
&lt;br /&gt;
Nested canvases also make it possible for people to easily implement GUI tools using the Canvas system, for example a GUI instrument or panel editor can be entirely implemented in scripting space now, without touching any C++ code. Similarly, GUI widgets could also be created in a WYSIWYG-fashion, too - so that even dialog editor or full GUI builders can be built using the Canvas system.&lt;br /&gt;
&lt;br /&gt;
In addition, Tom has now implemented support for window stacking. Check out the demo video below, which demonstrates how &amp;quot;nested&amp;quot; canvases and window stacking works:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|llVaasTEf44}}&lt;br /&gt;
&lt;br /&gt;
Also, Tom is currently working on an improved event handling system with support for event-propagation based on the Javascript/DOM model. The event handling systems requires close interaction between the core system and Nasal code. Event propagation and bubbling will be supported like in the W3C DOM standard. We need eg. to be able to mark an event as handled and maybe also other things which change the behavior of the propagation.&lt;br /&gt;
&lt;br /&gt;
In addition, Tom has started work on some building blocks to provide basic inheritance support for canvas properties, so that styling (CSS/XSL) will be much easier.&lt;br /&gt;
&lt;br /&gt;
Missing features, and features currently under development, are listed at [[Canvas Widgets#Missing_.2F_Todo|Missing Canvas Features]]&lt;br /&gt;
&lt;br /&gt;
=== FlightGear Run-Levels ===&lt;br /&gt;
&lt;br /&gt;
Recently, there was talk on the FlightGear developers mailing about implementing a standalone [[FGCanvas]] client, analogous to [[FGPanel]] - in order to be able to render [[Canvas]] instruments separately, in different processes and also on different computers.&lt;br /&gt;
&lt;br /&gt;
However, obviously this new startup mode would not need many of the default subsystems, such as the FDM, sound, terrain etc. This requirement is shared with the [[Flightgear On Android]] project. But, many of these default subsystems are initialized in a hard coded fashion so that they cannot currently be made optional even though they may not be stricly required. &lt;br /&gt;
Also, for a very long time, it's never been possible to fully reset FlightGear properly, this makes many things very difficult or even impossible, including the [[FGCanvas]] idea.&lt;br /&gt;
&lt;br /&gt;
Hooray and TheTom have now started collecting ideas on how this could be changed, by making subsystem initialization more explicit using listeners, so that SGSubsystems can be dynamically allocated and freed based on setting signal properties, so that recursive run levels can be implemented. For more information, please see [[FlightGear Run Levels]]. Feedback welcome!&lt;br /&gt;
&lt;br /&gt;
=== Mailing list digest ===&lt;br /&gt;
&lt;br /&gt;
(by far the easiest option to populate the newsletter with contents is copying/pasting stuff from the forum and the mailing list or the git logs)&lt;br /&gt;
&lt;br /&gt;
=== Forum digest ===&lt;br /&gt;
&lt;br /&gt;
=== '''Flightgear On Android''' ===&lt;br /&gt;
&lt;br /&gt;
A new developer has achieved a way to run Flightgear on Android phones.    [[File:Flightgear Android Launcher.png|thumb|FOA]] &lt;br /&gt;
&lt;br /&gt;
The project codename will be FOA;he has done a lot of Android and C++ coding.          				   [[File:FOA.jpg|thumb|FOA ingame]] &lt;br /&gt;
&lt;br /&gt;
His phone is a Samsung Galaxy Nexus and is running Android 4.04 (custom ROM but stock ROM should be OK). If your ready to test with us, please read the technical info then send a email to lacbrc@gmail.com!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TECHNICAL INFO:&lt;br /&gt;
It should have at least a 1GHz processor and decent graphics chip. Android 2.3 is a          &lt;br /&gt;
must but a rooted device is not needed but can improve performance.&lt;br /&gt;
Not much in this, as we haven't finished it to a release yet. &lt;br /&gt;
He tested it on a bluetooth keyboard and a wired one through usb host mode. Hope you are interested in it!&lt;br /&gt;
&lt;br /&gt;
The first ALPHA release is fresh out of its release, and you can read more here:&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&amp;amp;p=163745#p163745&lt;br /&gt;
&lt;br /&gt;
The FlightGear for Android Team&lt;br /&gt;
&lt;br /&gt;
Here is a few links:&lt;br /&gt;
&lt;br /&gt;
Forums:&lt;br /&gt;
&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&lt;br /&gt;
&lt;br /&gt;
Website page:&lt;br /&gt;
&lt;br /&gt;
http://horizonflightgearhangar.yolasite.com/fg-on-android.php&lt;br /&gt;
&lt;br /&gt;
Wiki page:&lt;br /&gt;
&lt;br /&gt;
http://wiki.flightgear.org/Flightgear_On_Android&lt;br /&gt;
&lt;br /&gt;
=== Git digest ===&lt;br /&gt;
&lt;br /&gt;
=== Getting involved as a programmer ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Howto:Start core development]]&lt;br /&gt;
&lt;br /&gt;
=== Translators required ===&lt;br /&gt;
{|&lt;br /&gt;
|[[File:en.gif]]&lt;br /&gt;
|The FlightGear Wiki still needs help for translating it into various languages. If you are interested in making the FlightGear Wiki multi-language then start at [[Help:Translate]].&lt;br /&gt;
|-&lt;br /&gt;
|[[File:de.gif]]&lt;br /&gt;
|Das FlightGear Wiki benötigt immer noch Hilfe bei der Übersetzung in verschiedene Sprachen. Wenn Du Interesse daran hast, das FlightGear Wiki Mehrsprachig zu machen, dann fang doch mit [[:de:Help:Übersetzen|Help:Übersetzen]] an.&lt;br /&gt;
|-&lt;br /&gt;
|[[File:nl.gif]]&lt;br /&gt;
|De FlightGear Wiki kan nog steed hulp gebruiken bij het vertalen van artikelen. Als je interesse hebt om de wiki meertalig te maken, raden we je aan om een kijkje te nemen bij [[:nl:Help:Vertalen|Help:Vertalen]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Interview with a contributor (NAME) ==&lt;br /&gt;
''In each edition we have an interview with a contributor. Suggestions for possible questions are available on [[interview questions]], you are invited to come up with new questions and interview ideas obviously! Anyone is free to write an interview (with him-/herself or others) for next month's newsletter! If you'd like to help interview a contributor or get interviewed, please do consider adding yourself to the [[list of interview volunteers]]! To keep this going and less awkward, we are currently trying to come up with the convention that former interviewees become next month's interviewers.''&lt;br /&gt;
&lt;br /&gt;
* How long have you been involved in FlightGear?&lt;br /&gt;
* What are your major interests in FlightGear?&lt;br /&gt;
* What project are you working on right now?&lt;br /&gt;
* What do you plan on doing in the future?&lt;br /&gt;
* Are you happy with the way the FlightGear project is going?&lt;br /&gt;
* What do you enjoy most about developing for FlightGear?&lt;br /&gt;
* Are there any &amp;quot;hidden features&amp;quot; you have worked on in FlightGear that new users may miss?&lt;br /&gt;
* What advice can you give to new developers who want to get started on their first aircraft/new feature/Nasal script?&lt;br /&gt;
&lt;br /&gt;
More questions are being collected here: [[Interview questions]].&lt;br /&gt;
&lt;br /&gt;
Stay tuned for next month's interview, featuring FlightGear contributor XXXXXXXX&lt;br /&gt;
&lt;br /&gt;
== Snapshot releases ==&lt;br /&gt;
Every now and then, easy-to-install development snapshots are created (usually, twice montlhy). These snapshos depict a recent state of the development version of FlightGear. By using them users can test out features that will be included in the upcoming release. Testers are encouraged to file bugs at [http://code.google.com/p/flightgear-bugs/ the issue tracker].&lt;br /&gt;
&lt;br /&gt;
The snapshot can be download via the links at the bottom of this page: http://www.flightgear.org/download/. Updates and feedback can be found [http://flightgear.org/forums/viewtopic.php?f=28&amp;amp;t=10488&amp;amp;p=144233&amp;amp;hilit=snapshot#p144233 at the forum].&lt;br /&gt;
&lt;br /&gt;
== Nasal for newbies ==&lt;br /&gt;
&lt;br /&gt;
== New software tools and projects ==&lt;br /&gt;
&lt;br /&gt;
== FlightGear addons and mods ==&lt;br /&gt;
&lt;br /&gt;
== In the hangar ==&lt;br /&gt;
&lt;br /&gt;
All the way back in May 2011, we addopted a new status-rating system for aircraft. So far, only a few have actually been rated, as can be seen in the list 'hockenberry' set up at [https://docs.google.com/spreadsheet/ccc?key=0ApzphjA4w05ndF94Y2F0bzJTbHQ5QTJXZXJRcUVRbWc&amp;amp;hl=en_US Google Docs]. If you're an aircraft developer and your aircraft is/are not on the list, please consider rating their status. All you'll need to know/do is described at [[Formalizing Aircraft Status]]. If you'd just like to get started contributing to FlightGear, this would also seem like an excellent way to get started.&lt;br /&gt;
&lt;br /&gt;
=== New hangers ===&lt;br /&gt;
&lt;br /&gt;
=== New aircraft ===&lt;br /&gt;
&lt;br /&gt;
At the request by a new user of FG, Helijah has created and made available the Yakovlev Yak 18T in his hangar and GIT.&lt;br /&gt;
[[File:Yak18t-splash.png|thumb|Yakovlev Yak 18T]]&lt;br /&gt;
&lt;br /&gt;
=== Updated aircraft ===&lt;br /&gt;
&lt;br /&gt;
==== [[ATC-FS]] ====&lt;br /&gt;
The Air Traffic Control tool ATC-FS got an update. The old radar screen was replaced by a radar screen, which can display fixes, navaids and ILS localizers. This new radar is resizable, so you can use your big screen more efficient. &lt;br /&gt;
&lt;br /&gt;
The next version is already being worked on, it will reimplement ATC-FS using the new [[Canvas]] system (scheduled for FG 3.0) so that a fully custom drawn radar screen can be created in scripting space, including custom GUI widgets (e.g. for flight strips) - without depending on any hard coded instruments or dialogs any longer.&lt;br /&gt;
&lt;br /&gt;
This new design will eventually even make it possible to reuse ATC-FS for other purposes, or even include it in an AWACS aircraft that is multiplayer-enabled.&lt;br /&gt;
&lt;br /&gt;
[[Image:ATC-FS.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
==== [[Mil_Mi6]] ====&lt;br /&gt;
The big old russian helicopter Mi-6 from the Mil design bureau has received a new update. More than a year after the last update a new structure of the Models-subfolder allows new instruments to be added much easier. Also the electrical system has been revisited and new instruments have beed added to the engineer panels. Please keep in mind that this still is a very early development version and therefore a lot of work still needs to be done. It is available from its [https://gitorious.org/mil-mi-6 gitorious-page.]&lt;br /&gt;
&lt;br /&gt;
=== Liveries ===&lt;br /&gt;
&lt;br /&gt;
== Scenery corner ==&lt;br /&gt;
=== 3D models import webform ===&lt;br /&gt;
The webform to import 3D models directly into the DB is in production. Now you can use this tool to send your models to the database used by Terrasync. If everything is fine and your model respects the specifications written in the foreword, then it will quickly be shipped to all FG users worldwide through [[Terrasync]]. Yet another unique feature amongst the flight simulation world held by FlightGear. Thanks to Clément, Julien, Martin, for their help &amp;amp; support, and all of FG users who showed interest and support in those tools.&lt;br /&gt;
&lt;br /&gt;
Already 100 3D models have been imported with this form in Shanghai, Berlin, Stuttgart, France and in the UK! See the statistics [http://scenemodels.flightgear.org/stats.php here]. Thanks Gijs for the new nice layout.&lt;br /&gt;
&lt;br /&gt;
With all the forms now working on the scenemodels website, remember you can:&lt;br /&gt;
* add a single object (if you only have one!!). Check [http://scenemodels.flightgear.org/submission/index.php here]!&lt;br /&gt;
* update an object (for instance, a lot of power pylons are in fact communication pylones). It's [http://scenemodels.flightgear.org/submission/shared/index_update.php here]!&lt;br /&gt;
* delete an object (if it does not exist anymore in real life). It's [http://scenemodels.flightgear.org/submission/shared/index_delete.php here]!&lt;br /&gt;
* run a mass object positions import (if you added a lot of objets in one place). It's [http://scenemodels.flightgear.org/submission/shared/index_mass_import.php here]!&lt;br /&gt;
* add 3D models you created to have them imported into FG scenery via Terrasync. It's [http://scenemodels.flightgear.org/submission/static/index.php here]: they can be specific to a city (for instance: the Eiffel tower), that's what is called 'static' in the FG world, or 'shared' (a new windturbine model, for instance).&lt;br /&gt;
&lt;br /&gt;
Please read carefully the various forewords on the site:&lt;br /&gt;
* all data imported has to comply with the GNU/GPL license ;&lt;br /&gt;
* you must use the elevation format used by Terrasync to give your objects/models elevation, and [http://scenemodels.flightgear.org/contribute.php#offset an offset] if necessary, or they could be floating/sunk for most of users.&lt;br /&gt;
&lt;br /&gt;
We hope to see a lot of scenes not yet available via Terrasync merge into scenemodels. Nothing is now easier, especially when used in conjunction with our Mapserver!&lt;br /&gt;
Remember that this is the strength of FG compared to other sims: everything can be in Terrasync and no need to download patches or sceneries here and there.&lt;br /&gt;
&lt;br /&gt;
Moreover, an Ac3D viewer using Hangar by Juan Mellado is also available for general public for those whose browser supports WebGL (such as Firefox)!&lt;br /&gt;
&lt;br /&gt;
=== Scenemodels cleanup and update ===&lt;br /&gt;
A big cleanup has been done on our scenemodels database. A few thousands of duplicate objects have been removed (they were caused by mass insertion of navigation data, essentially). Nothing urgent but this makes the data in Terrasync lighter and more coherent. A script has also been launched to update the country associated with each object. While not perfect, now a lot more objects have a country!&lt;br /&gt;
&lt;br /&gt;
=== Airports ===&lt;br /&gt;
&lt;br /&gt;
== Aircraft of the month ==&lt;br /&gt;
== Airport of the month ==&lt;br /&gt;
== Screenshot of the month ==&lt;br /&gt;
&lt;br /&gt;
== Suggested flights ==&lt;br /&gt;
&lt;br /&gt;
The US state of Idaho is known for its remote airstrips in mountainous terrain. The [http://idahoaviation.com/idahoAirstripNetwork.php Idaho Airstrip Network] has details on many of them, including airstrip diagrams. &lt;br /&gt;
&lt;br /&gt;
At this time of year, it's important to take into account the temperature and altitude of the airstrips, as they combine to sap the power and lift from GA aircraft.  AVWeb recently [http://www.avweb.com/avwebflash/news/stinson_crash_cockpit_video_ntsb_faa_207184-1.html highlighted] the (non-fatal) crash of a [http://en.wikipedia.org/wiki/Stinson_108 Stinson 108], which included a video taken by one of the passengers. Though the NTSB has only produced a preliminary report, it was notable that the aircraft was taking off from a grass airstrip at high altitude on a hot day and appears from the video to struggle to get airborne.  The Stinson is broadly similar in performance to the c172p in our base package, and the airstrip (Bruce Meadows Airport, Idaho - U63) exists in our scenery.  Those interested can try taking off using the c172p with 4 people on board (2400lbs max gross weight) and high temperatures.  McCall Municipal Airport (KMYL) is 44nm away, and a good destination.&lt;br /&gt;
&lt;br /&gt;
== Aircraft reviews ==&lt;br /&gt;
&lt;br /&gt;
== Wiki updates ==&lt;br /&gt;
===New articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===New aircraft articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
  categoryRoot=Aircraft&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===Most popular newsletters===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=hot&lt;br /&gt;
  count=5&lt;br /&gt;
  categoryRoot=FlightGear Newsletter&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community news ==&lt;br /&gt;
=== FlightGear on YouTube ===&lt;br /&gt;
Lukea made a short promo for the release of FlightGear 2.8&lt;br /&gt;
{{#ev:youtube|X2Gq1l8A7iU}}&lt;br /&gt;
=== New tutorials and screencasts ===&lt;br /&gt;
{{#ev:youtube|VwYOFL9B2CE}}&lt;br /&gt;
{{#ev:youtube|wyfqeiHbosU}}&lt;br /&gt;
&lt;br /&gt;
=== Forum news ===&lt;br /&gt;
=== Multiplayer ===&lt;br /&gt;
=== Virtual airlines ===&lt;br /&gt;
=== FlightGear events ===&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
== And finally ... ==&lt;br /&gt;
=== Did you know? ===&lt;br /&gt;
Did you know that the FlightGear project dates back to a discussion among a group of net citizens in 1996 resulting in a proposal written by David Murr? The original proposal is still available&lt;br /&gt;
from the FlightGear website and can be found [http://www.flightgear.org/proposal-3.0.1 on the FlightGear website]. Read it, you'll learn a lot about FlightGears' roots which still lead the project spirit.&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
One of the regular thoughts expressed on the FlightGear forums is &amp;quot;I'd like to contribute but I don't know how to program, and I don't have the time&amp;quot;. Unfortunately, there is a common mis-conception that contributing requires programming and lots of free time. In fact, there are a huge range of ways to contribute to the project without needing to write code or spending days working on something. &lt;br /&gt;
&lt;br /&gt;
For ideas on starting to contribute to FlightGear, you may want to check out: [[Volunteer]].&lt;br /&gt;
&lt;br /&gt;
=== Call for volunteers ===&lt;br /&gt;
* The [http://horizonflightgearhangar.yolasite.com/fg-on-android.php FOA] Team is looking for testers.&lt;br /&gt;
* The [[Target4Today]] project is looking for volunteers to help improving FlightGear's combat support&lt;br /&gt;
* The [[OpenRadar]] project is looking for a new maintainer.&lt;br /&gt;
* The [[FGFSPM]] (FlightGear Package Manager) is looking for a new maintainer.&lt;br /&gt;
&lt;br /&gt;
=== Did you know ===&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear Newsletter|2012 08]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=53065</id>
		<title>FlightGear Newsletter August 2012</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=53065"/>
		<updated>2012-08-16T16:18:42Z</updated>

		<summary type="html">&lt;p&gt;Fredb: Avoid duplicated section about Rembrandt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{newsletter}}&lt;br /&gt;
{{TOC_right|limit=2}}&lt;br /&gt;
&lt;br /&gt;
''We would like to emphasize that the monthly newsletter can not live without the contributions of FlightGear users and developers. Everyone with a wiki account (free to register) can edit the newsletter and every contribution is welcome. So if you know about any FlightGear related news or projects such as for example updated scenery or aircraft, please do feel invited to add such news to the newsletter.''&lt;br /&gt;
&lt;br /&gt;
== Development news ==&lt;br /&gt;
A view of FlightGear core and fgdata activity in [[Git]] since the 2.6.0 release. A big thank to all involved for making FG such a nice fireworks!&lt;br /&gt;
{{#ev:youtube|ibO6ruzQ5gM}} {{#ev:youtube|U0Dsgx9-Pbk}}&lt;br /&gt;
&lt;br /&gt;
=== Project Rembrandt ===&lt;br /&gt;
Fred's been working on some fancy new effects, especially useful for our film-making enthusiasts.&lt;br /&gt;
&lt;br /&gt;
The [[Project Rembrandt|Rembrandt renderer]] has a lot of potentiality when it comes to post processing effects. Indeed, the interesting property of a deferred shader is that all stages of rendering are kept into memory. Post-processing is as simple as using a filter on a camera.&lt;br /&gt;
&lt;br /&gt;
So currently the effects added in git are :&lt;br /&gt;
* Night vision including amplification grain and restrained field of view,&lt;br /&gt;
* Cinema effect including :&lt;br /&gt;
** Vignetting,&lt;br /&gt;
** Color shift, with Sepia as default value,&lt;br /&gt;
** Radial distortion (barrel and pincushion distortion, with scale compensation),&lt;br /&gt;
** Lateral chromatic aberration (purple fringing),&lt;br /&gt;
** Film wear simulation.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:Fgfs-rembrandt-old-timer.jpg|thumb|400px|Rembrandt old film style]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-distortion.jpg|thumb|400px|Rembrandt ordinary lens simulation]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-night-vision-2.png|thumb|400px|Rembrandt night vision simulation]]&lt;br /&gt;
|}&lt;br /&gt;
This won't make it for the 2.8 release but it's likely that an add-on will be available as it is contained in the data.&lt;br /&gt;
&lt;br /&gt;
See also :&lt;br /&gt;
{|&lt;br /&gt;
| {{#ev:youtube|tLZzlLjvDRQ}}&lt;br /&gt;
| {{#ev:youtube|_Dm-Xx5tfiE}}&lt;br /&gt;
| {{#ev:youtube|8jBvVyiq-D0}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Unified Weather GUI ===&lt;br /&gt;
As most readers will be aware, FG supports two weather models - Basic Weather which represents METAR data directly, and Local Weather which  models weather more realistically, with more variation.  In 2.8.0 these were configured separately using different UIs.  Stuart Buchanan and Thorsten Renk have been working on unifying the user interfaces to provide a more user-friendly and consistent interface.  This work is now available in git.&lt;br /&gt;
&lt;br /&gt;
=== Canvas News ===&lt;br /&gt;
&amp;lt;!--additions should also be added to:http://wiki.flightgear.org/Changelog_3.0.0#Some_of_the_major_changes_include: --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of 08/2012, the new [[Canvas]] 2D drawing system in FlightGear HEAD has now also support for:&lt;br /&gt;
* using raster images (vector images were already supported previously)&lt;br /&gt;
* nested canvases, where a canvas may contain images created by another canvas texture [[Howto:Using raster images and nested canvases]]&lt;br /&gt;
* creating GUI windows (not just widgets)&lt;br /&gt;
* handling GUI events using osgGA&lt;br /&gt;
* multiplatfom copy/paste support using two new Nasal functions: [[Howto:Clipboard access using Nasal]]&lt;br /&gt;
&lt;br /&gt;
Support for nested canvases will make it possible to also load canvas textures into other canvases, so that you can, for example, easily load an instrument into a GUI dialog, or even use GUI widgets in MFD instruments, which is a feature based on real avionics, i.e. as used in modern airliners like the A320 or the 787.&lt;br /&gt;
&lt;br /&gt;
Nested canvases also make it possible for people to easily implement GUI tools using the Canvas system, for example a GUI instrument or panel editor can be entirely implemented in scripting space now, without touching any C++ code. Similarly, GUI widgets could also be created in a WYSIWYG-fashion, too - so that even dialog editor or full GUI builders can be built using the Canvas system.&lt;br /&gt;
&lt;br /&gt;
In addition, Tom has now implemented support for window stacking. Check out the demo video below, which demonstrates how &amp;quot;nested&amp;quot; canvases and window stacking works:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|llVaasTEf44}}&lt;br /&gt;
&lt;br /&gt;
Missing features, and features currently under development, are listed at [[Canvas Widgets#Missing_.2F_Todo|Missing Canvas Features]]&lt;br /&gt;
&lt;br /&gt;
=== Mailing list digest ===&lt;br /&gt;
&lt;br /&gt;
(by far the easiest option to populate the newsletter with contents is copying/pasting stuff from the forum and the mailing list or the git logs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Forum digest ===&lt;br /&gt;
&lt;br /&gt;
=== '''Flightgear On Android''' ===&lt;br /&gt;
&lt;br /&gt;
A new developer has achieved a way to run Flightgear on Android phones.    [[File:Flightgear Android Launcher.png|thumb|FOA]] &lt;br /&gt;
&lt;br /&gt;
The project codename will be FOA;he has done a lot of Android and C++ coding.          				   [[File:FOA.jpg|thumb|FOA ingame]] &lt;br /&gt;
&lt;br /&gt;
His phone is a Samsung Galaxy Nexus and is running Android 4.04 (custom ROM but stock ROM should be OK). If your ready to test with us, please read the technical info then send a email to lacbrc@gmail.com!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TECHNICAL INFO:&lt;br /&gt;
It should have at least a 1GHz processor and decent graphics chip. Android 2.3 is a          &lt;br /&gt;
must but a rooted device is not needed but can improve performance.&lt;br /&gt;
Not much in this, as we haven't finished it to a release yet. &lt;br /&gt;
He tested it on a bluetooth keyboard and a wired one through usb host mode. Hope you are interested in it!&lt;br /&gt;
&lt;br /&gt;
The first ALPHA release is fresh out of its release, and you can read more here:&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&amp;amp;p=163745#p163745&lt;br /&gt;
&lt;br /&gt;
The FlightGear for Android Team&lt;br /&gt;
&lt;br /&gt;
Here is a few links:&lt;br /&gt;
&lt;br /&gt;
Forums:&lt;br /&gt;
&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&lt;br /&gt;
&lt;br /&gt;
Website page:&lt;br /&gt;
&lt;br /&gt;
http://horizonflightgearhangar.yolasite.com/fg-on-android.php&lt;br /&gt;
&lt;br /&gt;
Wiki page:&lt;br /&gt;
&lt;br /&gt;
http://wiki.flightgear.org/Flightgear_On_Android&lt;br /&gt;
&lt;br /&gt;
=== Git digest ===&lt;br /&gt;
&lt;br /&gt;
=== Getting involved as a programmer ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Howto:Start core development]]&lt;br /&gt;
&lt;br /&gt;
== Interview with a contributor (NAME) ==&lt;br /&gt;
''In each edition we have an interview with a contributor. Suggestions for possible questions are available on [[interview questions]], you are invited to come up with new questions and interview ideas obviously! Anyone is free to write an interview (with him-/herself or others) for next month's newsletter! If you'd like to help interview a contributor or get interviewed, please do consider adding yourself to the [[list of interview volunteers]]! To keep this going and less awkward, we are currently trying to come up with the convention that former interviewees become next month's interviewers.''&lt;br /&gt;
&lt;br /&gt;
* How long have you been involved in FlightGear?&lt;br /&gt;
* What are your major interests in FlightGear?&lt;br /&gt;
* What project are you working on right now?&lt;br /&gt;
* What do you plan on doing in the future?&lt;br /&gt;
* Are you happy with the way the FlightGear project is going?&lt;br /&gt;
* What do you enjoy most about developing for FlightGear?&lt;br /&gt;
* Are there any &amp;quot;hidden features&amp;quot; you have worked on in FlightGear that new users may miss?&lt;br /&gt;
* What advice can you give to new developers who want to get started on their first aircraft/new feature/Nasal script?&lt;br /&gt;
&lt;br /&gt;
More questions are being collected here: [[Interview questions]].&lt;br /&gt;
&lt;br /&gt;
Stay tuned for next month's interview, featuring FlightGear contributor XXXXXXXX &lt;br /&gt;
&lt;br /&gt;
== Snapshot releases ==&lt;br /&gt;
Every now and then, easy-to-install development snapshots are created (usually, twice montlhy). These snapshos depict a recent state of the development version of FlightGear. By using them users can test out features that will be included in the upcoming release. Testers are encouraged to file bugs at [http://code.google.com/p/flightgear-bugs/ the issue tracker].&lt;br /&gt;
&lt;br /&gt;
The snapshot can be download via the links at the bottom of this page: http://www.flightgear.org/download/. Updates and feedback can be found [http://flightgear.org/forums/viewtopic.php?f=28&amp;amp;t=10488&amp;amp;p=144233&amp;amp;hilit=snapshot#p144233 at the forum].&lt;br /&gt;
&lt;br /&gt;
== Nasal for newbies ==&lt;br /&gt;
&lt;br /&gt;
== New software tools and projects ==&lt;br /&gt;
&lt;br /&gt;
== FlightGear addons and mods ==&lt;br /&gt;
&lt;br /&gt;
== In the hangar ==&lt;br /&gt;
&lt;br /&gt;
All the way back in May 2011, we addopted a new status-rating system for aircraft. So far, only a few have actually been rated, as can be seen in the list 'hockenberry' set up at [https://docs.google.com/spreadsheet/ccc?key=0ApzphjA4w05ndF94Y2F0bzJTbHQ5QTJXZXJRcUVRbWc&amp;amp;hl=en_US Google Docs]. If you're an aircraft developer and your aircraft is/are not on the list, please consider rating their status. All you'll need to know/do is described at [[Formalizing Aircraft Status]]. If you'd just like to get started contributing to FlightGear, this would also seem like an excellent way to get started.&lt;br /&gt;
&lt;br /&gt;
=== New hangers ===&lt;br /&gt;
&lt;br /&gt;
=== New aircraft ===&lt;br /&gt;
&lt;br /&gt;
At the request by a new user of FG, Helijah has created and made available the Yakovlev Yak 18T in his hangar and GIT.&lt;br /&gt;
[[File:Yak18t-splash.png|thumb|Yakovlev Yak 18T]]&lt;br /&gt;
&lt;br /&gt;
=== Updated aircraft ===&lt;br /&gt;
&lt;br /&gt;
==== [[ATC-FS]] ====&lt;br /&gt;
The Air Traffic Control tool ATC-FS got an update. The old radar screen was replaced by a radar screen, which can display fixes, navaids and ILS localizers. This new radar is resizable, so you can use your big screen more efficient. &lt;br /&gt;
&lt;br /&gt;
The next version is already being worked on, it will reimplement ATC-FS using the new [[Canvas]] system (scheduled for FG 3.0) so that a fully custom drawn radar screen can be created in scripting space, including custom GUI widgets (e.g. for flight strips) - without depending on any hard coded instruments or dialogs any longer.&lt;br /&gt;
&lt;br /&gt;
This new design will eventually even make it possible to reuse ATC-FS for other purposes, or even include it in an AWACS aircraft that is multiplayer-enabled.&lt;br /&gt;
&lt;br /&gt;
[[Image:ATC-FS.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
==== [[Mil_Mi6]] ====&lt;br /&gt;
The big old russian helicopter Mi-6 from the Mil design bureau has received a new update. More than a year after the last update a new structure of the Models-subfolder allows new instruments to be added much easier. Also the electrical system has been revisited and new instruments have beed added to the engineer panels. Please keep in mind that this still is a very early development version and therefore a lot of work still needs to be done. It is available from its [https://gitorious.org/mil-mi-6 gitorious-page.]&lt;br /&gt;
&lt;br /&gt;
=== Liveries ===&lt;br /&gt;
&lt;br /&gt;
== Scenery corner ==&lt;br /&gt;
=== 3D models import webform ===&lt;br /&gt;
The webform to import 3D models directly into the DB is in production. Now you can use this tool to send your models to the database used by Terrasync. If everything is fine and your model respects the specifications written in the foreword, then it will quickly be shipped to all FG users worldwide through [[Terrasync]]. Yet another unique feature amongst the flight simulation world held by FlightGear. Thanks to Clément, Julien, Martin, for their help&amp;amp;support.&lt;br /&gt;
&lt;br /&gt;
With all the forms now working on the scenemodels website, remember you can:&lt;br /&gt;
* add a single object (if you only have one!!). Check here: http://scenemodels.flightgear.org/submission/index.php&lt;br /&gt;
* update an object (for instance, a lot of power pylons are in fact communication pylones). It's here: http://scenemodels.flightgear.org/submission/shared/index_update.php&lt;br /&gt;
* delete an object (if it does not exist anymore in real life). It's here: http://scenemodels.flightgear.org/submission/shared/index_delete.php&lt;br /&gt;
* run a mass object positions import (if you added a lot of objets in one place). It's here: http://scenemodels.flightgear.org/submission/shared/index_mass_import.php&lt;br /&gt;
* add 3D models you created to have them imported into FG scenery via Terrasync. It's here: http://scenemodels.flightgear.org/submission/static/index.php They can be specific to a city (for instance : the Eiffel tower), or shared (a new windturbine model, for instance).&lt;br /&gt;
&lt;br /&gt;
Please read carefully the various forewords on the site:&lt;br /&gt;
* all data imported has to comply with the GNU/GPL license ;&lt;br /&gt;
* you must use the elevation format used by Terrasync to give your objects/models elevation, or they could be floating/sunk for most of users.&lt;br /&gt;
&lt;br /&gt;
We hope to see a lot of scenes not yet available via Terrasync merge into scenemodels. Nothing is now easier, especially when used in conjunction with our Mapserver!&lt;br /&gt;
Remember that this is the strength of FG compared to other sims: everything can be in Terrasync and no need to download patches or sceneries here and there.&lt;br /&gt;
&lt;br /&gt;
=== Scenemodels cleanup and update ===&lt;br /&gt;
A big cleanup has been done on our scenemodels database. A few thousands of duplicate objects have been removed (they were caused by mass insertion of navigation data, essentially). Nothing urgent but this makes the data in Terrasync lighter and more coherent. A script has also been launched to update the country associated with each object. While not perfect, now a lot more objects have a country!&lt;br /&gt;
&lt;br /&gt;
=== Airports ===&lt;br /&gt;
&lt;br /&gt;
== Aircraft of the month ==&lt;br /&gt;
== Airport of the month ==&lt;br /&gt;
== Screenshot of the month ==&lt;br /&gt;
&lt;br /&gt;
== Suggested flights ==&lt;br /&gt;
&lt;br /&gt;
The US state of Idaho is known for its remote airstrips in mountainous terrain. The [http://idahoaviation.com/idahoAirstripNetwork.php Idaho Airstrip Network] has details on many of them, including airstrip diagrams. &lt;br /&gt;
&lt;br /&gt;
At this time of year, it's important to take into account the temperature and altitude of the airstrips, as they combine to sap the power and lift from GA aircraft.  AVWeb recently [http://www.avweb.com/avwebflash/news/stinson_crash_cockpit_video_ntsb_faa_207184-1.html highlighted] the (non-fatal) crash of a [http://en.wikipedia.org/wiki/Stinson_108 Stinson 108], which included a video taken by one of the passengers. Though the NTSB has only produced a preliminary report, it was notable that the aircraft was taking off from a grass airstrip at high altitude on a hot day and appears from the video to struggle to get airborne.  The Stinson is broadly similar in performance to the c172p in our base package, and the airstrip (Bruce Meadows Airport, Idaho - U63) exists in our scenery.  Those interested can try taking off using the c172p with 4 people on board (2400lbs max gross weight) and high temperatures.  McCall Municipal Airport (KMYL) is 44nm away, and a good destination.&lt;br /&gt;
&lt;br /&gt;
== Aircraft reviews ==&lt;br /&gt;
&lt;br /&gt;
== Wiki updates ==&lt;br /&gt;
===New articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===New aircraft articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
  categoryRoot=Aircraft&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===Most popular newsletters===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=hot&lt;br /&gt;
  count=5&lt;br /&gt;
  categoryRoot=FlightGear Newsletter&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community news ==&lt;br /&gt;
=== FlightGear on YouTube ===&lt;br /&gt;
&lt;br /&gt;
=== New tutorials and screencasts ===&lt;br /&gt;
=== Forum news ===&lt;br /&gt;
=== Multiplayer ===&lt;br /&gt;
=== Virtual airlines ===&lt;br /&gt;
=== FlightGear events ===&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
== And finally ... ==&lt;br /&gt;
=== Did you know? ===&lt;br /&gt;
Did you know that the FlightGear project dates back to a discussion among a group of net citizens in 1996 resulting in a proposal written by David Murr? The original proposal is still available&lt;br /&gt;
from the FlightGear website and can be found [http://www.flightgear.org/proposal-3.0.1 on the FlightGear website]. Read it, you'll learn a lot about FlightGears' roots which still lead the project spirit.&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
One of the regular thoughts expressed on the FlightGear forums is &amp;quot;I'd like to contribute but I don't know how to program, and I don't have the time&amp;quot;. Unfortunately, there is a common mis-conception that contributing requires programming and lots of free time. In fact, there are a huge range of ways to contribute to the project without needing to write code or spending days working on something. &lt;br /&gt;
&lt;br /&gt;
For ideas on starting to contribute to FlightGear, you may want to check out: [[Volunteer]].&lt;br /&gt;
&lt;br /&gt;
=== Call for volunteers ===&lt;br /&gt;
* The [http://horizonflightgearhangar.yolasite.com/fg-on-android.php FOA] Team is looking for testers.&lt;br /&gt;
* The [[Target4Today]] project is looking for volunteers to help improving FlightGear's combat support&lt;br /&gt;
* The [[OpenRadar]] project is looking for a new maintainer.&lt;br /&gt;
* The [[FGFSPM]] (FlightGear Package Manager) is looking for a new maintainer.&lt;br /&gt;
&lt;br /&gt;
=== Did you know ===&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear Newsletter|2012 08]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=52974</id>
		<title>FlightGear Newsletter August 2012</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=52974"/>
		<updated>2012-08-15T17:05:15Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Project Rembrandt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{newsletter}}&lt;br /&gt;
{{TOC_right|limit=2}}&lt;br /&gt;
&lt;br /&gt;
''We would like to emphasize that the monthly newsletter can not live without the contributions of FlightGear users and developers. Everyone with a wiki account (free to register) can edit the newsletter and every contribution is welcome. So if you know about any FlightGear related news or projects such as for example updated scenery or aircraft, please do feel invited to add such news to the newsletter.''&lt;br /&gt;
&lt;br /&gt;
== Development news ==&lt;br /&gt;
&lt;br /&gt;
=== Project Rembrandt ===&lt;br /&gt;
Fred's been working on some fancy new effects, especially useful for our film-making enthusiasts:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|tLZzlLjvDRQ}}&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|_Dm-Xx5tfiE}}&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|8jBvVyiq-D0}}&lt;br /&gt;
&lt;br /&gt;
=== Unified Weather GUI ===&lt;br /&gt;
As most readers will be aware, FG supports two weather models - Basic Weather which represents METAR data directly, and Local Weather which  models weather more realistically, with more variation.  In 2.8.0 these were configured separately using different UIs.  Stuart Buchanan and Thorsten Renk have been working on unifying the user interfaces to provide a more user-friendly and consistent interface.  This work is now available in git.&lt;br /&gt;
&lt;br /&gt;
=== Canvas News ===&lt;br /&gt;
&amp;lt;!--additions should also be added to:http://wiki.flightgear.org/Changelog_3.0.0#Some_of_the_major_changes_include: --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of 08/2012, the new [[Canvas]] 2D drawing system in FlightGear HEAD has now also support for:&lt;br /&gt;
* using raster images (vector images were already supported previously)&lt;br /&gt;
* nested canvases, where a canvas may contain images created by another canvas texture&lt;br /&gt;
* creating GUI windows (not just widgets)&lt;br /&gt;
* handling GUI events using osgGA&lt;br /&gt;
* multiplatfom copy/paste support using two new Nasal functions: [[Howto:Clipboard access using Nasal]]&lt;br /&gt;
&lt;br /&gt;
Support for nested canvases will make it possible to also load canvas textures into other canvases, so that you can, for example, easily load an instrument into a GUI dialog, or even use GUI widgets in MFD instruments, which is a feature based on real avionics, i.e. as used in modern airliners like the A320 or the 787.&lt;br /&gt;
&lt;br /&gt;
Nested canvases also make it possible for people to easily implement GUI tools using the Canvas system, for example a GUI instrument or panel editor can be entirely implemented in scripting space now, without touching any C++ code. Similarly, GUI widgets could also be created in a WYSIWYG-fashion, too - so that even dialog editor or full GUI builders can be built using the Canvas system.&lt;br /&gt;
&lt;br /&gt;
In addition, Tom has now implemented support for window stacking. Check out the demo video below, which demonstrates how &amp;quot;nested&amp;quot; canvases and window stacking works:&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|llVaasTEf44}}&lt;br /&gt;
&lt;br /&gt;
Missing features, and features currently under development, are listed at [[Canvas Widgets#Missing_.2F_Todo|Missing Canvas Features]]&lt;br /&gt;
&lt;br /&gt;
=== Mailing list digest ===&lt;br /&gt;
&lt;br /&gt;
(by far the easiest option to populate the newsletter with contents is copying/pasting stuff from the forum and the mailing list or the git logs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Forum digest ===&lt;br /&gt;
&lt;br /&gt;
=== '''Flightgear On Android''' ===&lt;br /&gt;
&lt;br /&gt;
A new developer has achieved a way to run Flightgear on Android phones.    [[File:Flightgear Android Launcher.png|thumb|FOA]] &lt;br /&gt;
&lt;br /&gt;
The project codename will be FOA;he has done a lot of Android and C++ coding.          				   [[File:FOA.jpg|thumb|FOA ingame]] &lt;br /&gt;
&lt;br /&gt;
His phone is a Samsung Galaxy Nexus and is running Android 4.04 (custom ROM but stock ROM should be OK). If your ready to test with us, please read the technical info then send a email to lacbrc@gmail.com!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TECHNICAL INFO:&lt;br /&gt;
It should have at least a 1GHz processor and decent graphics chip. Android 2.3 is a          &lt;br /&gt;
must but a rooted device is not needed but can improve performance.&lt;br /&gt;
Not much in this, as we haven't finished it to a release yet. &lt;br /&gt;
He tested it on a bluetooth keyboard and a wired one through usb host mode. Hope you are interested in it!&lt;br /&gt;
&lt;br /&gt;
The first ALPHA release is fresh out of its release, and you can read more here:&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&amp;amp;p=163745#p163745&lt;br /&gt;
&lt;br /&gt;
The FlightGear for Android Team&lt;br /&gt;
&lt;br /&gt;
Here is a few links:&lt;br /&gt;
&lt;br /&gt;
Forums:&lt;br /&gt;
&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&lt;br /&gt;
&lt;br /&gt;
Website page:&lt;br /&gt;
&lt;br /&gt;
http://horizonflightgearhangar.yolasite.com/fg-on-android.php&lt;br /&gt;
&lt;br /&gt;
Wiki page:&lt;br /&gt;
&lt;br /&gt;
http://wiki.flightgear.org/Flightgear_On_Android&lt;br /&gt;
&lt;br /&gt;
=== New effects in Rembrandt ===&lt;br /&gt;
The [[Project Rembrandt|Rembrandt renderer]] has a lot of potentiality when it comes to post processing effects. Indeed, the interesting property of a deferred shader is that all stages of rendering are kept into memory. Post-processing is as simple as using a filter on a camera.&lt;br /&gt;
&lt;br /&gt;
So currently the effects added in git are :&lt;br /&gt;
* Night vision including amplification grain and restrained field of view,&lt;br /&gt;
* Cinema effect including :&lt;br /&gt;
** Vignetting,&lt;br /&gt;
** Color shift, with Sepia as default value,&lt;br /&gt;
** Radial distortion (barrel and pincushion distortion, with scale compensation),&lt;br /&gt;
** Lateral chromatic aberration (purple fringing),&lt;br /&gt;
** Film wear simulation.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:Fgfs-rembrandt-old-timer.jpg|thumb|400px|Rembrandt old film style]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-distortion.jpg|thumb|400px|Rembrandt ordinary lens simulation]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-night-vision-2.png|thumb|400px|Rembrandt night vision simulation]]&lt;br /&gt;
|}&lt;br /&gt;
This won't make it for the 2.8 release but it's likely that an add-on will be available as it is contained in the data.&lt;br /&gt;
&lt;br /&gt;
=== Git digest ===&lt;br /&gt;
&lt;br /&gt;
=== Getting involved as a programmer ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Howto:Start core development]]&lt;br /&gt;
&lt;br /&gt;
== Interview with a contributor (NAME) ==&lt;br /&gt;
''In each edition we have an interview with a contributor. Suggestions for possible questions are available on [[interview questions]], you are invited to come up with new questions and interview ideas obviously! Anyone is free to write an interview (with him-/herself or others) for next month's newsletter! If you'd like to help interview a contributor or get interviewed, please do consider adding yourself to the [[list of interview volunteers]]! To keep this going and less awkward, we are currently trying to come up with the convention that former interviewees become next month's interviewers.''&lt;br /&gt;
&lt;br /&gt;
* How long have you been involved in FlightGear?&lt;br /&gt;
* What are your major interests in FlightGear?&lt;br /&gt;
* What project are you working on right now?&lt;br /&gt;
* What do you plan on doing in the future?&lt;br /&gt;
* Are you happy with the way the FlightGear project is going?&lt;br /&gt;
* What do you enjoy most about developing for FlightGear?&lt;br /&gt;
* Are there any &amp;quot;hidden features&amp;quot; you have worked on in FlightGear that new users may miss?&lt;br /&gt;
* What advice can you give to new developers who want to get started on their first aircraft/new feature/Nasal script?&lt;br /&gt;
&lt;br /&gt;
More questions are being collected here: [[Interview questions]].&lt;br /&gt;
&lt;br /&gt;
Stay tuned for next month's interview, featuring FlightGear contributor XXXXXXXX &lt;br /&gt;
&lt;br /&gt;
== Snapshot releases ==&lt;br /&gt;
Every now and then, easy-to-install development snapshots are created (usually, twice montlhy). These snapshos depict a recent state of the development version of FlightGear. By using them users can test out features that will be included in the upcoming release. Testers are encouraged to file bugs at [http://code.google.com/p/flightgear-bugs/ the issue tracker].&lt;br /&gt;
&lt;br /&gt;
The snapshot can be download via the links at the bottom of this page: http://www.flightgear.org/download/. Updates and feedback can be found [http://flightgear.org/forums/viewtopic.php?f=28&amp;amp;t=10488&amp;amp;p=144233&amp;amp;hilit=snapshot#p144233 at the forum].&lt;br /&gt;
&lt;br /&gt;
== Nasal for newbies ==&lt;br /&gt;
&lt;br /&gt;
== New software tools and projects ==&lt;br /&gt;
&lt;br /&gt;
== FlightGear addons and mods ==&lt;br /&gt;
&lt;br /&gt;
== In the hangar ==&lt;br /&gt;
&lt;br /&gt;
All the way back in May 2011, we addopted a new status-rating system for aircraft. So far, only a few have actually been rated, as can be seen in the list 'hockenberry' set up at [https://docs.google.com/spreadsheet/ccc?key=0ApzphjA4w05ndF94Y2F0bzJTbHQ5QTJXZXJRcUVRbWc&amp;amp;hl=en_US Google Docs]. If you're an aircraft developer and your aircraft is/are not on the list, please consider rating their status. All you'll need to know/do is described at [[Formalizing Aircraft Status]]. If you'd just like to get started contributing to FlightGear, this would also seem like an excellent way to get started.&lt;br /&gt;
&lt;br /&gt;
=== New hangers ===&lt;br /&gt;
&lt;br /&gt;
=== New aircraft ===&lt;br /&gt;
&lt;br /&gt;
At the request by a new user of FG, Helijah has created and made available the Yakovlev Yak 18T in his hangar and GIT.&lt;br /&gt;
[[File:Yak18t-splash.png|thumb|Yakovlev Yak 18T]]&lt;br /&gt;
&lt;br /&gt;
=== Updated aircraft ===&lt;br /&gt;
&lt;br /&gt;
==== [[ATC-FS]] ====&lt;br /&gt;
The Air Traffic Control tool ATC-FS got an update. The old radar screen was replaced by a radar screen, which can display fixes, navaids and ILS localizers. This new radar is resizable, so you can use your big screen more efficient. &lt;br /&gt;
&lt;br /&gt;
The next version is already being worked on, it will reimplement ATC-FS using the new [[Canvas]] system (scheduled for FG 3.0) so that a fully custom drawn radar screen can be created in scripting space, including custom GUI widgets (e.g. for flight strips) - without depending on any hard coded instruments or dialogs any longer.&lt;br /&gt;
&lt;br /&gt;
This new design will eventually even make it possible to reuse ATC-FS for other purposes, or even include it in an AWACS aircraft that is multiplayer-enabled.&lt;br /&gt;
&lt;br /&gt;
[[Image:ATC-FS.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
==== [[Mil_Mi6]] ====&lt;br /&gt;
The big old russian helicopter Mi-6 from the Mil design bureau has received a new update. More than a year after the last update a new structure of the Models-subfolder allows new instruments to be added much easier. Also the electrical system has been revisited and new instruments have beed added to the engineer panels. Please keep in mind that this still is a very early development version and therefore a lot of work still needs to be done. It is available from its [https://gitorious.org/mil-mi-6 gitorious-page.]&lt;br /&gt;
&lt;br /&gt;
=== Liveries ===&lt;br /&gt;
&lt;br /&gt;
== Scenery corner ==&lt;br /&gt;
=== 3D models import webform ===&lt;br /&gt;
The webform to import 3D models directly into the DB is in production. Now you can use this tool to send your models to the database used by Terrasync. If everything is fine and your model respects the specifications written in the foreword, then it will quickly be shipped to all FG users worldwide through [[Terrasync]]. Yet another unique feature amongst the flight simulation world held by FlightGear. Thanks to Clément, Julien, Martin, for their help&amp;amp;support.&lt;br /&gt;
&lt;br /&gt;
With all the forms now working on the scenemodels website, remember you can:&lt;br /&gt;
* add a single object (if you only have one!!). Check here: http://scenemodels.flightgear.org/submission/index.php&lt;br /&gt;
* update an object (for instance, a lot of power pylons are in fact communication pylones). It's here: http://scenemodels.flightgear.org/submission/shared/index_update.php&lt;br /&gt;
* delete an object (if it does not exist anymore in real life). It's here: http://scenemodels.flightgear.org/submission/shared/index_delete.php&lt;br /&gt;
* run a mass object positions import (if you added a lot of objets in one place). It's here: http://scenemodels.flightgear.org/submission/shared/index_mass_import.php&lt;br /&gt;
* add 3D models you created to have them imported into FG scenery via Terrasync. It's here: http://scenemodels.flightgear.org/submission/static/index.php They can be specific to a city (for instance : the Eiffel tower), or shared (a new windturbine model, for instance).&lt;br /&gt;
&lt;br /&gt;
Please read carefully the various forewords on the site:&lt;br /&gt;
* all data imported has to comply with the GNU/GPL license ;&lt;br /&gt;
* you must use the elevation format used by Terrasync to give your objects/models elevation, or they could be floating/sunk for most of users.&lt;br /&gt;
&lt;br /&gt;
We hope to see a lot of scenes not yet available via Terrasync merge into scenemodels. Nothing is now easier, especially when used in conjunction with our Mapserver!&lt;br /&gt;
Remember that this is the strength of FG compared to other sims: everything can be in Terrasync and no need to download patches or sceneries here and there.&lt;br /&gt;
&lt;br /&gt;
=== Scenemodels cleanup and update ===&lt;br /&gt;
A big cleanup has been done on our scenemodels database. A few thousands of duplicate objects have been removed (they were caused by mass insertion of navigation data, essentially). Nothing urgent but this makes the data in Terrasync lighter and more coherent. A script has also been launched to update the country associated with each object. While not perfect, now a lot more objects have a country!&lt;br /&gt;
&lt;br /&gt;
=== Airports ===&lt;br /&gt;
&lt;br /&gt;
== Aircraft of the month ==&lt;br /&gt;
== Airport of the month ==&lt;br /&gt;
== Screenshot of the month ==&lt;br /&gt;
&lt;br /&gt;
== Suggested flights ==&lt;br /&gt;
&lt;br /&gt;
The US state of Idaho is known for its remote airstrips in mountainous terrain. The [http://idahoaviation.com/idahoAirstripNetwork.php Idaho Airstrip Network] has details on many of them, including airstrip diagrams. &lt;br /&gt;
&lt;br /&gt;
At this time of year, it's important to take into account the temperature and altitude of the airstrips, as they combine to sap the power and lift from GA aircraft.  AVWeb recently [http://www.avweb.com/avwebflash/news/stinson_crash_cockpit_video_ntsb_faa_207184-1.html highlighted] the (non-fatal) crash of a [http://en.wikipedia.org/wiki/Stinson_108 Stinson 108], which included a video taken by one of the passengers. Though the NTSB has only produced a preliminary report, it was notable that the aircraft was taking off from a grass airstrip at high altitude on a hot day and appears from the video to struggle to get airborne.  The Stinson is broadly similar in performance to the c172p in our base package, and the airstrip (Bruce Meadows Airport, Idaho - U63) exists in our scenery.  Those interested can try taking off using the c172p with 4 people on board (2400lbs max gross weight) and high temperatures.  McCall Municipal Airport (KMYL) is 44nm away, and a good destination.&lt;br /&gt;
&lt;br /&gt;
== Aircraft reviews ==&lt;br /&gt;
&lt;br /&gt;
== Wiki updates ==&lt;br /&gt;
===New articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===New aircraft articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
  categoryRoot=Aircraft&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===Most popular newsletters===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=hot&lt;br /&gt;
  count=5&lt;br /&gt;
  categoryRoot=FlightGear Newsletter&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community news ==&lt;br /&gt;
=== FlightGear on YouTube ===&lt;br /&gt;
&lt;br /&gt;
=== New tutorials and screencasts ===&lt;br /&gt;
=== Forum news ===&lt;br /&gt;
=== Multiplayer ===&lt;br /&gt;
=== Virtual airlines ===&lt;br /&gt;
=== FlightGear events ===&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
== And finally ... ==&lt;br /&gt;
=== Did you know? ===&lt;br /&gt;
Did you know that the FlightGear project dates back to a discussion among a group of net citizens in 1996 resulting in a proposal written by David Murr? The original proposal is still available&lt;br /&gt;
from the FlightGear website and can be found [http://www.flightgear.org/proposal-3.0.1 on the FlightGear website]. Read it, you'll learn a lot about FlightGears' roots which still lead the project spirit.&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
One of the regular thoughts expressed on the FlightGear forums is &amp;quot;I'd like to contribute but I don't know how to program, and I don't have the time&amp;quot;. Unfortunately, there is a common mis-conception that contributing requires programming and lots of free time. In fact, there are a huge range of ways to contribute to the project without needing to write code or spending days working on something. &lt;br /&gt;
&lt;br /&gt;
For ideas on starting to contribute to FlightGear, you may want to check out: [[Volunteer]].&lt;br /&gt;
&lt;br /&gt;
=== Call for volunteers ===&lt;br /&gt;
* The [http://horizonflightgearhangar.yolasite.com/fg-on-android.php FOA] Team is looking for testers.&lt;br /&gt;
* The [[OpenRadar]] project is looking for a new maintainer.&lt;br /&gt;
* The [[FGFSPM]] (FlightGear Package Manager) is looking for a new maintainer.&lt;br /&gt;
&lt;br /&gt;
=== Did you know ===&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear Newsletter|2012 08]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52959</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52959"/>
		<updated>2012-08-15T12:35:02Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Appendix */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Making sure that all geometry will cast shadow ===&lt;br /&gt;
&lt;br /&gt;
To limit the amount of geometry rendered in the shadow map, and also to reduce artifacts (shadow acne), only faces not facing the sun are casting shadows. The test is made using the normal orientation. That means that double-sided polygons, or mesh that are not closed, will be transparent to light at certain sun angles. To avoid that, modelers can either :&lt;br /&gt;
* ensure that the object is always in the shadow of another objects,&lt;br /&gt;
* close their mesh, or,&lt;br /&gt;
* double polygons with the normal set to the opposite.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
* {{cite web |url=http://publications.dice.se/publications.asp?show_category=yes&amp;amp;which_category=Rendering |author=DICE |title=Publications on rendering |accessdate=15 August 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52958</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52958"/>
		<updated>2012-08-15T12:30:16Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Making sure that all geometry will cast shadow */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Making sure that all geometry will cast shadow ===&lt;br /&gt;
&lt;br /&gt;
To limit the amount of geometry rendered in the shadow map, and also to reduce artifacts (shadow acne), only faces not facing the sun are casting shadows. The test is made using the normal orientation. That means that double-sided polygons, or mesh that are not closed, will be transparent to light at certain sun angles. To avoid that, modelers can either :&lt;br /&gt;
* ensure that the object is always in the shadow of another objects,&lt;br /&gt;
* close their mesh, or,&lt;br /&gt;
* double polygons with the normal set to the opposite.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52956</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52956"/>
		<updated>2012-08-15T12:23:48Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Registering all translucent surfaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Making sure that all geometry will cast shadow ===&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52926</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52926"/>
		<updated>2012-08-14T15:56:33Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Near term tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Use stencil double-sided operations to limit the depth of light volumes. Use depth clamp to ensure front faces are always rendered even if the camera is enclosed in the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52916</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52916"/>
		<updated>2012-08-14T09:48:16Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Long term ideas (unsorted) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Render light volumes with back face culling and depth clamp instead of front face culling, and don't light pixels in front of the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*Use a separate list of light volumes to avoid traversing the scenegraph again (with transparency problems). Find out how we can detect unloading of models.&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Changelog_2.8.0&amp;diff=52914</id>
		<title>Changelog 2.8.0</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Changelog_2.8.0&amp;diff=52914"/>
		<updated>2012-08-14T09:43:20Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Some of the major changes include: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft|changelog|}}&lt;br /&gt;
&lt;br /&gt;
==FlightGear 2.8.0 ChangeLog==&lt;br /&gt;
&lt;br /&gt;
The FlightGear development team is happy to announce the v2.8.0 release of FlightGear, the free, open-source flight simulator. This new version contains many exciting new features, enhancements and bugfixes.&lt;br /&gt;
&lt;br /&gt;
Founded in 1997, FlightGear is developed by a worldwide group of volunteers, brought together by a shared ambition to create &lt;br /&gt;
the most realistic flight simulator possible that is free to use, modify and distribute. FlightGear is used all over the world &lt;br /&gt;
by desktop flight simulator enthusiasts, for research in universities and for interactive exhibits in museums.&lt;br /&gt;
&lt;br /&gt;
FlightGear features more than 400 aircraft, a worldwide scenery database, a multi-player environment, detailed sky modelling, a flexible and open aircraft modelling system, varied networking options, multiple display support, a powerful scripting language and an open architecture. Best of all, being open-source, the simulator is owned by the community and everyone is encouraged to contribute. &lt;br /&gt;
&lt;br /&gt;
Download FlightGear v2.8.0 for free from [http://www.flightgear.org FlightGear.org]&lt;br /&gt;
&lt;br /&gt;
FlightGear - Fly Free!&lt;br /&gt;
&lt;br /&gt;
=== Some of the major changes include: ===&lt;br /&gt;
&lt;br /&gt;
'''Aircraft operations'''&lt;br /&gt;
&lt;br /&gt;
'''AI system'''&lt;br /&gt;
&lt;br /&gt;
'''AI Traffic'''&lt;br /&gt;
* Aircraft models and textures have been improved.&lt;br /&gt;
&lt;br /&gt;
'''Flight dynamics'''&lt;br /&gt;
* FlightGear has been synced with the JSBSim project.&lt;br /&gt;
&lt;br /&gt;
'''Environment'''&lt;br /&gt;
* Region-specific terrain textures are used for Europe and Hawaii. Now towns in Europe look different from towns in the USA.&lt;br /&gt;
* Cities and towns now look more populated due to random 3D buildings, completed with lighting at night.&lt;br /&gt;
* Scenery looks more realistic due to improved placement of random objects, buildings and trees.&lt;br /&gt;
* Airport signs with full apt.dat 850 syntax support. Models are rendered in 3D, with support for double-sided signs.&lt;br /&gt;
* You can now select between summer and winter scenery in-sim.&lt;br /&gt;
&lt;br /&gt;
'''Instruments &amp;amp; HUDs'''&lt;br /&gt;
* There's a new fully scriptable 2D rendering system supported for creating instruments, the so called [[Canvas]] which allows you to create fully dynamic cockpit instruments and HUDs, even by loading and drawing vector images. This can be used to create CDUs/MCDUs for FMC, complex glass cockpit avionics (MFDs, EICAS etc) and any other &amp;quot;glass&amp;quot; instruments that could previously only be created in C++ space. All of this has now become possible just by using [[Nasal]] scripting, without having to rebuild FlightGear.&lt;br /&gt;
&lt;br /&gt;
'''Interface'''&lt;br /&gt;
* Support for menu translations.&lt;br /&gt;
* Navigation and route-manager data is now available through a Nasal s&lt;br /&gt;
'''Highlighted new and improved aircraft'''&lt;br /&gt;
* [[Airwave Xtreme 150]]: complete new (JSBSim) flight dynamics, new model, advanced pilot animations.&lt;br /&gt;
* [[Cessna 337G Skymaster]]&lt;br /&gt;
&lt;br /&gt;
'''Project infrastructure'''&lt;br /&gt;
* Various improvements to our scenery database have made it easier than ever to add, delete or update objects and 3D models into the FlightGear world.&lt;br /&gt;
&lt;br /&gt;
'''Visual effects'''&lt;br /&gt;
* A new, experimental renderer supporting shadows via deferred rendering, named after the famous painter Rembrandt, is included for testing purposes.&lt;br /&gt;
* An improved simulation of atmospheric light scattering with terrain haze for the classical renderer.&lt;br /&gt;
* Easier selection of material files.&lt;br /&gt;
&lt;br /&gt;
'''Other'''&lt;br /&gt;
* Additional joysticks and rudder pedals are supported out-of-the-box:&lt;br /&gt;
** InterLink Elite&lt;br /&gt;
** Qware USB&lt;br /&gt;
** Saitek Cyborg X (F.L.Y. 5)&lt;br /&gt;
** Saitek Pro Flight Trim Wheel&lt;br /&gt;
** Saitek Pro Flight Yoke&lt;br /&gt;
** Speedlink Defender&lt;br /&gt;
* A French partial translation of The FlightGear Manual is now available.&lt;br /&gt;
&lt;br /&gt;
'''Bug fixes'''&lt;br /&gt;
* See [http://code.google.com/p/flightgear-bugs/issues/list?can=1&amp;amp;q=Milestone%3D2.8.0 our bugtracker] for an extensive list of the bugs fixed in this release.&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear changelogs]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52911</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52911"/>
		<updated>2012-08-14T09:37:56Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Near term tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Render light volumes with back face culling and depth clamp instead of front face culling, and don't light pixels in front of the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52910</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52910"/>
		<updated>2012-08-14T09:23:11Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Near term tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
*Render light volumes with back face culling and depth clamp instead of front face culling, and don't light pixels in from of the light volume.&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52872</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52872"/>
		<updated>2012-08-12T18:40:56Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Long term ideas (unsorted) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement volumetric effects by extending lights to arbitrary shaders. Should enable to implement heat haze effect and real wake waves.&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel) - use a Poisson-disk distribution to implement variable size blur&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=52688</id>
		<title>FlightGear Newsletter August 2012</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=52688"/>
		<updated>2012-08-05T21:58:41Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* New effects in Rembrandt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{newsletter}}&lt;br /&gt;
{{TOC_right|limit=2}}&lt;br /&gt;
&lt;br /&gt;
''We would like to emphasize that the monthly newsletter can not live without the contributions of FlightGear users and developers. Everyone with a wiki account (free to register) can edit the newsletter and every contribution is welcome. So if you know about any FlightGear related news or projects such as for example updated scenery or aircraft, please do feel invited to add such news to the newsletter.''&lt;br /&gt;
&lt;br /&gt;
== Development news ==&lt;br /&gt;
&lt;br /&gt;
=== Canvas News ===&lt;br /&gt;
&lt;br /&gt;
=== Mailing list digest ===&lt;br /&gt;
&lt;br /&gt;
(by far the easiest option to populate the newsletter with contents is copying/pasting stuff from the forum and the mailing list or the git logs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Forum digest ===&lt;br /&gt;
&lt;br /&gt;
=== '''Flightgear On Android''' ===&lt;br /&gt;
&lt;br /&gt;
A new developer has achieved a way to run Flightgear on Android phones.    [[File:Flightgear Android Launcher.png|thumb|FOA]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The project codename will be FOA.          				   [[File:FOA.jpg|thumb|FOA ingame]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
He has done allot of Android and C++ coding. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
His phone is a Samsung Galaxy Nexus and is running Android 4.04           &lt;br /&gt;
Custom ROM but stock ROM should be OK). If your ready to test with us, &lt;br /&gt;
please read the technical info then send a email to lacbrc@gmail.com!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TECHNICAL INFO:&lt;br /&gt;
It should have at least a 1GHz processor and decent graphics chip. Android 2.3 is a          &lt;br /&gt;
must but a rooted device is not needed but can improve performance.&lt;br /&gt;
Not much in this, as we haven't finished it to a release yet. &lt;br /&gt;
He tested it on a bluetooth keyboard and a wired one through usb host mode. Hope your interested. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At current we are almost ready for the first release. We are all looking forward to it. &lt;br /&gt;
Hope you`ve enjoyed this and we`ll leave you with a screen of the Alpha Launcher:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Team at FOA&lt;br /&gt;
&lt;br /&gt;
Here is a few links:&lt;br /&gt;
&lt;br /&gt;
Forums:&lt;br /&gt;
&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&lt;br /&gt;
&lt;br /&gt;
Website page:&lt;br /&gt;
&lt;br /&gt;
http://horizonflightgearhangar.yolasite.com/fg-on-android.php&lt;br /&gt;
&lt;br /&gt;
Wiki page:&lt;br /&gt;
&lt;br /&gt;
http://wiki.flightgear.org/Flightgear_On_Android&lt;br /&gt;
&lt;br /&gt;
=== New effects in Rembrandt ===&lt;br /&gt;
The [[Project Rembrandt|Rembrandt renderer]] has a lot of potentiality when it comes to post processing effects. Indeed, the interesting property of a deferred shader is that all stages of rendering are kept into memory. Post-processing is as simple as using a filter on a camera.&lt;br /&gt;
&lt;br /&gt;
So currently the effects added in git are :&lt;br /&gt;
* Night vision including amplification grain and restrained field of view,&lt;br /&gt;
* Cinema effect including :&lt;br /&gt;
** Vignetting,&lt;br /&gt;
** Color shift, with Sepia as default value,&lt;br /&gt;
** Radial distortion (barrel and pincushion distortion, with scale compensation),&lt;br /&gt;
** Lateral chromatic aberration (purple fringing),&lt;br /&gt;
** Film wear simulation.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:Fgfs-rembrandt-old-timer.jpg|thumb|400px|Rembrandt old film style]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-distortion.jpg|thumb|400px|Rembrandt ordinary lens simulation]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-night-vision-2.png|thumb|400px|Rembrandt night vision simulation]]&lt;br /&gt;
|}&lt;br /&gt;
This won't make it for the 2.8 release but it's likely that an add-on will be available as it is contained in the data.&lt;br /&gt;
&lt;br /&gt;
=== Git digest ===&lt;br /&gt;
&lt;br /&gt;
=== Getting involved as a programmer ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Howto:Start core development]]&lt;br /&gt;
&lt;br /&gt;
== Interview with a contributor (NAME) ==&lt;br /&gt;
''In each edition we have an interview with a contributor. Suggestions for possible questions are available on [[interview questions]], you are invited to come up with new questions and interview ideas obviously! Anyone is free to write an interview (with him-/herself or others) for next month's newsletter! If you'd like to help interview a contributor or get interviewed, please do consider adding yourself to the [[list of interview volunteers]]! To keep this going and less awkward, we are currently trying to come up with the convention that former interviewees become next month's interviewers.''&lt;br /&gt;
&lt;br /&gt;
* How long have you been involved in FlightGear?&lt;br /&gt;
* What are your major interests in FlightGear?&lt;br /&gt;
* What project are you working on right now?&lt;br /&gt;
* What do you plan on doing in the future?&lt;br /&gt;
* Are you happy with the way the FlightGear project is going?&lt;br /&gt;
* What do you enjoy most about developing for FlightGear?&lt;br /&gt;
* Are there any &amp;quot;hidden features&amp;quot; you have worked on in FlightGear that new users may miss?&lt;br /&gt;
* What advice can you give to new developers who want to get started on their first aircraft/new feature/Nasal script?&lt;br /&gt;
&lt;br /&gt;
More questions are being collected here: [[Interview questions]].&lt;br /&gt;
&lt;br /&gt;
Stay tuned for next month's interview, featuring FlightGear contributor XXXXXXXX &lt;br /&gt;
&lt;br /&gt;
== Snapshot releases ==&lt;br /&gt;
Every now and then, easy-to-install development snapshots are created (usually, twice montlhy). These snapshos depict a recent state of the development version of FlightGear. By using them users can test out features that will be included in the upcoming release. Testers are encouraged to file bugs at [http://code.google.com/p/flightgear-bugs/ the issue tracker].&lt;br /&gt;
&lt;br /&gt;
The snapshot can be download via the links at the bottom of this page: http://www.flightgear.org/download/. Updates and feedback can be found [http://flightgear.org/forums/viewtopic.php?f=28&amp;amp;t=10488&amp;amp;p=144233&amp;amp;hilit=snapshot#p144233 at the forum].&lt;br /&gt;
&lt;br /&gt;
== Nasal for newbies ==&lt;br /&gt;
&lt;br /&gt;
== New software tools and projects ==&lt;br /&gt;
&lt;br /&gt;
== FlightGear addons and mods ==&lt;br /&gt;
&lt;br /&gt;
== In the hangar ==&lt;br /&gt;
&lt;br /&gt;
All the way back in May 2011, we addopted a new status-rating system for aircraft. So far, only a few have actually been rated, as can be seen in the list 'hockenberry' set up at [https://docs.google.com/spreadsheet/ccc?key=0ApzphjA4w05ndF94Y2F0bzJTbHQ5QTJXZXJRcUVRbWc&amp;amp;hl=en_US Google Docs]. If you're an aircraft developer and your aircraft is/are not on the list, please consider rating their status. All you'll need to know/do is described at [[Formalizing Aircraft Status]]. If you'd just like to get started contributing to FlightGear, this would also seem like an excellent way to get started.&lt;br /&gt;
&lt;br /&gt;
=== New hangers ===&lt;br /&gt;
&lt;br /&gt;
=== New aircraft ===&lt;br /&gt;
&lt;br /&gt;
=== Updated aircraft ===&lt;br /&gt;
&lt;br /&gt;
==== [[ATC-FS]] ====&lt;br /&gt;
The Air Traffic Control tool ATC-FS got an update. The old radar screen was replaced by a radar screen, which can display fixes, navaids and ILS localizers. This new radar is resizable, so you can use your big screen more efficient.&lt;br /&gt;
&lt;br /&gt;
[[Image:ATC-FS.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
=== Liveries ===&lt;br /&gt;
&lt;br /&gt;
== Scenery corner ==&lt;br /&gt;
=== Airports ===&lt;br /&gt;
&lt;br /&gt;
== Aircraft of the month ==&lt;br /&gt;
== Airport of the month ==&lt;br /&gt;
== Screenshot of the month ==&lt;br /&gt;
&lt;br /&gt;
== Suggested flights ==&lt;br /&gt;
== Aircraft reviews ==&lt;br /&gt;
&lt;br /&gt;
== Wiki updates ==&lt;br /&gt;
===New articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===New aircraft articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
  categoryRoot=Aircraft&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===Most popular newsletters===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=hot&lt;br /&gt;
  count=5&lt;br /&gt;
  categoryRoot=FlightGear Newsletter&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community news ==&lt;br /&gt;
=== FlightGear on YouTube ===&lt;br /&gt;
&lt;br /&gt;
=== New tutorials and screencasts ===&lt;br /&gt;
=== Forum news ===&lt;br /&gt;
=== Multiplayer ===&lt;br /&gt;
=== Virtual airlines ===&lt;br /&gt;
=== FlightGear events ===&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
== And finally ... ==&lt;br /&gt;
=== Did you know? ===&lt;br /&gt;
Did you know that the FlightGear project dates back to a discussion among a group of net citizens in 1996 resulting in a proposal written by David Murr? The original proposal is still available&lt;br /&gt;
from the FlightGear website and can be found [http://www.flightgear.org/proposal-3.0.1 on the FlightGear website]. Read it, you'll learn a lot about FlightGears' roots which still lead the project spirit.&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
One of the regular thoughts expressed on the FlightGear forums is &amp;quot;I'd like to contribute but I don't know how to program, and I don't have the time&amp;quot;. Unfortunately, there is a common mis-conception that contributing requires programming and lots of free time. In fact, there are a huge range of ways to contribute to the project without needing to write code or spending days working on something. &lt;br /&gt;
&lt;br /&gt;
For ideas on starting to contribute to FlightGear, you may want to check out: [[Volunteer]].&lt;br /&gt;
&lt;br /&gt;
=== Call for volunteers ===&lt;br /&gt;
* The [http://horizonflightgearhangar.yolasite.com/fg-on-android.php FOA] Team is looking for testers.&lt;br /&gt;
* The [[OpenRadar]] project is looking for a new maintainer.&lt;br /&gt;
* The [[FGFSPM]] (FlightGear Package Manager) is looking for a new maintainer.&lt;br /&gt;
&lt;br /&gt;
=== Did you know ===&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear Newsletter|2012 08]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=52686</id>
		<title>FlightGear Newsletter August 2012</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_August_2012&amp;diff=52686"/>
		<updated>2012-08-05T18:14:51Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* New effects in Rembrandt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{newsletter}}&lt;br /&gt;
{{TOC_right|limit=2}}&lt;br /&gt;
&lt;br /&gt;
''We would like to emphasize that the monthly newsletter can not live without the contributions of FlightGear users and developers. Everyone with a wiki account (free to register) can edit the newsletter and every contribution is welcome. So if you know about any FlightGear related news or projects such as for example updated scenery or aircraft, please do feel invited to add such news to the newsletter.''&lt;br /&gt;
&lt;br /&gt;
== Development news ==&lt;br /&gt;
&lt;br /&gt;
=== Canvas News ===&lt;br /&gt;
&lt;br /&gt;
=== Mailing list digest ===&lt;br /&gt;
&lt;br /&gt;
(by far the easiest option to populate the newsletter with contents is copying/pasting stuff from the forum and the mailing list or the git logs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Forum digest ===&lt;br /&gt;
&lt;br /&gt;
=== '''Flightgear On Android''' ===&lt;br /&gt;
&lt;br /&gt;
A new developer has achieved a way to run Flightgear on Android phones.    [[File:Flightgear Android Launcher.png|thumb|FOA]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The project codename will be FOA.          				   [[File:FOA.jpg|thumb|FOA ingame]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
He has done allot of Android and C++ coding. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
His phone is a Samsung Galaxy Nexus and is running Android 4.04           &lt;br /&gt;
Custom ROM but stock ROM should be OK). If your ready to test with us, &lt;br /&gt;
please read the technical info then send a email to lacbrc@gmail.com!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TECHNICAL INFO:&lt;br /&gt;
It should have at least a 1GHz processor and decent graphics chip. Android 2.3 is a          &lt;br /&gt;
must but a rooted device is not needed but can improve performance.&lt;br /&gt;
Not much in this, as we haven't finished it to a release yet. &lt;br /&gt;
He tested it on a bluetooth keyboard and a wired one through usb host mode. Hope your interested. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At current we are almost ready for the first release. We are all looking forward to it. &lt;br /&gt;
Hope you`ve enjoyed this and we`ll leave you with a screen of the Alpha Launcher:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Team at FOA&lt;br /&gt;
&lt;br /&gt;
Here is a few links:&lt;br /&gt;
&lt;br /&gt;
Forums:&lt;br /&gt;
&lt;br /&gt;
http://www.flightgear.org/forums/viewtopic.php?f=18&amp;amp;t=16719&lt;br /&gt;
&lt;br /&gt;
Website page:&lt;br /&gt;
&lt;br /&gt;
http://horizonflightgearhangar.yolasite.com/fg-on-android.php&lt;br /&gt;
&lt;br /&gt;
Wiki page:&lt;br /&gt;
&lt;br /&gt;
http://wiki.flightgear.org/Flightgear_On_Android&lt;br /&gt;
&lt;br /&gt;
=== '''New effects in Rembrandt''' ===&lt;br /&gt;
The [[Project Rembrandt|Rembrandt renderer]] as a lot of potentiality when it comes to post processing effects. Indeed, the interesting property of a deferred shader is that all stages of rendering are kept into memory. Post-processing is as simple as using a filter on a camera.&lt;br /&gt;
&lt;br /&gt;
So currently the effects added in git are :&lt;br /&gt;
* Night vision including amplification grain and restrained field of view,&lt;br /&gt;
* Cinema effect including :&lt;br /&gt;
** Vignetting,&lt;br /&gt;
** Color shift, with Sepia as default value,&lt;br /&gt;
** Radial distortion (barrel and pincushion distortion, with scale compensation),&lt;br /&gt;
** Lateral chromatic aberration (purple fringing),&lt;br /&gt;
** Film wear simulation.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:Fgfs-rembrandt-old-timer.jpg|thumb|400px|Rembrandt old film style]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-distortion.jpg|thumb|400px|Rembrandt ordinary lens simulation]]&lt;br /&gt;
| [[File:Fgfs-rembrandt-night-vision-2.png|thumb|400px|Rembrandt night vision simulation]]&lt;br /&gt;
|}&lt;br /&gt;
This won't make it for the 2.8 release but it's likely that an add-on will be available as it is contained in the data.&lt;br /&gt;
&lt;br /&gt;
=== Git digest ===&lt;br /&gt;
&lt;br /&gt;
=== Getting involved as a programmer ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Howto:Start core development]]&lt;br /&gt;
&lt;br /&gt;
== Interview with a contributor (NAME) ==&lt;br /&gt;
''In each edition we have an interview with a contributor. Suggestions for possible questions are available on [[interview questions]], you are invited to come up with new questions and interview ideas obviously! Anyone is free to write an interview (with him-/herself or others) for next month's newsletter! If you'd like to help interview a contributor or get interviewed, please do consider adding yourself to the [[list of interview volunteers]]! To keep this going and less awkward, we are currently trying to come up with the convention that former interviewees become next month's interviewers.''&lt;br /&gt;
&lt;br /&gt;
* How long have you been involved in FlightGear?&lt;br /&gt;
* What are your major interests in FlightGear?&lt;br /&gt;
* What project are you working on right now?&lt;br /&gt;
* What do you plan on doing in the future?&lt;br /&gt;
* Are you happy with the way the FlightGear project is going?&lt;br /&gt;
* What do you enjoy most about developing for FlightGear?&lt;br /&gt;
* Are there any &amp;quot;hidden features&amp;quot; you have worked on in FlightGear that new users may miss?&lt;br /&gt;
* What advice can you give to new developers who want to get started on their first aircraft/new feature/Nasal script?&lt;br /&gt;
&lt;br /&gt;
More questions are being collected here: [[Interview questions]].&lt;br /&gt;
&lt;br /&gt;
Stay tuned for next month's interview, featuring FlightGear contributor XXXXXXXX &lt;br /&gt;
&lt;br /&gt;
== Snapshot releases ==&lt;br /&gt;
Every now and then, easy-to-install development snapshots are created (usually, twice montlhy). These snapshos depict a recent state of the development version of FlightGear. By using them users can test out features that will be included in the upcoming release. Testers are encouraged to file bugs at [http://code.google.com/p/flightgear-bugs/ the issue tracker].&lt;br /&gt;
&lt;br /&gt;
The snapshot can be download via the links at the bottom of this page: http://www.flightgear.org/download/. Updates and feedback can be found [http://flightgear.org/forums/viewtopic.php?f=28&amp;amp;t=10488&amp;amp;p=144233&amp;amp;hilit=snapshot#p144233 at the forum].&lt;br /&gt;
&lt;br /&gt;
== Nasal for newbies ==&lt;br /&gt;
&lt;br /&gt;
== New software tools and projects ==&lt;br /&gt;
&lt;br /&gt;
== FlightGear addons and mods ==&lt;br /&gt;
&lt;br /&gt;
== In the hangar ==&lt;br /&gt;
&lt;br /&gt;
All the way back in May 2011, we addopted a new status-rating system for aircraft. So far, only a few have actually been rated, as can be seen in the list 'hockenberry' set up at [https://docs.google.com/spreadsheet/ccc?key=0ApzphjA4w05ndF94Y2F0bzJTbHQ5QTJXZXJRcUVRbWc&amp;amp;hl=en_US Google Docs]. If you're an aircraft developer and your aircraft is/are not on the list, please consider rating their status. All you'll need to know/do is described at [[Formalizing Aircraft Status]]. If you'd just like to get started contributing to FlightGear, this would also seem like an excellent way to get started.&lt;br /&gt;
&lt;br /&gt;
=== New hangers ===&lt;br /&gt;
&lt;br /&gt;
=== New aircraft ===&lt;br /&gt;
&lt;br /&gt;
=== Updated aircraft ===&lt;br /&gt;
&lt;br /&gt;
==== [[ATC-FS]] ====&lt;br /&gt;
The Air Traffic Control tool ATC-FS got an update. The old radar screen was replaced by a radar screen, which can display fixes, navaids and ILS localizers. This new radar is resizable, so you can use your big screen more efficient.&lt;br /&gt;
&lt;br /&gt;
[[Image:ATC-FS.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
=== Liveries ===&lt;br /&gt;
&lt;br /&gt;
== Scenery corner ==&lt;br /&gt;
=== Airports ===&lt;br /&gt;
&lt;br /&gt;
== Aircraft of the month ==&lt;br /&gt;
== Airport of the month ==&lt;br /&gt;
== Screenshot of the month ==&lt;br /&gt;
&lt;br /&gt;
== Suggested flights ==&lt;br /&gt;
== Aircraft reviews ==&lt;br /&gt;
&lt;br /&gt;
== Wiki updates ==&lt;br /&gt;
===New articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===New aircraft articles===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=new&lt;br /&gt;
  count=10&lt;br /&gt;
  categoryRoot=Aircraft&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
===Most popular newsletters===&lt;br /&gt;
&amp;lt;DynamicArticleList&amp;gt;&lt;br /&gt;
  type=hot&lt;br /&gt;
  count=5&lt;br /&gt;
  categoryRoot=FlightGear Newsletter&lt;br /&gt;
&amp;lt;/DynamicArticleList&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community news ==&lt;br /&gt;
=== FlightGear on YouTube ===&lt;br /&gt;
&lt;br /&gt;
=== New tutorials and screencasts ===&lt;br /&gt;
=== Forum news ===&lt;br /&gt;
=== Multiplayer ===&lt;br /&gt;
=== Virtual airlines ===&lt;br /&gt;
=== FlightGear events ===&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
== And finally ... ==&lt;br /&gt;
=== Did you know? ===&lt;br /&gt;
Did you know that the FlightGear project dates back to a discussion among a group of net citizens in 1996 resulting in a proposal written by David Murr? The original proposal is still available&lt;br /&gt;
from the FlightGear website and can be found [http://www.flightgear.org/proposal-3.0.1 on the FlightGear website]. Read it, you'll learn a lot about FlightGears' roots which still lead the project spirit.&lt;br /&gt;
&lt;br /&gt;
=== Contributing ===&lt;br /&gt;
One of the regular thoughts expressed on the FlightGear forums is &amp;quot;I'd like to contribute but I don't know how to program, and I don't have the time&amp;quot;. Unfortunately, there is a common mis-conception that contributing requires programming and lots of free time. In fact, there are a huge range of ways to contribute to the project without needing to write code or spending days working on something. &lt;br /&gt;
&lt;br /&gt;
For ideas on starting to contribute to FlightGear, you may want to check out: [[Volunteer]].&lt;br /&gt;
&lt;br /&gt;
=== Call for volunteers ===&lt;br /&gt;
* The [http://horizonflightgearhangar.yolasite.com/fg-on-android.php FOA] Team is looking for testers.&lt;br /&gt;
* The [[OpenRadar]] project is looking for a new maintainer.&lt;br /&gt;
* The [[FGFSPM]] (FlightGear Package Manager) is looking for a new maintainer.&lt;br /&gt;
&lt;br /&gt;
=== Did you know ===&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear Newsletter|2012 08]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=File:Fgfs-rembrandt-night-vision-2.png&amp;diff=52681</id>
		<title>File:Fgfs-rembrandt-night-vision-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=File:Fgfs-rembrandt-night-vision-2.png&amp;diff=52681"/>
		<updated>2012-08-05T17:27:48Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=={{int:filedesc}}==&lt;br /&gt;
{{Information&lt;br /&gt;
|description={{en|1=Rembrandt postprocessing effect simulating night vision device}}&lt;br /&gt;
|date=2012-08-05&lt;br /&gt;
|source={{own}}&lt;br /&gt;
|author=[[User:Fredb|Fredb]]&lt;br /&gt;
|permission=&lt;br /&gt;
|other_versions=&lt;br /&gt;
|other_fields=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=={{int:license-header}}==&lt;br /&gt;
{{self|cc-by-sa-3.0}}&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=File:Fgfs-rembrandt-old-timer.jpg&amp;diff=52680</id>
		<title>File:Fgfs-rembrandt-old-timer.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=File:Fgfs-rembrandt-old-timer.jpg&amp;diff=52680"/>
		<updated>2012-08-05T17:27:47Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=={{int:filedesc}}==&lt;br /&gt;
{{Information&lt;br /&gt;
|description={{en|1=Rembrandt postprocessing effect simulating very old film}}&lt;br /&gt;
|date=2012-08-05&lt;br /&gt;
|source={{own}}&lt;br /&gt;
|author=[[User:Fredb|Fredb]]&lt;br /&gt;
|permission=&lt;br /&gt;
|other_versions=&lt;br /&gt;
|other_fields=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=={{int:license-header}}==&lt;br /&gt;
{{self|cc-by-sa-3.0}}&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=File:Fgfs-rembrandt-distortion.jpg&amp;diff=52679</id>
		<title>File:Fgfs-rembrandt-distortion.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=File:Fgfs-rembrandt-distortion.jpg&amp;diff=52679"/>
		<updated>2012-08-05T17:27:44Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=={{int:filedesc}}==&lt;br /&gt;
{{Information&lt;br /&gt;
|description={{en|1=Rembrandt postprocessing effect simulating ordinary lens distortion (pincushion, vignette and chromatic aberration)}}&lt;br /&gt;
|date=2012-08-05&lt;br /&gt;
|source={{own}}&lt;br /&gt;
|author=[[User:Fredb|Fredb]]&lt;br /&gt;
|permission=&lt;br /&gt;
|other_versions=&lt;br /&gt;
|other_fields=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=={{int:license-header}}==&lt;br /&gt;
{{self|cc-by-sa-3.0}}&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52233</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52233"/>
		<updated>2012-07-29T17:35:49Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Near term tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
*Allow light masks using textures&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52232</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=52232"/>
		<updated>2012-07-29T17:33:56Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Registering all translucent surfaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beware: &amp;lt;Effect&amp;gt; only works on real objects, not on groups of objects or animations.'''&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51905</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51905"/>
		<updated>2012-07-22T08:05:15Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Adding lights to a model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Performance and compatibility considerations ====&lt;br /&gt;
Every light on screen is equivalent for the GPU of redrawing the light volume with a shader, without z buffer culling. So each light comes with a cost, that is small taken individually but noticeable when a lot of them are visible. That cost also increase with the size of the light volume.&lt;br /&gt;
&lt;br /&gt;
Beside that, it is wise to allow a model to work with the classical renderer that know nothing about lights and would render light volumes like other geometry. So a good practice is to complement each light animation with a select animation checking :&lt;br /&gt;
*if Rembrandt is enabled&lt;br /&gt;
*if the user selected quality match with the purpose of the light&lt;br /&gt;
*if the light should be on or off according to the other parameters of the simulation (position of the sun, position of switch, presence of power, ...)&lt;br /&gt;
&lt;br /&gt;
A quality property is created to reflect the user preferences about quality vs performance concerning lights, and a proper slider is added to the shader dialog.&lt;br /&gt;
[[File:Fgfs-shaders-with-light.jpg|thumb|Light quality slider]]&lt;br /&gt;
The propery to use is :&lt;br /&gt;
 /sim/rendering/shaders/lights&lt;br /&gt;
The quality slider sets its range from 0 (no lights) to 4 (all lights on). Simple airport lamp post appears at 1. Few bridge lamps at 2, all simple bridge lamp at 3 and more involved one at 4.&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;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSource&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightVolume&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;animation&amp;gt;&lt;br /&gt;
   &amp;lt;type&amp;gt;select&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;!-- Select the named animation --&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightSource&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;condition&amp;gt;&lt;br /&gt;
      &amp;lt;and&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Rembrandt enabled ? --&amp;gt;&lt;br /&gt;
         &amp;lt;property&amp;gt;/sim/rendering/rembrandt/enabled&amp;lt;/property&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Quality ok ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&amp;gt;&lt;br /&gt;
            &amp;lt;property&amp;gt;/sim/rendering/shaders/lights&amp;lt;/property&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;3.0&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
         &amp;lt;!-- Simulation conditions ? --&amp;gt;&lt;br /&gt;
         &amp;lt;greater-than&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;value&amp;gt;1.57&amp;lt;/value&amp;gt;&lt;br /&gt;
         &amp;lt;/greater-than&amp;gt;&lt;br /&gt;
      &amp;lt;/and&amp;gt;&lt;br /&gt;
   &amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=File:Fgfs-shaders-with-light.jpg&amp;diff=51904</id>
		<title>File:Fgfs-shaders-with-light.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=File:Fgfs-shaders-with-light.jpg&amp;diff=51904"/>
		<updated>2012-07-22T07:57:59Z</updated>

		<summary type="html">&lt;p&gt;Fredb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=={{int:filedesc}}==&lt;br /&gt;
{{Information&lt;br /&gt;
|description={{en|1=Shader selection box with light slider}}&lt;br /&gt;
|date=2012-07-22&lt;br /&gt;
|source={{own}}&lt;br /&gt;
|author=[[User:Fredb|Fredb]]&lt;br /&gt;
|permission=&lt;br /&gt;
|other_versions=&lt;br /&gt;
|other_fields=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=={{int:license-header}}==&lt;br /&gt;
{{self|cc-by-sa-3.0}}&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Changelog_2.8.0&amp;diff=51802</id>
		<title>Changelog 2.8.0</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Changelog_2.8.0&amp;diff=51802"/>
		<updated>2012-07-17T18:49:29Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Some of the major changes include: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft|changelog|}}&lt;br /&gt;
&lt;br /&gt;
==FlightGear 2.8.0 ChangeLog==&lt;br /&gt;
&lt;br /&gt;
The [[FlightGear]] development team is happy to announce the v2.8.0 release of FlightGear, the free, open-source flight simulator. &lt;br /&gt;
This new version contains many exciting new features, enhancements and bugfixes.&lt;br /&gt;
&lt;br /&gt;
Founded in 1997, FlightGear is developed by a worldwide group of volunteers, brought together by a shared ambition to create &lt;br /&gt;
the most realistic flight simulator possible that is free to use, modify and distribute. FlightGear is used all over the world &lt;br /&gt;
by desktop flight simulator enthusiasts, for research in universities and for interactive exhibits in museums.&lt;br /&gt;
&lt;br /&gt;
FlightGear features more than 400 aircraft, a worldwide scenery database, a worldwide multi-player environment, detailed sky modelling, a flexible and open aircraft modelling system, varied networking options, multiple display support, a powerful scripting language and an open architecture. Best of all, being open-source, the simulator is owned by the community and everyone is encouraged to contribute. &lt;br /&gt;
&lt;br /&gt;
Download FlightGear v2.8.0 for free from [http://www.flightgear.org FlightGear.org]&lt;br /&gt;
&lt;br /&gt;
FlightGear - Fly Free!&lt;br /&gt;
&lt;br /&gt;
=== Some of the major changes include: ===&lt;br /&gt;
&lt;br /&gt;
'''Aircraft operations'''&lt;br /&gt;
&lt;br /&gt;
'''AI system'''&lt;br /&gt;
&lt;br /&gt;
'''AI Traffic'''&lt;br /&gt;
* Improved aircraft models and textures.&lt;br /&gt;
&lt;br /&gt;
'''Flight dynamics'''&lt;br /&gt;
* Synced with the JSBSim project.&lt;br /&gt;
&lt;br /&gt;
'''Environment'''&lt;br /&gt;
* Random objects are only placed within certain areas of a terrain texture.&lt;br /&gt;
* Airport signs are 3D models now.&lt;br /&gt;
* Random 3D buildings for urban areas, complete with lighting at night.&lt;br /&gt;
&lt;br /&gt;
'''Interface'''&lt;br /&gt;
* Support for menu translations.&lt;br /&gt;
&lt;br /&gt;
'''Highlighted new and improved aircraft'''&lt;br /&gt;
* [[Airwave Xtreme 150]]: complete new (JSBSim) flight dynamics, new model, advanced pilot animations.&lt;br /&gt;
* [[Cessna 337G Skymaster]]&lt;br /&gt;
&lt;br /&gt;
'''Project infrastructure'''&lt;br /&gt;
* Various improvements to our scenery database have made it easier than ever to add, delete or update objects to the FlightGear world.&lt;br /&gt;
&lt;br /&gt;
'''Visual effects'''&lt;br /&gt;
* A new, experimental renderer, named after the famous painter Rembrandt, is included for testing purposes.&lt;br /&gt;
* Easy selection of material files.&lt;br /&gt;
&lt;br /&gt;
'''Other'''&lt;br /&gt;
* Additional joysticks and rudder pedals are supported out-of-the-box:&lt;br /&gt;
** InterLink Elite&lt;br /&gt;
** Qware USB&lt;br /&gt;
** Saitek Cyborg X (F.L.Y. 5)&lt;br /&gt;
** Saitek Pro Flight Trim Wheel&lt;br /&gt;
** Saitek Pro Flight Yoke&lt;br /&gt;
** Speedlink Defender&lt;br /&gt;
&lt;br /&gt;
'''Bug fixes'''&lt;br /&gt;
* See [http://code.google.com/p/flightgear-bugs/issues/list?can=1&amp;amp;q=Milestone%3D2.8.0 our bugtracker] for an extensive list of the bugs fixed in this release.&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear changelogs]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51739</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51739"/>
		<updated>2012-07-14T18:38:10Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* What is it ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=51738</id>
		<title>Fr/Projet Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=51738"/>
		<updated>2012-07-14T18:36:54Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* De quoi s'agit-il ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Pourquoi ce nom? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] était un peintre hollandais du XVIIème siècle, maître incontesté du [http://en.wikipedia.org/wiki/Chiaroscuro &amp;quot;clair-obscur&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Ce projet a pour but de changer la manière de rendre les éclairages et les [[Shadows|ombres]] qu'utilise [[FlightGear]], et d'essayer d'imiter le style de Rembrandt dans FG.&lt;br /&gt;
&lt;br /&gt;
== De quoi s'agit-il ? ==&lt;br /&gt;
L'idée maîtresse du projet est d'implémenter le [http://en.wikipedia.org/wiki/Deferred_shading rendu différé] au sein de FlightGear.&lt;br /&gt;
Depuis le début, FlightGear utilise un moteur de rendu en avant qui affiche toutes les propriétés d'un objet en une fois (ombre, éclairage, brouillard, ...), ce qui rend difficile le rendu d'un ombrage plus sophistiqué (voir le [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) du fait que tous les paramètres de [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ l'équation lumineuse] doivent être traités en une seule fois.&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Vue principale avec le contenu des buffers affichés dans les coins]]&lt;br /&gt;
Au contraire, le rendu différé cherche à séparer les opérations en étapes simplifiées et à collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par la prochain étape.&lt;br /&gt;
&lt;br /&gt;
;Le premier stade est celui de la Géométrie:&lt;br /&gt;
: nous rendons la scène entière dans 4 textures, en utilisant le rendu multi-cibles pour les traiter en un seul passage: un pour le buffer de profondeur, un pour les normales (en bas à gauche de l'image), un pour les couleurs &amp;quot;diffuses&amp;quot; (en bas à gauche) et un pour les couleurs &amp;quot;spéculaires&amp;quot; (en haut à droite).&lt;br /&gt;
&lt;br /&gt;
;Le stade suivant est celui de l'ombre :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=51737</id>
		<title>Fr/Projet Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=51737"/>
		<updated>2012-07-14T18:34:01Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* De quoi s'agit-il ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Pourquoi ce nom? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] était un peintre hollandais du XVIIème siècle, maître incontesté du [http://en.wikipedia.org/wiki/Chiaroscuro &amp;quot;clair-obscur&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Ce projet a pour but de changer la manière de rendre les éclairages et les [[Shadows|ombres]] qu'utilise [[FlightGear]], et d'essayer d'imiter le style de Rembrandt dans FG.&lt;br /&gt;
&lt;br /&gt;
== De quoi s'agit-il ? ==&lt;br /&gt;
L'idée maîtresse du projet est d'implémenter le [http://en.wikipedia.org/wiki/Deferred_shading rendu différé] au sein de FlightGear.&lt;br /&gt;
Depuis le début, FlightGear utilise un moteur de rendu en avant qui affiche toutes les propriétés d'un objet en une fois (ombre, éclairage, brouillard, ...), ce qui rend difficile le rendu d'un ombrage plus sophistiqué (voir le [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) du fait que tous les paramètres de [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ l'équation lumineuse] doivent être traités en une seule fois.&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Vue principale avec le contenu des buffers affichés dans les coins]]&lt;br /&gt;
Au contraire, le rendu différé cherche à séparer les opérations en étapes simplifiées et à collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par la prochain étape.&lt;br /&gt;
&lt;br /&gt;
;Le premier stade est celui de la Géométrie:&lt;br /&gt;
: nous rendons la scène entière en 4 textures, en utilisant des objets multi-rendu pour les traiter en un seul passage: un pour le buffer de profondeur, un pour les normales (en bas à gauche de l'image), un pour les couleurs &amp;quot;diffuses&amp;quot; (en bas à gauche) et un pour les couleurs &amp;quot;spéculaires&amp;quot; (en haut à droite).&lt;br /&gt;
&lt;br /&gt;
;Le stade suivant est celui de l'ombre :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=51736</id>
		<title>Fr/Projet Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Fr/Projet_Rembrandt&amp;diff=51736"/>
		<updated>2012-07-14T18:24:56Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Pourquoi ce nom? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Pourquoi ce nom? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] était un peintre hollandais du XVIIème siècle, maître incontesté du [http://en.wikipedia.org/wiki/Chiaroscuro &amp;quot;clair-obscur&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Ce projet a pour but de changer la manière de rendre les éclairages et les [[Shadows|ombres]] qu'utilise [[FlightGear]], et d'essayer d'imiter le style de Rembrandt dans FG.&lt;br /&gt;
&lt;br /&gt;
== De quoi s'agit-il ? ==&lt;br /&gt;
L'idée maîtresse du projet est d'obtenir un rendu différé de l'ombre [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] au sein de FlightGear.&lt;br /&gt;
Au début, FlightGear essayait de rendre toutes les propriétés d'un objet en un tout (ombre, éclairage, brouillard, ...) ce qui rendait difficile la mise au point des ombres plus sophistiquées&lt;br /&gt;
(voir le [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) du fait que tous les aspects de l'équation 3danimation/rendu sont traités d'un bloc [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Vue principale avec le contenu des buffers affichés dans les coins]]&lt;br /&gt;
Au contraire, le rendu différé cherche à séparer les opérations en stades simplifiés et a collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par le prochain stade.&lt;br /&gt;
&lt;br /&gt;
;Le premier stade est celui de la Géométrie:&lt;br /&gt;
: nous rendons la scène entière en 4 textures, en utilisant des objets multi-rendu pour les traiter en un seul passage: un pour le buffer profondeur, un pour les normals (en bas à gauche de l'image), un pour les couleurs &amp;quot;diffuse&amp;quot; (en bas à gauche) et un pour les couleurs &amp;quot;specular&amp;quot; (en haut à droite).&lt;br /&gt;
&lt;br /&gt;
;Le stade suivant est celui de l'ombre :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51735</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51735"/>
		<updated>2012-07-14T18:19:20Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* TODO List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Add some kind of fog to lights&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Move effect of cloud coverage from water shader to sunlight shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51734</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51734"/>
		<updated>2012-07-14T18:17:19Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Near term tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Fix Lights in multi screen (seems same problem than shadows. Forgot a 1/w factor ?)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;br /&gt;
[[fr:Projet Rembrandt]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51660</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51660"/>
		<updated>2012-07-08T18:00:54Z</updated>

		<summary type="html">&lt;p&gt;Fredb: References&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
== Appendix ==&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://directtovideo.wordpress.com/2009/11/13/deferred-rendering-in-frameranger/ |title=deferred rendering in frameranger. |author=Matt Swoboda |date=13 November 2009 |accessdate=8 July 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51499</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51499"/>
		<updated>2012-07-04T09:43:26Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Completed tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
*Global strength of glow or ambient occlusion via slider in rendering dialog&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51498</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51498"/>
		<updated>2012-07-04T09:41:44Z</updated>

		<summary type="html">&lt;p&gt;Fredb: Restructure TODO List&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*Fix shadow rendering when using multi threading in OSG&lt;br /&gt;
*Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)&lt;br /&gt;
*Honor 'noshadow' animation (done)&lt;br /&gt;
*See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*Test multi-screen (mostly done)&lt;br /&gt;
*Restore splashscreen&lt;br /&gt;
*Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)&lt;br /&gt;
*Add spotlights as animations (nearly finished)&lt;br /&gt;
*find a solution for ambient and emissive color of material (may need an additional buffer)&lt;br /&gt;
*Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT &lt;br /&gt;
*Use stencil buffer to limit light range(no - done in light shader)&lt;br /&gt;
**needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&lt;br /&gt;
*Use effect system instead of hard-coded shaders&lt;br /&gt;
*Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)&lt;br /&gt;
*Tidy up the architecture (done)&lt;br /&gt;
&lt;br /&gt;
*Fix dim-factor in multiplayer mode (done)&lt;br /&gt;
*Design and implement a configurable pipeline (done)&lt;br /&gt;
*Document rendering pipeline configuration file format (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51497</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51497"/>
		<updated>2012-07-04T09:35:11Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* &amp;quot;Merge in next&amp;quot; TODO List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):&lt;br /&gt;
* &amp;lt;code&amp;gt;--enable-rembrandt&amp;lt;/code&amp;gt; (when using [[FGRun]], you may add this behind the &amp;lt;tt&amp;gt;FG_EXECUTABLE&amp;lt;/tt&amp;gt; on the first page). &lt;br /&gt;
* &amp;lt;code&amp;gt;--prop:/sim/rendering/rembrandt/enabled=true&amp;lt;/code&amp;gt; (with FGRun this can be added via &amp;lt;tt&amp;gt;Advanced &amp;gt; Properties&amp;lt;/tt&amp;gt; on the last page).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Initial TODO List ==&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix shadow rendering when using multi threading in OSG&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night&amp;lt;/del&amp;gt;)&lt;br /&gt;
*&amp;lt;del&amp;gt;Honor 'noshadow' animation&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;See what happens with glow in fog&amp;lt;/del&amp;gt; : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*&amp;lt;del&amp;gt;Test multi-screen&amp;lt;/del&amp;gt; (mostly done)&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*&amp;lt;del&amp;gt;Restore splashscreen&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage)&amp;lt;/del&amp;gt; (OK - needs model contribution)&lt;br /&gt;
*&amp;lt;del&amp;gt;Add spotlights as animations (nearly finished)&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;find a solution for ambient and emissive color of material (may need an additional buffer)&amp;lt;/del&amp;gt;&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*&amp;lt;del&amp;gt;Provide a shader for transparent objects that could render to the emissive buffer too (using MRT)&amp;lt;/del&amp;gt; not doable. Light pass can't use MRT &lt;br /&gt;
*&amp;lt;del&amp;gt;Use stencil buffer to limit light range&amp;lt;/del&amp;gt;(no - done in light shader)&lt;br /&gt;
**&amp;lt;del&amp;gt;needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Use effect system instead of hard-coded shaders&amp;lt;/del&amp;gt;&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
**&amp;lt;del&amp;gt;Add new animation to link a light source to a model&amp;lt;/del&amp;gt; &amp;lt;del&amp;gt;(need to provide point light animation duplicating spot light)&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Tidy up the architecture&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
=== Completed tasks ===&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix dim-factor in multiplayer mode&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Design and implement a configurable pipeline&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Document rendering pipeline configuration file format&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
&lt;br /&gt;
=== Near term tasks ===&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
&lt;br /&gt;
=== Long term ideas (unsorted) ===&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51464</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51464"/>
		<updated>2012-06-30T14:53:57Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Initial TODO List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. Use the &amp;lt;tt&amp;gt;--enable-rembrandt&amp;lt;/tt&amp;gt; option to start FlightGear with this new renderer. The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Initial TODO List ==&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix shadow rendering when using multi threading in OSG&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night&amp;lt;/del&amp;gt;)&lt;br /&gt;
*&amp;lt;del&amp;gt;Honor 'noshadow' animation&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;See what happens with glow in fog&amp;lt;/del&amp;gt; : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*&amp;lt;del&amp;gt;Test multi-screen&amp;lt;/del&amp;gt; (mostly done)&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*&amp;lt;del&amp;gt;Restore splashscreen&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage)&amp;lt;/del&amp;gt; (OK - needs model contribution)&lt;br /&gt;
*&amp;lt;del&amp;gt;Add spotlights as animations (nearly finished)&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;find a solution for ambient and emissive color of material (may need an additional buffer)&amp;lt;/del&amp;gt;&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*&amp;lt;del&amp;gt;Provide a shader for transparent objects that could render to the emissive buffer too (using MRT)&amp;lt;/del&amp;gt; not doable. Light pass can't use MRT &lt;br /&gt;
*&amp;lt;del&amp;gt;Use stencil buffer to limit light range&amp;lt;/del&amp;gt;(no - done in light shader)&lt;br /&gt;
**&amp;lt;del&amp;gt;needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Use effect system instead of hard-coded shaders&amp;lt;/del&amp;gt;&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
*Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
**&amp;lt;del&amp;gt;Add new animation to link a light source to a model&amp;lt;/del&amp;gt; &amp;lt;del&amp;gt;(need to provide point light animation duplicating spot light)&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Tidy up the architecture&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Merge in next&amp;quot; TODO List ==&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix dim-factor in multiplayer mode&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*&amp;lt;del&amp;gt;Design and implement a configurable pipeline&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*&amp;lt;del&amp;gt;Document rendering pipeline configuration file format&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51463</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51463"/>
		<updated>2012-06-30T14:52:36Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* Initial TODO List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. Use the &amp;lt;tt&amp;gt;--enable-rembrandt&amp;lt;/tt&amp;gt; option to start FlightGear with this new renderer. The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Initial TODO List ==&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix shadow rendering when using multi threading in OSG&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night&amp;lt;/del&amp;gt;)&lt;br /&gt;
*&amp;lt;del&amp;gt;Honor 'noshadow' animation&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;See what happens with glow in fog&amp;lt;/del&amp;gt; : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*&amp;lt;del&amp;gt;Test multi-screen&amp;lt;/del&amp;gt; (mostly done)&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*&amp;lt;del&amp;gt;Restore splashscreen&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage)&amp;lt;/del&amp;gt; (OK - needs model contribution)&lt;br /&gt;
*&amp;lt;del&amp;gt;Add spotlights as animations (nearly finished)&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;find a solution for ambient and emissive color of material (may need an additional buffer)&amp;lt;/del&amp;gt;&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*&amp;lt;del&amp;gt;Provide a shader for transparent objects that could render to the emissive buffer too (using MRT)&amp;lt;/del&amp;gt; not doable. Light pass can't use MRT &lt;br /&gt;
*&amp;lt;del&amp;gt;Use stencil buffer to limit light range&amp;lt;/del&amp;gt;(no - done in light shader)&lt;br /&gt;
**&amp;lt;del&amp;gt;needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Use effect system instead of hard-coded shaders&amp;lt;/del&amp;gt;&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
**Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
**&amp;lt;del&amp;gt;Add new animation to link a light source to a model&amp;lt;/del&amp;gt; &amp;lt;del&amp;gt;(need to provide point light animation duplicating spot light)&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Tidy up the architecture&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Merge in next&amp;quot; TODO List ==&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix dim-factor in multiplayer mode&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*&amp;lt;del&amp;gt;Design and implement a configurable pipeline&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*&amp;lt;del&amp;gt;Document rendering pipeline configuration file format&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51191</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51191"/>
		<updated>2012-06-26T08:13:02Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* &amp;quot;Merge in next&amp;quot; TODO List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. Use the &amp;lt;tt&amp;gt;--enable-rembrandt&amp;lt;/tt&amp;gt; option to start FlightGear with this new renderer. The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Initial TODO List ==&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix shadow rendering when using multi threading in OSG&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night&amp;lt;/del&amp;gt;)&lt;br /&gt;
*Honor &amp;lt;noshadow&amp;gt; animation directive&lt;br /&gt;
*&amp;lt;del&amp;gt;See what happens with glow in fog&amp;lt;/del&amp;gt; : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*&amp;lt;del&amp;gt;Test multi-screen&amp;lt;/del&amp;gt; (mostly done)&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*&amp;lt;del&amp;gt;Restore splashscreen&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage)&amp;lt;/del&amp;gt; (OK - needs model contribution)&lt;br /&gt;
*&amp;lt;del&amp;gt;Add spotlights as animations (nearly finished)&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;find a solution for ambient and emissive color of material (may need an additional buffer)&amp;lt;/del&amp;gt;&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*&amp;lt;del&amp;gt;Provide a shader for transparent objects that could render to the emissive buffer too (using MRT)&amp;lt;/del&amp;gt; not doable. Light pass can't use MRT &lt;br /&gt;
*&amp;lt;del&amp;gt;Use stencil buffer to limit light range&amp;lt;/del&amp;gt;(no - done in light shader)&lt;br /&gt;
**&amp;lt;del&amp;gt;needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Use effect system instead of hard-coded shaders&amp;lt;/del&amp;gt;&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
**Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
**&amp;lt;del&amp;gt;Add new animation to link a light source to a model&amp;lt;/del&amp;gt; &amp;lt;del&amp;gt;(need to provide point light animation duplicating spot light)&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Tidy up the architecture&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Merge in next&amp;quot; TODO List ==&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix dim-factor in multiplayer mode&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*&amp;lt;del&amp;gt;Design and implement a configurable pipeline&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*&amp;lt;del&amp;gt;Document rendering pipeline configuration file format&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51190</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51190"/>
		<updated>2012-06-26T08:12:34Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* &amp;quot;Merge in next&amp;quot; TODO List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. Use the &amp;lt;tt&amp;gt;--enable-rembrandt&amp;lt;/tt&amp;gt; option to start FlightGear with this new renderer. The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Initial TODO List ==&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix shadow rendering when using multi threading in OSG&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night&amp;lt;/del&amp;gt;)&lt;br /&gt;
*Honor &amp;lt;noshadow&amp;gt; animation directive&lt;br /&gt;
*&amp;lt;del&amp;gt;See what happens with glow in fog&amp;lt;/del&amp;gt; : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*&amp;lt;del&amp;gt;Test multi-screen&amp;lt;/del&amp;gt; (mostly done)&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*&amp;lt;del&amp;gt;Restore splashscreen&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage)&amp;lt;/del&amp;gt; (OK - needs model contribution)&lt;br /&gt;
*&amp;lt;del&amp;gt;Add spotlights as animations (nearly finished)&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;find a solution for ambient and emissive color of material (may need an additional buffer)&amp;lt;/del&amp;gt;&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*&amp;lt;del&amp;gt;Provide a shader for transparent objects that could render to the emissive buffer too (using MRT)&amp;lt;/del&amp;gt; not doable. Light pass can't use MRT &lt;br /&gt;
*&amp;lt;del&amp;gt;Use stencil buffer to limit light range&amp;lt;/del&amp;gt;(no - done in light shader)&lt;br /&gt;
**&amp;lt;del&amp;gt;needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Use effect system instead of hard-coded shaders&amp;lt;/del&amp;gt;&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
**Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
**&amp;lt;del&amp;gt;Add new animation to link a light source to a model&amp;lt;/del&amp;gt; &amp;lt;del&amp;gt;(need to provide point light animation duplicating spot light)&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Tidy up the architecture&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Merge in next&amp;quot; TODO List ==&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix dim-factor in multiplayer mode&amp;lt;/del&amp;gt;(done)&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*&amp;lt;del&amp;gt;Design and implement a configurable pipeline&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*&amp;lt;del&amp;gt;Document rendering pipeline configuration file format&amp;lt;/del&amp;gt;(done)&lt;br /&gt;
*Fix fog on clouds&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51189</id>
		<title>Project Rembrandt</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Project_Rembrandt&amp;diff=51189"/>
		<updated>2012-06-26T08:11:22Z</updated>

		<summary type="html">&lt;p&gt;Fredb: /* &amp;quot;Merge in next&amp;quot; TODO List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
== Why this name ? ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Rembrandt Rembrandt] was a dutch painter living in the 17th century, famous as one of the master of [http://en.wikipedia.org/wiki/Chiaroscuro chiaroscuro].&lt;br /&gt;
&lt;br /&gt;
This project is about changing the way [[FlightGear]] renders lights, [[shadows]] and shades, and aims at making Rembrandt painting style possible in FG.&lt;br /&gt;
&lt;br /&gt;
== What is it ? ==&lt;br /&gt;
The idea driving the project is to implement [http://en.wikipedia.org/wiki/Deferred_shading deferred rendering] inside FlightGear.&lt;br /&gt;
From the beginning FlightGear had a forward renderer that tries to render all properties of an object in one pass (shading, lighting, fog, ...), making it difficult to render more sophisticated shading &lt;br /&gt;
(see the [[FlightGear Newsletter December 2011#Shaders|'Uber-shader']]) because one has to take into account all aspects of the [http://www.wired.com/magazine/2010/07/st_equation_3danimation/ rendering equation].&lt;br /&gt;
&lt;br /&gt;
[[Image:project_rembrandt_1.png|thumb|300px|Main view with the content of buffers displayed at corners]]&lt;br /&gt;
On the contrary, deferred rendering is about separating operations in simplified stages and collecting the intermediary results in hidden buffers that can be used by the next stage.&lt;br /&gt;
&lt;br /&gt;
;First stage is the Geometry Stage :&lt;br /&gt;
: we render all the scene into 4 textures, using multi render targets, to do it in one pass: one for the depth buffer, one for the normals (lower left of the image), one for the diffuse colors (lower right) and one for the specular colors (upper right).&lt;br /&gt;
&lt;br /&gt;
;Next stage is the Shadow Stage :&lt;br /&gt;
: we render the scene again into a depth texture from the point of view of the lights. There will be one texture for every light casting shadows.&lt;br /&gt;
&lt;br /&gt;
;Then comes the Lighting Stage, with several substages :&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sky pass&amp;lt;/u&amp;gt;: the sky is first drawn using classical method.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Ambient pass&amp;lt;/u&amp;gt;: the diffuse buffer is modulated with the ambient color of the scene and is drawn as a screen-aligned textured quad&lt;br /&gt;
:*&amp;lt;u&amp;gt;Sunlight pass&amp;lt;/u&amp;gt;: a second screen aligned quad is drawn and a shader computes the view position of every pixel to compute its diffuse and specular color, using the normal stored in the first stage. The resulting color is blended with the previous pass. Shadows are computed here by comparing the position of the pixel with the position of the light occluder stored in the shadow map.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Additional light pass&amp;lt;/u&amp;gt;: the scene graph will be traversed another time to display light volumes (cone or frusta for spot lights, sphere for omni-directional lights) and their shader will add the light contributed by the source only on pixels receiving light.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Fog pass&amp;lt;/u&amp;gt;: a new screen aligned quad is draw and the position of the pixel is computed to evaluate the amount of fog the pixel has. The fog color is blended with the result of the previous stage.&lt;br /&gt;
:*&amp;lt;u&amp;gt;Transparent objects pass&amp;lt;/u&amp;gt;: transparent objects (and clouds) are finally rendered using classical method.&lt;br /&gt;
&lt;br /&gt;
:All lighting computations are accumulated in a single buffer that will be used for the last stage, in addition of the one computed by the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
;In the end, the Display Stage, with optional Post-Processing effect :&lt;br /&gt;
:The results of the previous buffers are pushed to the main framebuffer to be displayed, optionally modified to show Glow, Motion blur, HDR, redout or blackout, screen-space ambient occlusion, anti-aliasing, etc...&lt;br /&gt;
&lt;br /&gt;
In FG, we end the rendering pipeline by displaying the [[Menubar|GUI]] and the [[HUD]].&lt;br /&gt;
&lt;br /&gt;
All these stages are more precisely described if this [http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf tutorial] that is the basis of the current code, with some addition and modifications.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
Deferred rendering is not able to display transparency. For the moment, clouds are renderer separately and should be lit and shaded by their own. Transparent surfaces are alpha-tested and not blended. They would have to be drawn in their own bin over the composited image.&lt;br /&gt;
&lt;br /&gt;
It also don't fit with depth partitioning because the depth buffer should be kept to retain the view space position, so for the moment, z-fighting is quite visible. Depth partitioning with non overlapping depth range might be the solution and should be experimented at one point.&lt;br /&gt;
&lt;br /&gt;
The glow pass can make certain MFD (that use emissive color) unreadable because blurred. Should be treated as transparent.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
=== Repositories ===&lt;br /&gt;
The code is in the main branch of the [[FlightGear and Git|official repository]]. Any other location is not maintained anymore.&lt;br /&gt;
&lt;br /&gt;
=== Rendering of transparent surfaces ===&lt;br /&gt;
[[Image:project_rembrandt_5.png|thumb|300px|Transparent surfaces drawn after opaque objects]]&lt;br /&gt;
Transparent surfaces are detected by OSG loader plugins and their state set receive the TRANSPARENT_BIN rendering hint. In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.&lt;br /&gt;
&lt;br /&gt;
=== Memory consumption ===&lt;br /&gt;
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :&lt;br /&gt;
* G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb&lt;br /&gt;
* Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb&lt;br /&gt;
Not counting textures, display list or vertex buffers for models and terrain&lt;br /&gt;
&lt;br /&gt;
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.&lt;br /&gt;
&lt;br /&gt;
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;map-size type=&amp;quot;int&amp;quot;&amp;gt;8192&amp;lt;/map-size&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And put 4096 or 2048 instead.&lt;br /&gt;
You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048&lt;br /&gt;
&lt;br /&gt;
=== Configurable pipeline ===&lt;br /&gt;
&lt;br /&gt;
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :&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;!-- BUFFERS --&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth buffer definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- STAGES --&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- First stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;!-- nth stage definition --&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/PropertyList&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Buffers ====&lt;br /&gt;
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;buffer&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;buffer-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;internal-format&amp;gt;rgba8&amp;lt;/internal-format&amp;gt; &amp;lt;!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-format&amp;gt;rgba&amp;lt;/source-format&amp;gt; &amp;lt;!-- rg, rgb, rgba, depth-component or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;source-type&amp;gt;unsigned-byte&amp;lt;/source-type&amp;gt; &amp;lt;!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;width&amp;gt;screen&amp;lt;/width&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/width/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;height&amp;gt;screen&amp;lt;/height&amp;gt; &amp;lt;!-- screen, value or &amp;lt;property&amp;gt;/a/height/property&amp;lt;/property&amp;gt; --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;1.0&amp;lt;/scale-factor&amp;gt;&lt;br /&gt;
		&amp;lt;wrap-mode&amp;gt;clamp-to-border&amp;lt;/wrap-mode&amp;gt; &amp;lt;!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value --&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional, for shadow map --&amp;gt;&lt;br /&gt;
		&amp;lt;shadow-comparison&amp;gt;true&amp;lt;/shadow-comparison&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/buffer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Stages ====&lt;br /&gt;
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Stage type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|geometry&lt;br /&gt;
|The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers.&lt;br /&gt;
|-&lt;br /&gt;
|shadow&lt;br /&gt;
|In this stage, the geometry is rendered in the normal map from the perspective of the sun.&lt;br /&gt;
|-&lt;br /&gt;
|lighting&lt;br /&gt;
|This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects.&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Stages of this type are used to alter the whole scene or transform data from a particular buffer.&lt;br /&gt;
|-&lt;br /&gt;
|display&lt;br /&gt;
|Final rendering of the scene to the screen or the texture defined in the camera group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A stage description is outlined below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;stage&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;stage-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;stage-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;needs-du-dv&amp;gt;true&amp;lt;/needs-du-dv&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;scale-factor&amp;gt;0.25&amp;lt;/scale-factor&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
		&amp;lt;attachment&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth attachment definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- Passes only for the lighting stage --&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- First pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
		&amp;lt;pass&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Nth pass definition --&amp;gt;&lt;br /&gt;
		&amp;lt;/pass&amp;gt;&lt;br /&gt;
	&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.&lt;br /&gt;
&lt;br /&gt;
===== Attachments =====&lt;br /&gt;
Attachment describe bindings between buffer and attachment point :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;attachment&amp;gt;&lt;br /&gt;
		&amp;lt;component&amp;gt;color0&amp;lt;/component&amp;gt; &amp;lt;!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 --&amp;gt;&lt;br /&gt;
		&amp;lt;buffer&amp;gt;buffer-name&amp;lt;/buffer&amp;gt;&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/attachment&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Passes =====&lt;br /&gt;
Passes are only available in the &amp;lt;tt&amp;gt;lighting&amp;lt;/tt&amp;gt; stage. Three kind of stage are allowed :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Pass type&lt;br /&gt;
!align=&amp;quot;left&amp;quot;| Purpose&lt;br /&gt;
|-&lt;br /&gt;
|sky-clouds&lt;br /&gt;
|Renders the skydome, sun, moon, planet, stars and clouds&lt;br /&gt;
|-&lt;br /&gt;
|lights&lt;br /&gt;
|Renders additional spot and point lights&lt;br /&gt;
|-&lt;br /&gt;
|fullscreen&lt;br /&gt;
|Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage&lt;br /&gt;
|}&lt;br /&gt;
A pass is defined like below :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;pass&amp;gt;&lt;br /&gt;
		&amp;lt;name&amp;gt;pass-name&amp;lt;/name&amp;gt;&lt;br /&gt;
		&amp;lt;type&amp;gt;pass-type&amp;lt;/type&amp;gt; &amp;lt;!-- optional if name is one of the predefined type except fullscreen --&amp;gt;&lt;br /&gt;
		&amp;lt;order-num&amp;gt;-1&amp;lt;/order-num&amp;gt;&lt;br /&gt;
		&amp;lt;effect&amp;gt;Effects/fullscreen-effect&amp;lt;/effect&amp;gt; &amp;lt;!-- only if type == fullscreen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;!-- optional condition --&amp;gt;&lt;br /&gt;
		&amp;lt;condition&amp;gt;&lt;br /&gt;
			&amp;lt;!-- Valid boolean expression --&amp;gt;&lt;br /&gt;
		&amp;lt;/condition&amp;gt;&lt;br /&gt;
	&amp;lt;/pass&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A typical lighting stage is a succession of 5 passes :&lt;br /&gt;
# &amp;lt;tt&amp;gt;sky-clouds&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for ambient light&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for sun light (and shadows)&lt;br /&gt;
# &amp;lt;tt&amp;gt;lights&amp;lt;/tt&amp;gt; pass&lt;br /&gt;
# &amp;lt;tt&amp;gt;fullscreen&amp;lt;/tt&amp;gt; pass for fog&lt;br /&gt;
&lt;br /&gt;
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.&lt;br /&gt;
&lt;br /&gt;
== Running Flightgear with Rembrandt ==&lt;br /&gt;
[[File:Rembrandt dialog.png|thumb|270px|Rembrandt dialog]]&lt;br /&gt;
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. Use the &amp;lt;tt&amp;gt;--enable-rembrandt&amp;lt;/tt&amp;gt; option to start FlightGear with this new renderer. The &amp;lt;tt&amp;gt;View &amp;gt; Rendering Options &amp;gt; Rembrandt Options&amp;lt;/tt&amp;gt; dialog allows you to toggle and adjust the various features that Rembrandt offers.&lt;br /&gt;
&lt;br /&gt;
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :&lt;br /&gt;
&lt;br /&gt;
 RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6&lt;br /&gt;
 Warning: RenderStage::runCameraSetUp(State&amp;amp;) Pbuffer does not support multiple color outputs.&lt;br /&gt;
&lt;br /&gt;
Some card also exhibit messages like this :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram &amp;quot;&amp;quot; FAILED&lt;br /&gt;
 Program &amp;quot;&amp;quot; infolog:&lt;br /&gt;
 Fragment info&lt;br /&gt;
 -------------&lt;br /&gt;
 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable&lt;br /&gt;
&lt;br /&gt;
There is a number of additional options that can help to avoid these problems :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/use-color-for-depth=true&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in &amp;quot;fog curtains&amp;quot; at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/enabled=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Disable shadows altogether.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Avoid the &amp;quot;error C6013&amp;quot; message on old cards at the cost of resolution in the cockpit. Set &amp;lt;tt&amp;gt;/sim/rendering/shadows/cascade-far-m[0]&amp;lt;/tt&amp;gt; to change the shadow map range. The more the range, the less the resolution (default value is 5 meters)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/map-size=&amp;lt;power-of-two&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/shadows/cascade-far-m[i]&amp;lt;/tt&amp;gt;&lt;br /&gt;
(1 &amp;lt;= i &amp;lt;= &amp;lt;tt&amp;gt;/sim/rendering/shadows/num-cascades&amp;lt;/tt&amp;gt; &amp;lt;= 4)&lt;br /&gt;
|Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;--prop:/sim/rendering/rembrandt/no-16bit-buffer=false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for shader writers ==&lt;br /&gt;
=== Predefined uniforms ===&lt;br /&gt;
These glsl uniforms don't need to be declared in the effect file.&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 the screen position to view direction&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 the screen position to view direction&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 used to transform the screen position to view direction&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;
|&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;
|&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;
|&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;
|&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&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&lt;br /&gt;
|}&lt;br /&gt;
They still have to be declared in the fragment or the vertex shader to be used.&lt;br /&gt;
&lt;br /&gt;
=== Utility functions ===&lt;br /&gt;
&lt;br /&gt;
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-encode.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to encode all the values of the G-Buffer in material shaders&lt;br /&gt;
&lt;br /&gt;
==== gbuffer-functions.frag ====&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec2 normal_encode(vec3 n)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Used to compress normals into the G-Buffer in material shaders. Normally called from &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 normal_decode(vec2 enc)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 float_to_color(in float f)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;encode_gbuffer()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;float color_to_float(vec3 color)&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by &amp;lt;tt&amp;gt;position()&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt; is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, float depth )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec3 depthColor )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of &amp;lt;tt&amp;gt;/sim/rendering/use-color-for_depth&amp;lt;/tt&amp;gt;) at a given fragment on screen, given by &amp;lt;tt&amp;gt;coords&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Usage ====&lt;br /&gt;
&lt;br /&gt;
For material shaders, it is necessary to provide both &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gbuffer-encode.frag&amp;lt;/tt&amp;gt; in the effect file, 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;Shaders/ubershader.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/ubershader-gbuffer.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-encode.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;
For fullscreen passes shaders, only &amp;lt;tt&amp;gt;gbuffer-functions.frag&amp;lt;/tt&amp;gt; should be provided, 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;Shaders/sunlight.vert&amp;lt;/vertex-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/sunlight.frag&amp;lt;/fragment-shader&amp;gt;&lt;br /&gt;
		&amp;lt;fragment-shader&amp;gt;Shaders/gbuffer-functions.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;
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);&lt;br /&gt;
&lt;br /&gt;
main() {&lt;br /&gt;
    vec3 normal;&lt;br /&gt;
    vec3 color;&lt;br /&gt;
    int mId;&lt;br /&gt;
    float specular;&lt;br /&gt;
    float shininess;&lt;br /&gt;
    float emission;&lt;br /&gt;
    float depth;&lt;br /&gt;
&lt;br /&gt;
    // Do shader computations&lt;br /&gt;
&lt;br /&gt;
    encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geometry Stage ===&lt;br /&gt;
The Geometry Stage is there to fill the G-buffer. '''Shading doesn't occur at this stage, so light or fog computation should not be part of the shader'''. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|depth (gl_FragDepth)||GL_DEPTH_COMPONENT32||colspan=&amp;quot;4&amp;quot;|Fragment depth&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[0]||GL_RG16||colspan=&amp;quot;2&amp;quot;|normal.x * 0.5 + 0.5||colspan=&amp;quot;2&amp;quot;|normal.y * 0.5 + 0.5&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[1]||GL_RGBA8||diffuse.r||diffuse.g||diffuse.b||material id * 1/255.0&lt;br /&gt;
|-&lt;br /&gt;
|gl_FragData[2]||GL_RGBA8||specular.l||specular.s||emission.l||pixel valid if != 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#Depth buffer, modified with gl_FragDepth, will record the distance between the fragment and the camera. Default behavior is to avoid to touch it, living the GPU rasterizer doing sensible things by interpolating vertex gl_Position from the Vertex or the Geometry Shader. If altering the computed depth is required, like in the Urban shader, the value of gl_FragDepth should be set.&lt;br /&gt;
#Normal buffer, modified with gl_FragData[0].xyz, will record the normal of the fragment in eye coordinates. gl_FragData[0].w is reserved for future use. The interpolated normal is usually simply stored but bump mapping or relief mapping affecting the normal can be computed here.&lt;br /&gt;
#Diffuse color buffer, modified with gl_FragData[1].rgb, will hold the unshaded color of the fragment, usually modulating the material diffuse+ambient color with the texture map. Diffuse color from environment mapping should also go here.&lt;br /&gt;
#Specular color, modified with gl_FragData[2].rgb, and specular shininess in gl_FragData[2].a, will retain the specular color of the fragment.&lt;br /&gt;
#Emission color, modified with gl_FragData[3].rgb&lt;br /&gt;
In anyway, don't use gl_FragColor as it is incompatible with MRT (Multi Render Target) and would affect the four last buffers with the same value. In that case, the model will glow (emission buffer initialized) and parts will disappear at certain view angles because normals are not initialized properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;font-size:1.5em;font-weight:bold&amp;quot;&amp;gt;This layout is going to change in the official repository when the merge will be done. The goal of this change is to fill more useful data into less texture memory and get rid of a stupid IP issue on float textures&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional light pass ===&lt;br /&gt;
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.&lt;br /&gt;
&lt;br /&gt;
=== Fog Pass ===&lt;br /&gt;
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.&lt;br /&gt;
&lt;br /&gt;
=== Bloom Pass ===&lt;br /&gt;
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.&lt;br /&gt;
&lt;br /&gt;
=== Required Effects ===&lt;br /&gt;
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Kind&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ssao&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Compute ambient occlusion from the normal buffer and the depth buffer&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/light-spot&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on real geometry of the light volume&lt;br /&gt;
|Computes the light contribution of a spot light defined in a &amp;lt;tt&amp;gt;light&amp;lt;/tt&amp;gt; animation having a &amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt; of '''&amp;lt;tt&amp;gt;spot&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/fog&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Computes the fog from the G-buffer and the lighting parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;Effects/display&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Works on a full screen quad&lt;br /&gt;
|Renders the composite final image from the G-buffer and the lighting buffer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guidelines for modelers ==&lt;br /&gt;
&lt;br /&gt;
=== Porting aircraft ===&lt;br /&gt;
* Rembrandt computes shadows =&amp;gt; no more fake shadows in the model&lt;br /&gt;
* Rembrandt computes ambient occlusion =&amp;gt; no ambient occlusion baked into textures&lt;br /&gt;
* Rembrandt has light =&amp;gt; static lightmap are not needed, emissive color to see models at night is not needed and would interfere&lt;br /&gt;
* Rembrandt has glow =&amp;gt; incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted&lt;br /&gt;
* Rembrandt has strict needs with shaders =&amp;gt; shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong&lt;br /&gt;
* Rembrandt can't do transparent surfaces =&amp;gt; transparent surface need to be properly registered to render them with the classical path&lt;br /&gt;
&lt;br /&gt;
=== Registering all translucent surfaces ===&lt;br /&gt;
&lt;br /&gt;
Every model is, by default, rendered using the &amp;lt;tt&amp;gt;Effects/model-default&amp;lt;/tt&amp;gt; effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.&lt;br /&gt;
&lt;br /&gt;
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to &amp;quot;DepthSortedBin&amp;quot;, or sets the rendering hint to &amp;quot;transparent&amp;quot;. This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The &amp;lt;tt&amp;gt;Effects/model-transparent&amp;lt;/tt&amp;gt; can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:&lt;br /&gt;
 &amp;lt;effect&amp;gt;&lt;br /&gt;
  &amp;lt;inherits-from&amp;gt;Effects/model-transparent&amp;lt;/inherits-from&amp;gt;&lt;br /&gt;
  &amp;lt;object-name&amp;gt;TheObject&amp;lt;/object-name&amp;gt;&lt;br /&gt;
 &amp;lt;/effect&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the &amp;quot;RenderBin&amp;quot; bin, or the rendering hint set to &amp;quot;opaque&amp;quot;, and the G-buffer needs to be initialized correctly in the Geometry stage.&lt;br /&gt;
&lt;br /&gt;
=== Adding lights to a model ===&lt;br /&gt;
&lt;br /&gt;
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.&lt;br /&gt;
&lt;br /&gt;
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.&lt;br /&gt;
&lt;br /&gt;
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.&lt;br /&gt;
&lt;br /&gt;
All available animations are possible on the light volume, except '''material''' and '''texture'''. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.&lt;br /&gt;
&lt;br /&gt;
==== Spotlights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;spot&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&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;-0.9988&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.0349&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;-0.0349&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;exponent&amp;gt;30.0&amp;lt;/exponent&amp;gt;&lt;br /&gt;
   &amp;lt;cutoff&amp;gt;39&amp;lt;/cutoff&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''spot'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a cone with an apex at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, along &amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt; axis if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is lesser than 90 degrees, or a sphere centered at &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt; is greater than 90 degrees )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;direction&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, direction to the center of the spot&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;exponent&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Attenuation is multiplied by &amp;lt;tt&amp;gt;pow( dot( lightDir, &amp;lt;direction&amp;gt; ), &amp;lt;exponent&amp;gt; )&amp;lt;/tt&amp;gt;, lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;cutoff&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Point is lit by this source if &amp;lt;tt&amp;gt;dot( lightDir, &amp;lt;direction&amp;gt; ) &amp;gt; &amp;lt;cutoff&amp;gt;&amp;lt;/tt&amp;gt; , lightDir being vector from light position to point, in camera space.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Point lights ====&lt;br /&gt;
{|cellpadding=10|&lt;br /&gt;
|valign=top|&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;light&amp;lt;/type&amp;gt;&lt;br /&gt;
   &amp;lt;light-type&amp;gt;point&amp;lt;/light-type&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;LightSrcRight&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;object-name&amp;gt;LightRight&amp;lt;/object-name&amp;gt;&lt;br /&gt;
   &amp;lt;nopreview/&amp;gt;&lt;br /&gt;
   &amp;lt;position&amp;gt;&lt;br /&gt;
     &amp;lt;x&amp;gt;0.169&amp;lt;/x&amp;gt;&lt;br /&gt;
     &amp;lt;y&amp;gt;0.570&amp;lt;/y&amp;gt;&lt;br /&gt;
     &amp;lt;z&amp;gt;0.713&amp;lt;/z&amp;gt;&lt;br /&gt;
   &amp;lt;/position&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.0&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.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.6&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;/diffuse&amp;gt;&lt;br /&gt;
   &amp;lt;specular&amp;gt;&lt;br /&gt;
     &amp;lt;r&amp;gt;0.7&amp;lt;/r&amp;gt;&lt;br /&gt;
     &amp;lt;g&amp;gt;0.7&amp;lt;/g&amp;gt;&lt;br /&gt;
     &amp;lt;b&amp;gt;0.7&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;/specular&amp;gt;&lt;br /&gt;
   &amp;lt;dim-factor&amp;gt;&lt;br /&gt;
      &amp;lt;property&amp;gt;dimming/property&amp;lt;/property&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional begin --&amp;gt;&lt;br /&gt;
      &amp;lt;expression /&amp;gt;&lt;br /&gt;
      &amp;lt;interpolation /&amp;gt;&lt;br /&gt;
      &amp;lt;factor&amp;gt;1&amp;lt;/factor&amp;gt;&lt;br /&gt;
      &amp;lt;offset&amp;gt;0&amp;lt;/offset&amp;gt;&lt;br /&gt;
      &amp;lt;min&amp;gt;0&amp;lt;/min&amp;gt;&lt;br /&gt;
      &amp;lt;max&amp;gt;1&amp;lt;/max&amp;gt;&lt;br /&gt;
      &amp;lt;!-- optional end --&amp;gt;&lt;br /&gt;
   &amp;lt;/dim-factor&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.002&amp;lt;/l&amp;gt;&lt;br /&gt;
     &amp;lt;q&amp;gt;0.00005&amp;lt;/q&amp;gt;&lt;br /&gt;
   &amp;lt;/attenuation&amp;gt;&lt;br /&gt;
   &amp;lt;near-m&amp;gt;3.5&amp;lt;/near-m&amp;gt;&lt;br /&gt;
   &amp;lt;far-m&amp;gt;39&amp;lt;/far-m&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|valign=top|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Purpose&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Install the &amp;lt;tt&amp;gt;'''light'''&amp;lt;/tt&amp;gt; animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;light-type&amp;lt;/tt&amp;gt;&lt;br /&gt;
|This is a &amp;lt;tt&amp;gt;'''point'''&amp;lt;/tt&amp;gt; light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name given to this animation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;object-name&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Name of the light volume in the 3d model (typically a sphere centered on &amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;, with a radius of &amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;nopreview&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Hide light volume in fgrun 3d preview&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;&lt;br /&gt;
|In object space, position of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;ambient&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Ambient color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;diffuse&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Diffuse color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;specular&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Specular color of the light&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;dim-factor&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Group of parameters to control a factor that is applied to ambient, diffuse and specular at the same time&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;attenuation&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Three element vector. &amp;lt;c&amp;gt; element is the constant factor, &amp;lt;l&amp;gt; element is the linear factor and &amp;lt;q&amp;gt; element is the quadratic factor.&amp;lt;br /&amp;gt;&lt;br /&gt;
Attenuation of color at distance d is [[File:Spotlight_attenuation.png]]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;near-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Minimum distance of influence, from position, in meters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;far-m&amp;lt;/tt&amp;gt;&lt;br /&gt;
|Maximum distance of influence, from position, in meters&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Initial TODO List ==&lt;br /&gt;
*&amp;lt;del&amp;gt;Fix shadow rendering when using multi threading in OSG&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night&amp;lt;/del&amp;gt;)&lt;br /&gt;
*Honor &amp;lt;noshadow&amp;gt; animation directive&lt;br /&gt;
*&amp;lt;del&amp;gt;See what happens with glow in fog&amp;lt;/del&amp;gt; : unknown landclass creates white patches in the emission buffer - scenery generation problem&lt;br /&gt;
*&amp;lt;del&amp;gt;Test multi-screen&amp;lt;/del&amp;gt; (mostly done)&lt;br /&gt;
*Fix shadow matrices in multi-screen&lt;br /&gt;
*&amp;lt;del&amp;gt;Restore splashscreen&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage)&amp;lt;/del&amp;gt; (OK - needs model contribution)&lt;br /&gt;
*&amp;lt;del&amp;gt;Add spotlights as animations (nearly finished)&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;find a solution for ambient and emissive color of material (may need an additional buffer)&amp;lt;/del&amp;gt;&lt;br /&gt;
*implement strength of glow (in the emissive buffer alpha channel)&lt;br /&gt;
**provide levels 0 to 5 - we are currently at level 5&lt;br /&gt;
**level 0 should be ok for MFDs that are currenly unreadable because blurred&lt;br /&gt;
*&amp;lt;del&amp;gt;Provide a shader for transparent objects that could render to the emissive buffer too (using MRT)&amp;lt;/del&amp;gt; not doable. Light pass can't use MRT &lt;br /&gt;
*&amp;lt;del&amp;gt;Use stencil buffer to limit light range&amp;lt;/del&amp;gt;(no - done in light shader)&lt;br /&gt;
**&amp;lt;del&amp;gt;needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe&amp;lt;/del&amp;gt;&lt;br /&gt;
*&amp;lt;del&amp;gt;Use effect system instead of hard-coded shaders&amp;lt;/del&amp;gt;&lt;br /&gt;
*Convert existing shaders to deferred rendering&lt;br /&gt;
**Modify shadows to allow multiple casters (limited list)&lt;br /&gt;
**Implement a priority list of light sources, based on priority and distance from the viewer&lt;br /&gt;
**&amp;lt;del&amp;gt;Add new animation to link a light source to a model&amp;lt;/del&amp;gt; &amp;lt;del&amp;gt;(need to provide point light animation duplicating spot light)&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*&amp;lt;del&amp;gt;Tidy up the architecture&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Restore depth partitioning using depth ranges&lt;br /&gt;
*Restore stereo and other options currently available in CameraGroup&lt;br /&gt;
*Implement quality vs performance user control&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Merge in next&amp;quot; TODO List ==&lt;br /&gt;
*Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.&lt;br /&gt;
*Fix dim-factor in multiplayer mode&lt;br /&gt;
*take care of particles and precipitation&lt;br /&gt;
*&amp;lt;del&amp;gt;Design and implement a configurable pipeline&amp;lt;/del&amp;gt; (done)&lt;br /&gt;
*Implement lightfield shader&lt;br /&gt;
*Document rendering pipeline configuration file format&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
{{#ev:youtube|PXHhtQb5yzc}} {{#ev:youtube|peEzEapavkg}} {{#ev:youtube|RIetPh8iJXk}} {{#ev:youtube|oaNFrxgQY1c}} {{#ev:youtube|8xGzy12hlis}} {{#ev:youtube|ZyuHBlm3xXU}} {{#ev:youtube|RgH9GZRukOI}} {{#ev:youtube|UQvbHnBkpaM}} {{#ev:youtube|v02phoOqWHE}}{{#ev:youtube|dlSo4sBa7Nk}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix|all|&lt;br /&gt;
* {{cite web |url=http://http.download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf |title=Deferred Shading |author=Shawn Hargreaves and Mark Harris }}&lt;br /&gt;
* {{cite web |url=http://bat710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf |title=Deferred Shading Tutorial |author=Fabio Policarpo and Francisco Fonseca }}&lt;br /&gt;
* {{cite web |url=http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf |title=Deferred Rendering in Killzone 2 |author=Michal Valient |month=July |year=2007 }}&lt;br /&gt;
* {{cite web |url=http://www.anandtech.com/show/5011/nvidiaea-posts-battlefield-3-graphics-tech-talk |title=Battlefield 3 Graphics Tech Talk |author=Johan Andersson |month=October |year=2011 }}&lt;br /&gt;
* {{cite web |url=http://www.disney.co.uk/cms_res/blackrockstudio/pdf/Rendering_Techniques_in_SplitSecond.pdf |title=Rendering Techniques in Split/Second |author=Jeremy Moore and David Jefferies |year=2009 }}&lt;br /&gt;
* {{cite web |url=http://www.crytek.com/sites/default/files/A_bit_more_deferred_-_CryEngine3.ppt |title=&amp;quot;A bit more Deferred&amp;quot; - CryEngine 3 (PPT) |author=Martin Mittring }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html |title=Deferred Shading in S.T.A.L.K.E.R. |author=Oles Shishkovtsov }}&lt;br /&gt;
* {{cite web |url=http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html |title=Deferred Shading in Tabula Rasa |author=Rusty Koonce }}&lt;br /&gt;
* {{cite web |url=http://aras-p.info/texts/CompactNormalStorage.html |title=Compact Normal Storage for small g-buffers |author=Aras Pranckevičius |date=4 August 2009 |accessdate=12 April 2012 }}&lt;br /&gt;
* {{cite web |url=http://the-witness.net/news/2010/03/graphics-tech-shadow-maps-part-1/ |title=Graphics Tech: Shadow Maps (part 1) |author=Jonathan Blow |date=3 March 2010 |accessdate=13 April 2012 }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Shader development]]&lt;br /&gt;
[[Category:Core development projects]]&lt;/div&gt;</summary>
		<author><name>Fredb</name></author>
	</entry>
</feed>