Compositor: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
No edit summary
 
(96 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{Template:Non-stable|version=2019.2|build_flags=-DENABLE_COMPOSITOR=ON|progress=100}}
{{forum|47|Effects & Shaders}}
{{forum|47|Effects & Shaders}}


{{infobox subsystem
{{infobox subsystem
|image      = ALS Compositor pipeline.jpg
|image      = Compositor logo.png
|name        = Compositor Framework
|name        = Compositor Framework
|started    = 01/2018 (Available since FlightGear 2019.2)
|started    = 01/2018 (Available since FlightGear 2020.4)
|description = Dynamic rendering pipeline configured via the property tree and XML
|description = Dynamic rendering pipeline configured via the [[Property tree]] and [[PropertyList XML File|XML]]
|status      = Stable
|status      = Stable (merged and actively maintained)
|developers  = Fernando García Liñán
|developers  = Fernando García Liñán <ref>https://sourceforge.net/u/fgarlin/profile/</ref>
|changelog = https://sourceforge.net/u/fgarlin/profile/feed.rss
|folders =  
|folders =  
* {{simgear file|simgear/scene/viewer}}
* {{flightgear file|src/Viewer}}
* {{flightgear file|src/Viewer}}
* {{simgear file|simgear/scene/viewer}}
* {{fgdata file|Compositor}}
* {{fgdata file|Compositor}}
}}
}}


The '''Compositor''' aims to bring multi-pass rendering to FlightGear. It encapsulates a rendering pipeline and exposes its parameters to a [[Property Tree]] interface. At startup, FlightGear reads the pipeline definition file for each physical viewport defined on the [[Howto:Configure camera view windows|CameraGroup settings]]. If no Compositor file is specified for a physical camera, the one given by the <code>--compositor=</code> startup command will be used. If such startup option is not used either, FlightGear will look for a valid Compositor file in $FG_ROOT/Compositor/default.xml
{{Rendering}}
 
The '''Compositor''' aims to bring multi-pass rendering to FlightGear. It encapsulates a rendering pipeline and exposes its parameters to a [[Property Tree]] interface. At startup, FlightGear reads the pipeline definition file for each physical viewport defined on the [[Howto:Configure camera view windows|CameraGroup settings]]. If no Compositor file is specified for a physical camera, the one given by the <code>--compositor=</code> startup command will be used. If such startup option is not used either, FlightGear will look for a valid Compositor file in <tt>$FG_ROOT/Compositor/default.xml</tt>.


The Compositor introduces a new dedicated fgdata directory for new/custom rendering pipelines: {{Fgdata file|Compositor}}.
The Compositor introduces a new dedicated fgdata directory for new/custom rendering pipelines: {{Fgdata file|Compositor}}.


== Background ==
== Background ==
{{See also|Supporting multiple renderers|Howto:Canvas View Camera Element}}
First discussed in 03/2012 during the early [[Rembrandt]] days, Zan (Lauri Peltonen) came up with a set of patches demonstrating how to create an XML-configurable rendering pipeline.


Back then, this work was considered to look pretty promising <ref>{{cite web
First discussed in 03/2012 during the early [[Rembrandt]] days, Zan (Lauri Peltonen) came up with a set of patches demonstrating how to create an XML-configurable rendering pipeline. Back then, this work was considered to look pretty promising <ref>{{cite web
   |url    =  https://sourceforge.net/p/flightgear/mailman/message/28946515/  
   |url    =  https://sourceforge.net/p/flightgear/mailman/message/28946515/  
   |title  =  <nowiki> Re: [Flightgear-devel] [Rembrandt] the plan </nowiki>  
   |title  =  <nowiki> Re: [Flightgear-devel] [Rembrandt] the plan </nowiki>  
Line 36: Line 32:
   }}</ref> and at the time plans were discussed to unify this with the ongoing Rembrandt implementation (no longer maintained).
   }}</ref> and at the time plans were discussed to unify this with the ongoing Rembrandt implementation (no longer maintained).


Adopting Zan's approach would have meant that efforts like [[Rembrandt]] (deferred rendering) could have been implemented without requiring C++ space modifications, i.e. purely in [[Base package]] space.
Adopting Zan's approach would have meant that efforts like [[Rembrandt]] (deferred rendering) could have been implemented without requiring C++ space modifications, i.e. purely in [[Base package]] space. Rembrandt's developer (FredB) suggested to extend the format to avoid duplicating the stages when you have more than one viewport, i.e.  specifying a pipeline as a template, with conditions like in effects, and have the current camera layout refer the pipeline that would be duplicated, resized and positioned for each declared viewport <ref>{{cite web
 
Rembrandt's developer (FredB) suggested to extend the format to avoid duplicating the stages when you have more than one viewport, i.e.  specifying a pipeline as a template, with conditions like in effects, and have the current camera layout refer the pipeline that would be duplicated, resized and positioned for each declared viewport <ref>{{cite web
   |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944773/  
   |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944773/  
   |title  =  <nowiki> Re: [Flightgear-devel] [Rembrandt] the plan </nowiki>  
   |title  =  <nowiki> Re: [Flightgear-devel] [Rembrandt] the plan </nowiki>  
Line 47: Line 41:
   }}</ref>
   }}</ref>


Zan's original patches can still be found in his newcameras branches which allow the user to define the rendering pipeline in preferences.xml: {{gitorious source|proj=fg|repo=zans-flightgear|branch=newcameras|text=FlightGear}}, {{gitorious source|proj=fg|repo=zans-simgear|branch=newcameras|text=SimGear}}.
Zan's original patches can still be found in his newcameras branches which allow the user to define the rendering pipeline in preferences.xml: {{gitorious source|proj=fg|repo=zans-flightgear|branch=newcameras|text=FlightGear}}, {{gitorious source|proj=fg|repo=zans-simgear|branch=newcameras|text=SimGear}}. At that point, it didn't have everything Rembrandt's pipeline needs, but most likely could be easily enhanced to support those things. Basically, the original version added support for multiple camera passes, texture targets, texture formats, passing textures from one pass to another etc, while preserving the standard rendering line if user wants that. <ref>{{cite web
 
At that point, it didn't have everything Rembrandt's pipeline needs, but most likely could be easily enhanced to support those things.  
 
