Compositor: Difference between revisions

Jump to navigation Jump to search
761 bytes added ,  5 November 2019
no edit summary
mNo edit summary
No edit summary
Line 66: Line 66:


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.
== Status ==
'''06/2019'''
The Compositor core is complete and stable. Effects and shaders still need to be adapted to the Compositor.


== Features ==
== Features ==
Line 82: Line 77:
* Static branching support. Every pipeline element can be enabled/disabled at startup via a <condition> block.
* Static branching support. Every pipeline element can be enabled/disabled at startup via a <condition> block.


== Elements ==
== 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 following command line argument:
 
<code>--compositor=Compositor/ALS/als</code>
 
== Pipelines ==
 
=== Low-Spec pipeline ===
 
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 ===
 
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 aircrafts with complex cockpit geometry).
 
==== 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.
 
<syntaxhighlight lang="cpp">
void removeTransparentBins(simgear::EffectCullVisitor *cv,
                          osgUtil::RenderBin::RenderBinList &transparent_bins)
{
    osgUtil::RenderStage *stage = cv->getRenderStage();
    osgUtil::RenderBin::RenderBinList &rbl = stage->getRenderBinList();
    for (auto rbi = rbl.begin(); rbi != rbl.end(); ) {
        if (rbi->second->getSortMode() == osgUtil::RenderBin::SORT_BACK_TO_FRONT) {
            transparent_bins.insert(std::make_pair(rbi->first, rbi->second));
            rbl.erase(rbi++);
        } else {
            ++rbi;
        }
    }
}
</syntaxhighlight>
* 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 ==
 
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}}).


=== Buffers ===
=== Buffers ===
Line 225: Line 280:
</pass>
</pass>
</syntaxhighlight>
</syntaxhighlight>
== Pipelines ==
=== Low-Spec pipeline ===
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 ===
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 aircrafts with complex cockpit geometry).
==== 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.
<syntaxhighlight lang="cpp">
void removeTransparentBins(simgear::EffectCullVisitor *cv,
                          osgUtil::RenderBin::RenderBinList &transparent_bins)
{
    osgUtil::RenderStage *stage = cv->getRenderStage();
    osgUtil::RenderBin::RenderBinList &rbl = stage->getRenderBinList();
    for (auto rbi = rbl.begin(); rbi != rbl.end(); ) {
        if (rbi->second->getSortMode() == osgUtil::RenderBin::SORT_BACK_TO_FRONT) {
            transparent_bins.insert(std::make_pair(rbi->first, rbi->second));
            rbl.erase(rbi++);
        } else {
            ++rbi;
        }
    }
}
</syntaxhighlight>
* 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?


== TODO ==
== TODO ==
343

edits

Navigation menu