Compositor: Difference between revisions

Jump to navigation Jump to search
7,863 bytes removed ,  17 November 2020
no edit summary
m (+-cat: Core development projects → Compositor)
No edit summary
(2 intermediate revisions by the same user not shown)
Line 4: Line 4:
|image      = ALS Compositor pipeline.jpg
|image      = ALS Compositor pipeline.jpg
|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 [[PropertyList XML File|XML]]
|description = Dynamic rendering pipeline configured via the [[Property tree]] and [[PropertyList XML File|XML]]
|status      = Stable (merged and actively maintained)
|status      = Stable (merged and actively maintained)
Line 13: Line 13:
* {{flightgear file|src/Viewer}}
* {{flightgear file|src/Viewer}}
* {{fgdata file|Compositor}}
* {{fgdata file|Compositor}}
|ticket-label = 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 <tt>$FG_ROOT/Compositor/default.xml</tt>.
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}}.
The framework is now included in the latest stable release ([[Changelog_2020.1|FlightGear v2020.1]]) as a separate binary. Developers are encouraged to test the Compositor with their personal projects and report any breakages. Also keep in mind that some features might not work/look as intended - see [[#Known Issues|Known Issues]].


== Background ==
== Background ==
{{See also|Supporting multiple renderers|Howto:Canvas View Camera Element}}
{{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.
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
 
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 38: Line 31:
   }}</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 49: Line 40:
   }}</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 78: Line 65:
== 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.  
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.
SimGear doesn't require any extra parameters.  


On Linux, one can use <code>download_and_compile.sh --compositor</code> (see [[Scripted Compilation on Linux Debian/Ubuntu]]).  
If you compile FlightGear from source, you can already try the Compositor. Make sure you are pulling the latest version of the 'next' branch.


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|ALS pipeline]], start FlightGear with the command line argument: <code>--compositor=Compositor/als</code>
If you want to enable shadows on all objects, use these options as startup parameters (in QT GUI or in the commandline) <code>--prop:bool:/sim/rendering/shadows/enabled=true</code> and <code>--prop:int:/sim/rendering/shadows/sun-atlas-size=2048</code>. If you feel like shadows are too low-quality (specially in the cockpit), increase the shadow resolution to 4096 or 8192 instead of 2048.
 
If you want to enable shadows on all objects in the ALS pipeline use these options as a startup parameters (in QT GUI or in the commandline) <code>--prop:bool:/sim/rendering/als/shadows/enabled=true</code> and <code>--prop:int:/sim/rendering/als/shadows/sun-atlas-size=2048</code>. If you feel like the shadows are too low-quality (specially in the cockpit), increase the shadow resolution to 4096 or 8192 instead of 2048.
 
If you are having trouble with lights using an integrated GPU and the Mesa drivers under Linux, try starting FlightGear with the environment variable <tt>MESA_GL_VERSION_OVERRIDE="3.1COMPAT"</tt>


== Notes for aircraft developers ==
== Notes for aircraft developers ==
Line 193: Line 175:
== Porting and developing Effects/Shaders ==
== Porting and developing Effects/Shaders ==


Effects can now have different implementations depending on the Compositor pipeline being used. For example, a grass Effect implemented in the ALS pipeline might have much more detail than the one in the low-spec pipeline. Still, they both implement the "look" of grass, so they share the same Effect file (grass.eff).
Effects can now 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 <tt><scheme></tt> of the techniques.
The Compositor chooses which implementation of an Effect to render based on the <tt><scheme></tt> of the techniques.
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<technique n="15">
<technique n="15">
   <scheme>als-lighting</scheme>
   <scheme>test-scheme</scheme>
   [...]
   [...]
</technique>
</technique>
</syntaxhighlight>
</syntaxhighlight>


In this case the technique will be chosen if the Compositor pipeline <tt><scene></tt> pass uses the <tt>als-lighting</tt> Effect scheme. Consequently, porting an Effect to a pipeline will require knowing which Effect schemes it uses and writing a technique for each one. The only exception to this is the Default (Low-Spec) pipeline, which uses techniques with no scheme.
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 pipeline will require knowing which Effect schemes it uses and writing a technique for each one. The only exception to this is the Classic pipeline, which uses techniques with no scheme.
 