Basically, the original version added support for multiple camera passes, texture targets, texture formats, passing textures from one pass to another etc, while preserving the standard rendering line if user wants that. <ref>{{cite web
   |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944733/  
   |url    =  https://sourceforge.net/p/flightgear/mailman/message/28944733/  
   |title  =  <nowiki> [Flightgear-devel] [Rembrandt] the plan </nowiki>  
   |title  =  <nowiki> [Flightgear-devel] [Rembrandt] the plan </nowiki>  
Line 63: Line 53:


The new '''Compositor''' is an improved re-implementation of Zan's original work using not just XML, but also [[Property Tree|properties]] and a handful of [[Canvas]] concepts.
The new '''Compositor''' is an improved re-implementation of Zan's original work using not just XML, but also [[Property Tree|properties]] and a handful of [[Canvas]] concepts.
== News / Changelog ==
== Developer Discussion ==
{{Note|This is a rough summary of the main topics discussed among core developers on the FlightGear Devel mailing list.}}
=== Integration ===
The Compositor is disabled by default at compilation time in
FlightGear (not SimGear). Both Rembrandt and the forward pipeline are
still available if this flag is disabled.<ref>https://sourceforge.net/p/flightgear/mailman/message/36578956/</ref>
The Compositor is a standalone part of SimGear, the problem is the
interfacing with FlightGear (CameraGroup and the FGRenderer). It's
hard to have two simultaneous renderers when many other parts of the
sim rely on it. You always end up with a lot of 'if' branching, as it
happended with Rembrandt.<ref>https://sourceforge.net/p/flightgear/mailman/message/36657975/</ref>
=== Compatibility ===
it is worth remembering that at the moment compositor is
identical to the default pipeline and thus there will be no advantage
for flying - it is currently there so we can develop it further<ref>https://sourceforge.net/p/flightgear/mailman/message/36605836/</ref>
The Compositor is designed to be compatible with everything in
FlightGear, except of course Rembrandt and the classic forward
pipeline. It makes use of Effects for everything shader related and
works seamlessly with multiple monitors/windows defined in the
CameraGroup. There are also plans to support Canvas.
=== FGData structure ===
The current approach seems fine - i.e. having a Compositor
folder within fgdata to provide some isolation of the new components. 
My approach would likely be to create a Compositor/Shaders folder for
shaders rather than using the existing fgdata/Shaders folder.  Once
things mature, I'd revisit this to determine a long-term folder structure.<ref>https://sourceforge.net/p/flightgear/mailman/message/36657761/</ref>
Richard has proposed a similar file structure and Fernando agreed, it is
definitely a good idea to separate new Effects from the old ones for
now.<ref>https://sourceforge.net/p/flightgear/mailman/message/36657975/</ref>
There is a new scheme that Fernando is currently working on whereby we
have a definition of the effects/shaders within the pipeline keep them
within the pipeline folder structure; together with defining what the
shader does (if applicable) so it can be controlled by a future UI.
There is a very rough draft design doc for this available here
http://www.zaretto.com/sites/zaretto.com/files/compositor-effects-registry.pdf <ref>https://sourceforge.net/p/flightgear/mailman/message/36606242/</ref>
=== Availability ===
Would it be practical to get to a point where both the legacy and
compositor CameraGroup classes can co-exist at runtime? I recently made a
fix (pull request coming shortly) that involved a lot of duplicate code in
the legacy and compositor code, and then I had to change compile options,
recompile, etc. to test it; yuck. I'm very enthusiastic about the
compositor, but it will get much more of a workout if it  is compiled and
available to everyone.<ref>https://sourceforge.net/p/flightgear/mailman/message/36605878/</ref>
=== Runtime Toggling ===
drop support for legacy renderer: agree - not wise.  It is too early to
consider doing so.  Ideally, we would want a toggle between Default and
Compositor pipelines while Compositor is being developed.  I would keep
the toggle point very simple for now - perhaps a commandline switch to
activate compositor and disable default.  The harder part is the
refactoring necessary to allow the two approaches to coexist - one being
active and the other being inactive (e.g. feature toggle -
https://www.martinfowler.com/articles/feature-toggles.html) <ref>https://sourceforge.net/p/flightgear/mailman/message/36657761/</ref>
Runtime toggling for the Compositor has been discussed before.
Implementing such thing is not trivial though. The legacy
CameraGroup/renderer is already quite messy due to Rembrandt. Around a
year ago, when I started planning the Compositor, I made the decision
to keep things simple and keep the CameraGroup implementation for the
compositor as a separate file, just so I wouldn't have to deal with
that mess. The advantages you mention for runtime toggling are indeed
very interesting, but I'm personally not interested in having to deal
with the headache caused by implementing it. I seem to recall that
James proposed adding a compositor build to Jenkins, that would be a
nice middle ground so people can test/develop for the Compositor while
keeping the legacy renderer intact.<ref>https://sourceforge.net/p/flightgear/mailman/message/36657975/</ref>
=== Replacing the legacy renderer ===
The vision is we would replace the legacy rendering with
compositor; this will then allow us to clean up a lot of the hardcoded
stuff that sets up the pipeline, remove the Rembrandt code and generally
have a good tidy up.
Tim Moore suggested to dump the legacy renderer and going with
the compositor. He did some work to eliminate the
need for the far camera, and decided to gamble on doing the work with the
compositor renderer instead of the legacy renderer. He had to add render
buffers to the compositor pass syntax, but otherwise it went well. Going
forward, other work he is doing will use the compositor.
This work uses a floating point depth buffer, the OpenGL clip control
extension to restrict Z values from 0 to 1, and the scheme of reversing the
Z values so that 0 is at the far plane. Tim will submit a merge request for
it once he determines if something similar will work for systems that don't
support clip control.<ref>https://sourceforge.net/p/flightgear/mailman/message/36659646/</ref>
== Gallery ==
<gallery mode=packed widths=230px heights=230px>
Aircrane-compositor-11-2019.jpeg|Aircrane helicopter in [[Compositor]] mode, screen shot by wlbragg <ref>https://forum.flightgear.org/viewtopic.php?f=47&t=36269&start=45#p357570</ref>
</gallery>
{{#ev:youtube|5KYZylR3Wao}}


== Features ==
== Features ==


* Completely independent of other parts of the simulator, i.e. it's part of [[SimGear]] and can be used in a standalone fashion if needed, ala Canvas.
* Completely independent of other parts of the simulator, i.e. it's part of [[SimGear]] and can be used in a standalone fashion if needed, ala Canvas.
* Although independent, its aim is to be fully compatible with the current rendering framework in FG. This includes the [[Effects]] system, [[Howto:Configure camera view windows|CameraGroup]], [[Rembrandt]] and [[ALS]] (and obviously the [[Canvas]]).
* Although independent, its aim is to be fully compatible with the current rendering framework in FG. This includes the [[Effects]] system, [[Howto:Configure camera view windows|CameraGroup]], [[Rembrandt]], [[ALS]] and [[Canvas]].
* Its functionality overlaps Rembrandt: what can be done with Rembrandt can be done with the Compositor, but not vice versa.
* Its functionality overlaps Rembrandt: what can be done with Rembrandt can be done with the Compositor, but not vice versa.
* Fully configurable via an XML interface without compromising performance (ala Effects, using [[PropertyList XML File|PropertyList files]]).
* Fully configurable via an XML interface without compromising performance (ala Effects, using [[PropertyList XML File|PropertyList files]]).
Line 178: Line 63:
* It doesn't increase the hardware requirements, it expands the hardware range FG can run on. People with integrated GPUs (Intel HD etc) can run a Compositor with a single pass that renders directly to the screen like before, while people with more powerful cards can run a Compositor that implements deferred rendering, for example.
* It doesn't increase the hardware requirements, it expands the hardware range FG can run on. People with integrated GPUs (Intel HD etc) can run a Compositor with a single pass that renders directly to the screen like before, while people with more powerful cards can run a Compositor that implements deferred rendering, for example.
* Static branching support. Every pipeline element can be enabled/disabled at startup via a [[Conditions|<condition> block]].
* Static branching support. Every pipeline element can be enabled/disabled at startup via a [[Conditions|<condition> block]].
* The entire rendering pipeline can be reloaded via an fgcommand (<tt>reload-compositor</tt>).


== How to enable the Compositor ==
== How to enable the Compositor ==


Currently the Compositor can only be enabled at compile time via the <code>-DENABLE_COMPOSITOR=ON</code> CMake flag in FlightGear. SimGear doesn't require any extra parameters. Once you have a binary with the Compositor enabled and you run it, you will be presented with the default rendering pipeline. At the time of writing, this is the low spec rendering pipeline. If you want to try the ALS pipeline, start FlightGear with the command line argument: <code>--compositor=Compositor/ALS/als</code>
The Compositor is now the default renderer framework in FlightGear since 2020/11/17. It will be included as part of version 2020.4 onwards.


 
If you compile FlightGear from source, you can already try the Compositor. Make sure you are pulling the latest version of the 'next' branch. You can also try out the latest nightly build from the [[FlightGear build server]].
== Good to know ==
* still untested, but it's supposed to work with multiple monitors <ref>https://forum.flightgear.org/viewtopic.php?f=47&t=36269#p354669</ref>
* Spot lights aren't supported yet for clustered shading, i.e. they are registered and parsed but aren't processed as lights. Point lights are, but I don't remember what's their current status regarding shaders. <ref>https://forum.flightgear.org/viewtopic.php?f=47&t=36269#p353179</ref>
* shadows are only supported on the ALS pipeline <ref>https://forum.flightgear.org/viewtopic.php?f=47&t=36269&start=60#p357586</ref>
* Transparency on trees require MSAA (anti-aliasing) <ref>https://forum.flightgear.org/viewtopic.php?f=47&t=36269&start=45#p357580</ref>


== Notes for aircraft developers ==
== Notes for aircraft developers ==
Line 194: Line 75:
=== Lights ===
=== Lights ===


The Compositor introduces a new way of defining lights that is renderer agnostic, so every rendering pipeline will be able to access the lights that have been implemented like this. As of 2019/11, the only pipeline that supports dynamic lights is the ALS pipeline. The resulting light volumes can be visualized for debugging purposes by setting the property <tt>/sim/debug/show-light-volumes</tt> to true.
The Compositor introduces a new way of defining lights that is renderer agnostic, so every rendering pipeline will be able to access the lights that have been implemented like this. The resulting light volumes can be visualized for debugging purposes by setting the property <tt>/sim/debug/show-light-volumes</tt> to true.
 
You can edit existing lights with the '''[[Illuminator addon|Illuminator]]''', but you have to define them first e.g. in your aircraft. The Illuminator add-on is meant for fine-tuning the light parameters.
 
[[Project Rembrandt]] light definitions are also read by the Compositor for backwards compatibility reasons. However, it is not recommended to use the old syntax for new/updated projects.


{|cellpadding=10|
{|cellpadding=10|
Line 238: Line 123:
   <spot-cutoff>40</spot-cutoff>
   <spot-cutoff>40</spot-cutoff>
   <range-m>50</range-m>
   <range-m>50</range-m>
  <dim-factor>
    <property>controls/lighting/instruments-norm</property>
  </dim-factor>
</light>
</light>
</syntaxhighlight>
</syntaxhighlight>
|valign=top style="width: 80%;"|
|valign=top style="width: 80%;"|
* <tt>'''name'''</tt>. An {{tag|animation}} will be able to reference the light by this name. Most animations will work as expected (rotate, translate, spin etc).
* <tt>'''name'''</tt>. An {{tag|animation}} will be able to reference the light by this name. Most [[Howto:Animate_models|animations]] will work as expected (rotate, translate, spin etc). Material animations are not supported.
* <tt>'''type'''</tt>. <tt>spot</tt> or <tt>point</tt>.
* <tt>'''type'''</tt>. <tt>spot</tt> or <tt>point</tt>.
* <tt>'''position'''</tt>. The position of the light source in model space and in meters.
* <tt>'''position'''</tt>. The position of the light source in model space and in meters.
Line 272: Line 160:
* <tt>'''attenuation'''</tt>. Three-component vector where <code><c></code> specifies the constant factor, <code><l></code> specifies the linear factor and <code><nowiki><q></nowiki></code> specifies the quadratic factor. These factors are plugged into the OpenGL light attenuation formula [[File:Spotlight_attenuation.png]] where d is the distance of the fragment to the light source. See this [http://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation table] for a list of attenuation values based on the range of the light.
* <tt>'''attenuation'''</tt>. Three-component vector where <code><c></code> specifies the constant factor, <code><l></code> specifies the linear factor and <code><nowiki><q></nowiki></code> specifies the quadratic factor. These factors are plugged into the OpenGL light attenuation formula [[File:Spotlight_attenuation.png]] where d is the distance of the fragment to the light source. See this [http://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation table] for a list of attenuation values based on the range of the light.
* <tt>'''range-m'''</tt>. Maximum range from the light source position in meters. This value will be used by the renderers to determine if a fragment is illuminated by this source. Every fragment outside this range isn't guaranteed to be affected by the light, even if the attenuation factor isn't 0 in that particular fragment.
* <tt>'''range-m'''</tt>. Maximum range from the light source position in meters. This value will be used by the renderers to determine if a fragment is illuminated by this source. Every fragment outside this range isn't guaranteed to be affected by the light, even if the attenuation factor isn't 0 in that particular fragment.
* <tt>'''cutoff'''</tt>. Only available in <tt>spot</tt> lights. It specifies the maximum spread angle of a light source. Only values in the range 0 90 are accepted. If the angle between the direction of the light and the direction from the light to the fragment being lighted is greater than the spot cutoff angle, it won't be lit.
* <tt>'''spot-cutoff'''</tt>. Only available in <tt>spot</tt> lights. It specifies the maximum spread angle of a light source. Only values in the range 0 90 are accepted. If the angle between the direction of the light and the direction from the light to the fragment being lighted is greater than the spot cutoff angle, it won't be lit.
* <tt>'''exponent'''</tt>. Only available in <tt>spot</tt> lights. Higher spot exponents result in a more focused light source, regardless of the spot cutoff angle.
* <tt>'''spot-exponent'''</tt>. Only available in <tt>spot</tt> lights. Higher spot exponents result in a more focused light source, regardless of the spot cutoff angle.
* <tt>'''dim-factor'''</tt> ('''Optional'''). Controls the dimming of the light source through an [[Expressions|expression]].
* <tt>'''debug-color'''</tt> ('''Optional'''). Sets the color of the debug light volume. By default it's red.
* <tt>'''debug-color'''</tt> ('''Optional'''). Sets the color of the debug light volume. By default it's red.
'''<span style="color:red">Important: </span>'''The following parameters are '''only''' available in the [[HDR Pipeline]].
* <tt>'''color'''</tt>. The color or hue of emitted light. It is expected to be in the sRGB color space.
* <tt>'''intensity'''</tt>. The brightness of the light. This value can be (and will almost always be) higher than 1.
|}
|}


=== Shadows ===
=== Shadows ===


The shadow mapping algorithm can be customized entirely by the rendering pipeline. This means that each one will have its own requirements when it comes to shadows. Here are some general recommendations:
The shadow mapping algorithm can be customized entirely by the rendering pipeline. This means that each pipeline will have its own requirements when it comes to shadows. Here are some general recommendations:


* Use the <code><noshadow></code> animation to disable shadows on objects that don't need them. An example would be billboarded lights or really small cockpit elements that don't need shadows and would cause degraded performance.
* Use the [[Howto:Animate models#Noshadow|<tt>noshadow</tt> animation]] to disable shadows on objects that don't need them. An example would be billboarded lights (light sprites) or really small cockpit elements that don't need shadows and would cause degraded performance.
If the casted aircraft shadow appears blocky then there probably are some objects which need the noshadow animation applied. Most notably are billboarded lights which include [[ALS_technical_notes#ALS procedural lights|ALS procedural lights]].
* Try to mark as many cockpit objects as possible as <tt>interior</tt>.
* Try to mark as many cockpit objects as possible as <tt>interior</tt>.
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
Line 292: Line 185:
* Unlike in Rembrandt, polygons facing the Sun are the ones used to generate the shadow map, so single sided surfaces and non-closed objects should be rendered correctly.
* Unlike in Rembrandt, polygons facing the Sun are the ones used to generate the shadow map, so single sided surfaces and non-closed objects should be rendered correctly.


== Pipelines ==
== Effects and Shaders ==


=== Low-Spec pipeline ===
=== Schemes ===


A fixed function forward rendering pipeline mainly targeted to low spec systems. It imitates the classic forward pipeline used before multi-pass rendering was introduced by using two near/far cameras rendering directly to the screen.
Effects can have different implementations depending on the Compositor pipeline being used. For example, a grass Effect implemented for a high quality pipeline might have much more detail than one that targets low specification machines. Still, they both implement the "look" of grass, so they share the same Effect file (grass.eff).


[[File:Low-spec Compositor pipeline.png|thumb|Screenshot showing OSG stats of the Compositor-based low-spec rendering pipeline.]]
The Compositor chooses which implementation of an Effect to render based on the <tt><scheme></tt> of the techniques.
<syntaxhighlight lang="xml">
<technique n="15">
  <scheme>test-scheme</scheme>
  [...]
</technique>
</syntaxhighlight>


=== ALS ===
In this case the technique will be chosen if the Compositor pipeline <tt><scene></tt> pass uses the <tt>test-scheme</tt> Effect scheme. Consequently, porting an Effect to a Compositor pipeline will require knowing which Effect schemes it uses and writing a technique for each one. The only exception to this is the Classic/default pipeline, which uses techniques with no scheme.


The ALS pipeline tries to bring multipass rendering to the current ALS framework, effectively combining the best from ALS and Project Rembrandt.
=== Built-in uniforms ===


==== Cascaded shadow mapping ====
The Compositor provides a set of built-in uniforms that are passed along to every shader. These uniforms must '''not''' be defined in the Effect file, as they are defined and updated in C++.


The main issue with shadow mapping in FlightGear is the complexity of the scene graph. Culling times can become huge if we don't carefully select which parts of the scene graph we want to render in the shadow maps. Some possible optimizations:
{|class="wikitable" style="font-size: 85%; width: auto; table-layout: fixed;
* Study the minimum shadow map distance we can get without noticeable light leaking. Select an appropiate amount of cascades (more cascades = more passes over all geometry, and in general we want to keep the amount of forward passes to a minimum). We should have at least three cascades: the first just for cockpit/internal shadows, the second for the whole aircraft and the third for the rest of the scenery geometry. A fourth can be added if the transition between the second and the third is too harsh.
!Name
* Improve the culling masks (simgear/scene/util/RenderConstants.hxx). The CASTSHADOW_BIT flag is present in almost every object in the scene graph. Turning this flag off for trees, random buildings and other geometry intensive objects improves framerates by a very considerable amount. Should the user be able to select which objects cast shadows?
!Type
* Should the terrain cast shadows? The terrain is rarely steep enough to cast shadows. Apart from that, the terrain in FlightGear messes with automatic near/far computations for the shadow passes since the geometry is not tessellated enough. Also, the terrain LOD is not good enough to have decent cull times at far cascades.
!Description
* Adding a "internal only" shadow flag for aircraft developers. This allows farther shadow cascades to cull complex objects that are only visible in the nearest cascades. (Very important optimization for aircrafts with complex cockpit geometry).
|-
 
|<tt>fg_TextureMatrix</tt>
==== Post-processing ====
|<tt>mat4</tt>
 
|Texture matrix that replaces the old fixed-function behaviour. If no texture animations are present it corresponds to the identity matrix.
Gamma correction, night vision and other ALS filters should happen in a quad pass. The current filter_combined() should be left for post-processing that requires as much precision as possible - e.g. dithering to prevent banding). HDR is not a planned feature for now so ALS will be using rgba8 buffers for most of its features.
|-
 
|<tt>fg_Viewport</tt>
==== Real-time dynamic reflections ====
|<tt>vec4</tt>
 
|Viewport geometry for the current pass (x, y, width, height).
Rendering dynamically to a cubemap is possible. As with shadow mapping, minimizing the object count and number of forward passes is vital to get good performance in FlightGear. Rendering to six cubemap faces requires six forward passes, but we can render to a dual paraboloid map instead, reducing this number to two.
|-
 
|<tt>fg_PixelSize</tt>
==== Transparency ====
|<tt>vec2</tt>
 
|Inverse of the width and height of the viewport.
When shadows (and multipass rendering in general) come into play, transparent objects have to be treated differently, even when we are dealing with a forward renderer. In OSG there are two ways to separate transparent surfaces:
|-
 
|<tt>fg_ViewMatrix</tt>
* Using RenderBins. After a single scene cull traversal, surfaces which belong to a special RenderBin type (DepthSortedBin) are removed or moved to another camera. This is how Rembrandt does it and it is the most backwards compatible approach since RenderBins can be changed directly inside Effects.
|<tt>mat4</tt>
* Using cull masks. Two separate traversals are done: one for opaque objects and another for translucent objects. This requires offering aircraft developers another way of tagging a surface as transparent. A trivial approach would be to add a new <animation> type called 'transparent', but that wouldn't be backwards compatible. Maybe we can add some kind of system where we can change cull masks inside Effects? Would that be too hacky or out of place?
|View matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_ViewMatrixInverse</tt>
|<tt>mat4</tt>
|Inverse of the view matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_ProjectionMatrix</tt>
|<tt>mat4</tt>
|Projection matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_ProjectionMatrixInverse</tt>
|<tt>mat4</tt>
|Inverse of the projection matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_PrevViewMatrix</tt>
|<tt>mat4</tt>
|Previous frame view matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_PrevViewMatrixInverse</tt>
|<tt>mat4</tt>
|Previous frame inverse of the view matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_PrevProjectionMatrix</tt>
|<tt>mat4</tt>
|Previous frame projection matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_PrevProjectionMatrixInverse</tt>
|<tt>mat4</tt>
|Previous frame inverse of the projection matrix given by CameraGroup for this Compositor.
|-
|<tt>fg_CameraPositionCart</tt>
|<tt>vec3</tt>
|Position of the camera in world space, expressed in cartesian coordinates.
|-
|<tt>fg_CameraPositionGeod</tt>
|<tt>vec3</tt>
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters).
|-
|<tt>fg_CameraDistanceToEarthCenter</tt>
|<tt>float</tt>
|Distance from the camera to the center of the Earth in meters.
|-
|<tt>fg_CameraWorldUp</tt>
|<tt>vec3</tt>
|Camera up vector in world space.
|-
|<tt>fg_CameraViewUp</tt>
|<tt>vec3</tt>
|Camera up vector in view space.
|-
|<tt>fg_EarthRadius</tt>
|<tt>float</tt>
|Earth radius right below the camera position in meters.
|-
|<tt>fg_NearFar</tt>
|<tt>vec2</tt>
|Near and far clipping planes in meters. x component is the near plane, y component is the far plane.
|-
|<tt>fg_Fcoef</tt>
|<tt>float</tt>
|Used by logarithmic depth.
|-
|<tt>fg_FOVScale</tt>
|<tt>vec2</tt>
|Used by logarithmic depth.
|-
|<tt>fg_SunDirection</tt>
|<tt>vec3</tt>
|Normalized Sun (directional light) direction in view space.
|-
|<tt>fg_SunDirectionWorld</tt>
|<tt>vec3</tt>
|Normalized Sun (directional light) direction in world space.
|-
|<tt>fg_SunZenithCosTheta</tt>
|<tt>float</tt>
|Dot product between the Sun direction and the up vector at the camera position.
|-
|<tt>fg_MoonDirection</tt>
|<tt>vec3</tt>
|Normalized Moon (directional light) direction in view space.
|-
|<tt>fg_MoonDirectionWorld</tt>
|<tt>vec3</tt>
|Normalized Moon (directional light) direction in world space.
|-
|<tt>fg_MoonZenithCosTheta</tt>
|<tt>float</tt>
|Dot product between the Moon direction and the up vector at the camera position.
|}


== Creating a custom rendering pipeline ==
== Creating a custom rendering pipeline ==


Since the Compositor is completely data-driven, new rendering pipelines can be created by writing a custom XML pipeline definition. This section tries to document most of the available parameters, but the best and most up-to-date resource is the Compositor parsing code in SimGear ({{simgear file|simgear/scene/viewer}}). See existing pipelines in {{fgdata file|Compositor}} for practical examples on how to use these parameters.
Since the Compositor is completely data-driven, new rendering pipelines can be created by writing a custom XML pipeline definition. This section tries to document most of the available parameters, but the best and most up-to-date resource is the Compositor parsing code in SimGear ({{simgear file|simgear/scene/viewer}}). See existing pipelines in {{fgdata file|Compositor}} for practical examples on how to use these parameters.
Also keep in mind that every pipeline element can be enabled/disabled through a [[Conditions|<condition> block]]. This allows for dynamic rendering pipelines that have toggleable features. However, the pipeline can't be updated in real-time: the simulator has to be restarted or the Compositor has to be reloaded through the <tt>reload-compositor</tt> [[Fgcommands|fgcommand]].


=== Buffers ===
=== Buffers ===
Line 556: Line 546:
! scope="row"| <tt>z-near, z-far</tt>
! scope="row"| <tt>z-near, z-far</tt>
| {{Yes}}
| {{Yes}}
| int
| float
| Default Z range in the CameraGroup
| 0.0 uses the value given by the CameraGroup
| They change the depth range to be used
| Sets a custom near and far values. Useful for implementing depth partition and limiting the depth range on cubemap passes
|-
|-
! scope="row"| <tt>cubemap-face</tt>
! scope="row"| <tt>cubemap-face</tt>
Line 565: Line 555:
| <tt>-1</tt> (don't use cubemap)
| <tt>-1</tt> (don't use cubemap)
| Ignores the given view and projection matrices and uses a custom one that renders the scene as if it was seen from inside a cubemap looking towards the specified face
| Ignores the given view and projection matrices and uses a custom one that renders the scene as if it was seen from inside a cubemap looking towards the specified face
|-
! scope="row"| <tt>use-shadow-pass</tt>
| {{Yes}}
| string
| Empty
| Name of a shadow mapping pass. Exposes shadow mapping related uniforms to the shaders of the current pass
|}
Scene passes can also use the tag <code><clustered-shading></code> to enable clustered shading (lights). The following parameters are available:
{| class="wikitable" style="text-align: center; font-size: 85%; width: auto; table-layout: fixed;
! scope="col" | Parameter Name
! scope="col" | Optional
! scope="col" | Value
! scope="col" | Default Value
! scope="col" | Description
|-
! scope="row"| <tt>max-pointlights</tt>
| {{Yes}}
| int
| 1024
| Maximum amount of point light sources allowed on the entire scene
|-
! scope="row"| <tt>max-spotlights</tt>
| {{Yes}}
| int
| 1024
| Maximum amount of spot light sources allowed on the entire scene
|-
! scope="row"| <tt>max-light-indices</tt>
| {{Yes}}
| int
| 256
| Size of the light indices texture. Keep in mind that it is a 2D texture, so the total size will be e.g. 256x256
|-
! scope="row"| <tt>tile-size</tt>
| {{Yes}}
| int
| 128
| Size of each clustered shading tile
|-
! scope="row"| <tt>num-threads</tt>
| {{Yes}}
| int
| 1
| Number of threads to use during the light culling process. Keep in mind that a high thread count when there aren't many lights will worsen performance due to the thread creation overhead
|-
! scope="row"| <tt>depth-slices</tt>
| {{Yes}}
| int
| 1
| Number of slices to partition the view frustum in the Z axis. Higher numbers will cull lights more aggressively, increasing performance if there are many lights further out that don't contribute much to the overall scene's lighting
|}
|}


Line 578: Line 620:
! scope="row"| <tt>geometry</tt>
! scope="row"| <tt>geometry</tt>
| {{Yes}}
| {{Yes}}
| float values for <code><x>, <y>, <width>, <height></code>
| float values for <code><x>, <y>, <width>, <height>, <scale></code>
| <tt>0.0, 0.0, 1.0, 1.0</tt> respectively
| <tt>0.0, 0.0, 1.0, 1.0, 1.0</tt> respectively
| Size of the fullscreen quad inside the viewport using normalized coordinates.
| Size of the fullscreen quad inside the viewport using normalized coordinates.
|-
|-
Line 589: Line 631:
|}
|}


==== shadow-map ====
==== csm ====
Renders the scene from a light's point of view.
Implements Cascaded Shadow Mapping by rendering the scene from a light's point of view (the Sun by default). For now it only supports directional light sources. There has to be one <tt>csm</tt> pass for each cascade.
{| class="wikitable" style="text-align: center; font-size: 85%; width: auto; table-layout: fixed;
{| class="wikitable" style="text-align: center; font-size: 85%; width: auto; table-layout: fixed;
! scope="col" | Parameter Name
! scope="col" | Parameter Name
Line 599: Line 641:
|-
|-
! scope="row"| <tt>light-name</tt>
! scope="row"| <tt>light-name</tt>
| {{No}}
| {{Yes}}
| Valid light name that exists in the scene graph
| Valid light name that exists in the scene graph
|
| <tt>FGLightSource</tt> (Sun)
| The name of the <tt>osg::LightSource</tt> to use for this shadow map
| The name of the <tt>osg::LightSource</tt> to use for this shadow map
|-
! scope="row"| <tt>render-at-night</tt>
| {{Yes}}
| bool
| true
| Whether to render the shadows at night or not
|-
|-
! scope="row"| <tt>near-m, far-m</tt>
! scope="row"| <tt>near-m, far-m</tt>
| {{No}}
| {{No}}
| Valid Effect file
| float (meters)
|
|
| They specify the depth range of the shadow map
| They specify the range of the shadow map
|}
|}
== TODO ==
* Bring back distortion correction.
* $FG_ROOT/Compositor could use a per-pipeline structure, so that effects/shaders and pipelines are neatly separated and organized, this would also make it easier for maintainers to track a certain pipeline instead of having to track all changes under $FG_ROOT/Compositor (git log)
* Some kind of versioning system to be able to make breaking changes in the future if/when the compositor is updated in any significant way, without people having to manually update their configs.
* Bring back [[Howto:Canvas View Camera Element|Canvas integration]] so aircraft devs have access to the rendering pipeline. This allows to render exterior views in cockpit displays etc.
* Automatically calculate light source attenuation based on radius and radius based on attenuation.
== Known Issues ==
* Setting a buffer scale factor different from 1.0 and rendering to it might not scale the splash screen correctly.
* Clustered shading crashes FG if compiled under OSG 3.6. This is related to osg::TextureBuffer changing definition from OSG 3.4 to OSG 3.6 (Images vs BufferData).


== References ==
== References ==
Line 629: Line 664:
== Related content ==
== Related content ==
=== Wiki articles ===
=== Wiki articles ===
* [[HDR Pipeline]]
* [[glTF]]
* [[Canvas View Camera Element]]
* [[CompositeViewer Support]]
* [[Uniform Buffer Objects]]
* [[Uniform Buffer Objects]]
* [[CompositeViewer Support]]
* [[FlightGear CIGI Support (Common Image Generator Interface)]]
* [[FlightGear CIGI Support (Common Image Generator Interface)]]


Line 637: Line 675:
* {{forum link|t=35095|text=Clustered Forward Rendering}} (12/2018)
* {{forum link|t=35095|text=Clustered Forward Rendering}} (12/2018)
* {{forum link|t=33045|text=Getting started with RTT}}
* {{forum link|t=33045|text=Getting started with RTT}}
* {{forum link|t=32846|text=Canvas::View Development}}
* {{forum link|t=23929|text=Gear View in Cockpit}}
* {{forum link|t=20057|text=Rear-View mirror}}
* {{forum link|t=18905|text=Progress on synthetic terrain}}
* {{forum link|t=17184|text=Instruments with heightmaps}}


[[Category:Core development projects]]
[[Category:Compositor]]

Latest revision as of 13:46, 7 February 2024

Compositor Framework
Compositor logo.png
Started in 01/2018 (Available since FlightGear 2020.4)
Description Dynamic rendering pipeline configured via the Property tree and XML
Contributor(s) Fernando García Liñán [1]
Status Stable (merged and actively maintained)
Folders
Changelog https://sourceforge.net/u/fgarlin/profile/feed.rss

The Compositor aims to bring multi-pass rendering to FlightGear. It encapsulates a rendering pipeline and exposes its parameters to a Property Tree interface. At startup, FlightGear reads the pipeline definition file for each physical viewport defined on the CameraGroup settings. If no Compositor file is specified for a physical camera, the one given by the --compositor= startup command will be used. If such startup option is not used either, FlightGear will look for a valid Compositor file in $FG_ROOT/Compositor/default.xml.

The Compositor introduces a new dedicated fgdata directory for new/custom rendering pipelines: fgdata/Compositor.

Background

First discussed in 03/2012 during the early Rembrandt days, Zan (Lauri Peltonen) came up with a set of patches demonstrating how to create an XML-configurable rendering pipeline. Back then, this work was considered to look pretty promising [2] and at the time plans were discussed to unify this with the ongoing Rembrandt implementation (no longer maintained).

Adopting Zan's approach would have meant that efforts like Rembrandt (deferred rendering) could have been implemented without requiring C++ space modifications, i.e. purely in Base package space. Rembrandt's developer (FredB) suggested to extend the format to avoid duplicating the stages when you have more than one viewport, i.e. specifying a pipeline as a template, with conditions like in effects, and have the current camera layout refer the pipeline that would be duplicated, resized and positioned for each declared viewport [3]

Zan's original patches can still be found in his newcameras branches which allow the user to define the rendering pipeline in preferences.xml: FlightGear, SimGear. At that point, it didn't have everything Rembrandt's pipeline needs, but most likely could be easily enhanced to support those things. Basically, the original version added support for multiple camera passes, texture targets, texture formats, passing textures from one pass to another etc, while preserving the standard rendering line if user wants that. [4]

Since the early days of Zan's groundwork, providing the (hooks) infrastructure to enable base package developers to prototype, test and develop distinct rendering pipelines without requiring C++ space modifications has been a long-standing idea, especially after the Canvas system became available in early 2012, which demonstrated how RTT-rendering buffers (FBOs) could be set up, created and manipulated procedurally (i.e. at run-time) using XML, the property tree and Nasal scripting. [5]

The new Compositor is an improved re-implementation of Zan's original work using not just XML, but also properties and a handful of Canvas concepts.

Features

  • Completely independent of other parts of the simulator, i.e. it's part of SimGear and can be used in a standalone fashion if needed, ala Canvas.
  • Although independent, its aim is to be fully compatible with the current rendering framework in FG. This includes the Effects system, CameraGroup, Rembrandt, ALS and Canvas.
  • Its functionality overlaps Rembrandt: what can be done with Rembrandt can be done with the Compositor, but not vice versa.
  • Fully configurable via an XML interface without compromising performance (ala Effects, using PropertyList files).
  • Flexible, expandable and compatible with modern graphics.
  • It doesn't increase the hardware requirements, it expands the hardware range FG can run on. People with integrated GPUs (Intel HD etc) can run a Compositor with a single pass that renders directly to the screen like before, while people with more powerful cards can run a Compositor that implements deferred rendering, for example.
  • Static branching support. Every pipeline element can be enabled/disabled at startup via a <condition> block.
  • The entire rendering pipeline can be reloaded via an fgcommand (reload-compositor).

How to enable the Compositor

The Compositor is now the default renderer framework in FlightGear since 2020/11/17. It will be included as part of version 2020.4 onwards.

If you compile FlightGear from source, you can already try the Compositor. Make sure you are pulling the latest version of the 'next' branch. You can also try out the latest nightly build from the FlightGear build server.

Notes for aircraft developers

Lights

The Compositor introduces a new way of defining lights that is renderer agnostic, so every rendering pipeline will be able to access the lights that have been implemented like this. The resulting light volumes can be visualized for debugging purposes by setting the property /sim/debug/show-light-volumes to true.

You can edit existing lights with the Illuminator, but you have to define them first e.g. in your aircraft. The Illuminator add-on is meant for fine-tuning the light parameters.

Project Rembrandt light definitions are also read by the Compositor for backwards compatibility reasons. However, it is not recommended to use the old syntax for new/updated projects.

<light>
  <name>my-spotlight</name>
  <type>spot</type>
  <position>
    <x-m>-7.7476</x-m>
    <y-m>0</y-m>
    <z-m>-1.7990</z-m>
  </position>
  <direction>
    <x>-1.0</x>
    <y>0</y>
    <z>-0.013</z>
  </direction>
  <ambient>
    <r>0.03</r>
    <g>0.03</g>
    <b>0.03</b>
    <a>1</a>
  </ambient>
  <diffuse>
    <r>0.95</r>
    <g>0.9</g>
    <b>0.9</b>
    <a>1</a>
  </diffuse>
  <specular>
    <r>0.95</r>
    <g>0.9</g>
    <b>0.9</b>
    <a>1</a>
  </specular>
  <attenuation>
    <c>1.0</c>
    <l>0.09</l>
    <q>0.032</q>
  </attenuation>
  <spot-exponent>5</spot-exponent>
  <spot-cutoff>40</spot-cutoff>
  <range-m>50</range-m>
  <dim-factor>
    <property>controls/lighting/instruments-norm</property>
  </dim-factor>
</light>
  • name. An <animation> will be able to reference the light by this name. Most animations will work as expected (rotate, translate, spin etc). Material animations are not supported.
  • type. spot or point.
  • position. The position of the light source in model space and in meters.
  • direction. Only available in spot lights. It indicates the direction of the spotlight. This parameter can be specified in three different ways:
Direction vector Look-at point Rotation angles
A vector in model space that specifies the direction. Doesn't have to be normalized.
<x>-1.0</x>
<y>0</y>
<z>-0.013</z>
The spotlight will calculate its direction by looking at this position from the light position. The point is in model space and in meters.
<lookat-x-m>-8.031</lookat-x-m>
<lookat-y-m>0</lookat-y-m>
<lookat-z-m>-2</lookat-z-m>
A three angle rotation in degrees that rotates the spotlight around the three axes. A 0 degree angle in all axes makes the spotlight point downwards (negative Z).
<pitch-deg>90</pitch-deg>
<roll-deg>0</roll-deg>
<heading-deg>0</heading-deg>
  • ambient, diffuse and specular. Four-component vectors that specify the light color.
  • attenuation. Three-component vector where <c> specifies the constant factor, <l> specifies the linear factor and <q> specifies the quadratic factor. These factors are plugged into the OpenGL light attenuation formula Spotlight attenuation.png where d is the distance of the fragment to the light source. See this table for a list of attenuation values based on the range of the light.
  • range-m. Maximum range from the light source position in meters. This value will be used by the renderers to determine if a fragment is illuminated by this source. Every fragment outside this range isn't guaranteed to be affected by the light, even if the attenuation factor isn't 0 in that particular fragment.
  • spot-cutoff. Only available in spot lights. It specifies the maximum spread angle of a light source. Only values in the range 0 90 are accepted. If the angle between the direction of the light and the direction from the light to the fragment being lighted is greater than the spot cutoff angle, it won't be lit.
  • spot-exponent. Only available in spot lights. Higher spot exponents result in a more focused light source, regardless of the spot cutoff angle.
  • dim-factor (Optional). Controls the dimming of the light source through an expression.
  • debug-color (Optional). Sets the color of the debug light volume. By default it's red.

Important: The following parameters are only available in the HDR Pipeline.

  • color. The color or hue of emitted light. It is expected to be in the sRGB color space.
  • intensity. The brightness of the light. This value can be (and will almost always be) higher than 1.

Shadows

The shadow mapping algorithm can be customized entirely by the rendering pipeline. This means that each pipeline will have its own requirements when it comes to shadows. Here are some general recommendations:

  • Use the noshadow animation to disable shadows on objects that don't need them. An example would be billboarded lights (light sprites) or really small cockpit elements that don't need shadows and would cause degraded performance.

If the casted aircraft shadow appears blocky then there probably are some objects which need the noshadow animation applied. Most notably are billboarded lights which include ALS procedural lights.

  • Try to mark as many cockpit objects as possible as interior.
<model>
  <name>interior</name>
  <usage>interior</usage>
  <path>Aircraft/JA37/Models/ja37-interior.xml</path> <!-- All the objects that should only be seen when inside the cockpit are in this file -->
</model>
  • Unlike in Rembrandt, polygons facing the Sun are the ones used to generate the shadow map, so single sided surfaces and non-closed objects should be rendered correctly.

Effects and Shaders

Schemes

Effects can have different implementations depending on the Compositor pipeline being used. For example, a grass Effect implemented for a high quality pipeline might have much more detail than one that targets low specification machines. Still, they both implement the "look" of grass, so they share the same Effect file (grass.eff).

The Compositor chooses which implementation of an Effect to render based on the <scheme> of the techniques.

<technique n="15">
  <scheme>test-scheme</scheme>
  [...]
</technique>

In this case the technique will be chosen if the Compositor pipeline <scene> pass uses the test-scheme Effect scheme. Consequently, porting an Effect to a Compositor pipeline will require knowing which Effect schemes it uses and writing a technique for each one. The only exception to this is the Classic/default pipeline, which uses techniques with no scheme.

Built-in uniforms

The Compositor provides a set of built-in uniforms that are passed along to every shader. These uniforms must not be defined in the Effect file, as they are defined and updated in C++.

Name Type Description
fg_TextureMatrix mat4 Texture matrix that replaces the old fixed-function behaviour. If no texture animations are present it corresponds to the identity matrix.
fg_Viewport vec4 Viewport geometry for the current pass (x, y, width, height).
fg_PixelSize vec2 Inverse of the width and height of the viewport.
fg_ViewMatrix mat4 View matrix given by CameraGroup for this Compositor.
fg_ViewMatrixInverse mat4 Inverse of the view matrix given by CameraGroup for this Compositor.
fg_ProjectionMatrix mat4 Projection matrix given by CameraGroup for this Compositor.
fg_ProjectionMatrixInverse mat4 Inverse of the projection matrix given by CameraGroup for this Compositor.
fg_PrevViewMatrix mat4 Previous frame view matrix given by CameraGroup for this Compositor.
fg_PrevViewMatrixInverse mat4 Previous frame inverse of the view matrix given by CameraGroup for this Compositor.
fg_PrevProjectionMatrix mat4 Previous frame projection matrix given by CameraGroup for this Compositor.
fg_PrevProjectionMatrixInverse mat4 Previous frame inverse of the projection matrix given by CameraGroup for this Compositor.
fg_CameraPositionCart vec3 Position of the camera in world space, expressed in cartesian coordinates.
fg_CameraPositionGeod vec3 Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters).
fg_CameraDistanceToEarthCenter float Distance from the camera to the center of the Earth in meters.
fg_CameraWorldUp vec3 Camera up vector in world space.
fg_CameraViewUp vec3 Camera up vector in view space.
fg_EarthRadius float Earth radius right below the camera position in meters.
fg_NearFar vec2 Near and far clipping planes in meters. x component is the near plane, y component is the far plane.
fg_Fcoef float Used by logarithmic depth.
fg_FOVScale vec2 Used by logarithmic depth.
fg_SunDirection vec3 Normalized Sun (directional light) direction in view space.
fg_SunDirectionWorld vec3 Normalized Sun (directional light) direction in world space.
fg_SunZenithCosTheta float Dot product between the Sun direction and the up vector at the camera position.
fg_MoonDirection vec3 Normalized Moon (directional light) direction in view space.
fg_MoonDirectionWorld vec3 Normalized Moon (directional light) direction in world space.
fg_MoonZenithCosTheta float Dot product between the Moon direction and the up vector at the camera position.

Creating a custom rendering pipeline

Since the Compositor is completely data-driven, new rendering pipelines can be created by writing a custom XML pipeline definition. This section tries to document most of the available parameters, but the best and most up-to-date resource is the Compositor parsing code in SimGear (simgear/simgear/scene/viewer). See existing pipelines in fgdata/Compositor for practical examples on how to use these parameters.

Also keep in mind that every pipeline element can be enabled/disabled through a <condition> block. This allows for dynamic rendering pipelines that have toggleable features. However, the pipeline can't be updated in real-time: the simulator has to be restarted or the Compositor has to be reloaded through the reload-compositor fgcommand.

Buffers

A buffer represents a texture or, more generically, a region of GPU memory.

Parameter Name Optional Value Default Value Description
name No string Passes will be able to address the buffer by this name
type No 1d, 2d, 2d-array, 2d-multisample, 3d, rect, cubemap Any texture type allowed by OpenGL
width No Any unsigned integer or screen to use the physical viewport width. The <property> tag can also be used to use a property value Texture width
screen-width-scale Yes float 1.0 If screen was used, this controls the width scaling factor
height No Any unsigned integer or screen to use the physical viewport height. The <property> tag can also be used to use a property value Texture height
screen-height-scale Yes float 1.0 If screen was used, this controls the height scaling factor
depth No Any unsigned integer. The <property> tag can also be used to use a property value Texture depth
format Yes See simgear/simgear/scene/viewer/CompositorBuffer.cxx for the latest available values rgba8 Specifies the texture format. It corresponds to the internalformat, format and type arguments of the OpenGL function glTexImage2D
min-filter, mag-filter Yes linear, linear-mipmap-linear, linear-mipmap-nearest, nearest, nearest-mipmap-linear, nearest-mipmap-nearest linear Change the minification and magnification filtering respectively
wrap-s, wrap-t, wrap-r Yes clamp, clamp-to-edge, clamp-to-border, repeat, mirror clamp-to-border They change the wrap mode for each coordinate
anisotropy Yes float 1.0
border-color Yes vec4 (0.0f, 0.0f, 0.0f, 0.0f)
shadow-comparison Yes bool true
shadow-texture-mode Yes luminance, intensity, alpha luminance
shadow-compare-func Yes never, less, equal, lequal, greater, notequal, gequal, always lequal

Passes

A pass wraps around an osg::Camera. Passes all have some common parameters:

Parameter Name Optional Value Default Value Description
clear-color, clear-accum, clear-depth and clear-stencil Yes vec4 black, black, 1.0, 0 respectively Pass clear colors
clear-mask Yes color, stencil, depth, accum color depth Pass clear mask
effect-scheme Yes Valid effect scheme name None The pass will try to use the specified effect scheme to draw every object.

Passes can render to a buffer (Render to Texture), to several buffers (Multiple Render Targets) or directly to the framebuffer. This is accomplished by the <attachment> tag. Possible parameters of an attachment are:

Parameter Name Optional Value Default Value Description
buffer No Valid buffer name The name of the buffer to output to
component No color, color0 to color15, depth, stencil, depth-stencil FBO attachment point
level Yes int 0 Mipmap level of the texture that is attached
face Yes int 0 Face of cube map texture or z-level of 3d texture
mipmap-generation Yes bool false Whether mipmap generation should be done for texture
multisample-samples Yes int 0 Multisample anti-aliasing (MSAA) samples
multisample-color-samples Yes int 0 Multisample anti-aliasing (MSAA) color samples

Passes can also receive buffers as input and use them in their shaders. This is accomplished by the <binding> tag, which has the following parameters:

Parameter Name Optional Value Default Value Description
buffer No Valid buffer name The name of the buffer to bind
unit No int The texture unit to place the texture on. Effects will be able to access the buffer on this texture unit

There are specific pass types, each with their own set of custom parameters.

scene

Renders the scene from the point of view given by the CameraGroup.

Parameter Name Optional Value Default Value Description
cull-mask Yes A 32 bit number. See simgear/simgear/scene/util/RenderConstants.hxx to know which bits enable what 0xffffffff Specifies the cull mask to be used in the underlying osg::Camera
z-near, z-far Yes float 0.0 uses the value given by the CameraGroup Sets a custom near and far values. Useful for implementing depth partition and limiting the depth range on cubemap passes
cubemap-face Yes int -1 (don't use cubemap) Ignores the given view and projection matrices and uses a custom one that renders the scene as if it was seen from inside a cubemap looking towards the specified face
use-shadow-pass Yes string Empty Name of a shadow mapping pass. Exposes shadow mapping related uniforms to the shaders of the current pass

Scene passes can also use the tag <clustered-shading> to enable clustered shading (lights). The following parameters are available:

Parameter Name Optional Value Default Value Description
max-pointlights Yes int 1024 Maximum amount of point light sources allowed on the entire scene
max-spotlights Yes int 1024 Maximum amount of spot light sources allowed on the entire scene
max-light-indices Yes int 256 Size of the light indices texture. Keep in mind that it is a 2D texture, so the total size will be e.g. 256x256
tile-size Yes int 128 Size of each clustered shading tile
num-threads Yes int 1 Number of threads to use during the light culling process. Keep in mind that a high thread count when there aren't many lights will worsen performance due to the thread creation overhead
depth-slices Yes int 1 Number of slices to partition the view frustum in the Z axis. Higher numbers will cull lights more aggressively, increasing performance if there are many lights further out that don't contribute much to the overall scene's lighting

quad

Renders a fullscreen quad with an optional effect applied. Useful for screen space shaders (like SSAO, Screen Space Reflections or bloom) and deferred rendering.

Parameter Name Optional Value Default Value Description
geometry Yes float values for <x>, <y>, <width>, <height>, <scale> 0.0, 0.0, 1.0, 1.0, 1.0 respectively Size of the fullscreen quad inside the viewport using normalized coordinates.
effect Yes Valid Effect file None This Effect will be applied to the quad geometry

csm

Implements Cascaded Shadow Mapping by rendering the scene from a light's point of view (the Sun by default). For now it only supports directional light sources. There has to be one csm pass for each cascade.

Parameter Name Optional Value Default Value Description
light-name Yes Valid light name that exists in the scene graph FGLightSource (Sun) The name of the osg::LightSource to use for this shadow map
render-at-night Yes bool true Whether to render the shadows at night or not
near-m, far-m No float (meters) They specify the range of the shadow map

References

References

Related content

Wiki articles

Forum topics