Generally porting legacy Effects will require these steps:
* Remove <tt>/sim/rendering/shaders/skydome</tt> from the ALS techniques and add the <tt>als-lighting</tt> scheme.
* Remove Rembrandt techniques.
* Use technique numbers from 0 to 9 for the Default pipeline techniques and 10 to 19 for the ALS pipeline.
* Move the shaders to their correct directory. Now the <tt>$FG_ROOT/Shaders</tt> directory is subdivided into different folders for each pipeline. For example, shaders related to the ALS pipeline are located in <tt>$FG_ROOT/Shaders/ALS</tt>.
 
To add features specific to a particular pipeline (like shadows in the ALS pipeline), see each pipeline's documentation below.
 
=== ALS ===
 
==== Adding shadows ====
 
==== Rendering correct depth ====
 
The ALS pipeline uses a logarithmic depth buffer. This is accomplished by writing to <tt>gl_FragDepth</tt> in the fragment shader or by modifying <tt>gl_Position.z</tt> in the vertex shader. The second option is faster but doesn't work for polygons that intersect the near plane of the camera (e.g. terrain), so you should use it by default unless visual bugs appear.
 
* '''1st option'''
Add the following to the vertex shader:
<syntaxhighlight lang="glsl">
uniform float fg_Fcoef;
[...]
gl_Position = ...
gl_Position.z = (log2(max(1e-6, 1.0 + gl_Position.w)) * fg_Fcoef - 1.0) * gl_Position.w;
</syntaxhighlight>
 
* '''2nd option'''
Add the following to the vertex shader:
<syntaxhighlight lang="glsl">
varying float flogz;
[...]
gl_Position = ...
flogz = 1.0 + gl_Position.w;
</syntaxhighlight>
And the following to the fragment shader:
<syntaxhighlight lang="glsl">
uniform float fg_Fcoef;
varying float flogz;
[...]
gl_FragColor = ...
gl_FragDepth = log2(flogz) * fg_Fcoef * 0.5;
</syntaxhighlight>
 
== Pipeline technical notes ==
 
=== Default (Low-Spec) ===
 
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.
 
[[File:Low-spec Compositor pipeline.png|thumb|Screenshot showing OSG stats of the Compositor-based low-spec rendering pipeline.]]
 
=== ALS ===
{{See also|ALS technical notes}}
 
The ALS pipeline tries to bring multipass rendering to the current ALS framework, effectively combining the best from ALS and Project Rembrandt.
 
==== Cascaded shadow mapping ====
 
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:
* 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.
* 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?
* 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.
* 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 aircraft with complex cockpit geometry).
* Vegetation shadows will be done by the "legacy" method currently in use. Shadow mapping on vegetation is much more expensive in terms of performance and the current algorithm does the job well enough. <ref>https://forum.flightgear.org/viewtopic.php?f=47&p=357606</ref>
 
==== Post-processing ====
 
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.
 
==== Real-time dynamic reflections ====
 
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.
 
==== Transparency ====
 
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:
 
* 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.
* 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?


== Creating a custom rendering pipeline ==
== Creating a custom rendering pipeline ==
Line 607: Line 510:
| They specify the depth range of the shadow map
| They specify the depth range of the shadow map
|}
|}
== TODO ==
{{See also|Post FlightGear 2020.2 LTS changes}}
* Bring back distortion correction.
* Rework [[Draw masks|node masks]] ({{simgear file|simgear/scene/util/RenderConstants.hxx}}). Each node type should have its own node mask bit, e.g. trees should only have <tt>TREE_BIT</tt> enabled, the main aircraft should only have <tt>AIRCRAFT_BIT</tt> enabled etc. This allows the Compositor cameras to properly filter scene graph nodes based on the cull mask. Shadow cameras can then choose what geometry they render dynamically.
* Automatically calculate light source attenuation based on radius and radius based on attenuation.
* Add clustered shading to every Effect as a separate technique.
* Proper shader quality settings for both low-spec and ALS pipelines.
* Launcher and UI:
** [[Integrated Qt5 Launcher]]
** Rendering dialog


== Known Issues ==
== Known Issues ==
343

edits

Navigation menu