Rendering

This section provides a general overview of the OpenGL rendering pipeline in Met.3D.

The render pipeline is implemented in MSceneViewGLWidget::paintGL(). Each actor implements MActor::getRenderPasses(), which returns the render passes in which the actor participates. If the current render pass matches one of the returned flags and the actor is enabled, it is rendered in that pass.

By default, actors are rendered in the SHADOW_MAPPING, RENDER_SCENE, and RENDER_UI passes.

The current render pass can be queried at runtime using MSceneViewGLWidget::renderStep().

(*) --> "Multisampled cascaded shadow pass"
--> "DVR volume lighting pass"
If "Single fullscreen actor" then
-->[true] "Single fullscreen actor pass"
--> "Multisample resolve"
else
-->[false] "Multisampled 3-D actors pass"
--> "Multisampled DVR pass"
Endif
--> "Multisample resolve"
If "Use FSR upscaling" then
-->[true] "FSR upscaling"
--> "2-D UI actors pass"
else
-->[false] "2-D UI actors pass"
Endif
--> "Label pass"
--> "Present to viewport"
--> (*)

Fig. 46 Render pipeline implemented in MSceneViewGLWidget.

The following subsections describe each render pass in detail.

Multisampled cascaded shadow pass

The multisampled cascaded shadow pass renders cascaded shadow maps of all 3-D actors in the scene. During this pass, MSceneViewGLWidget::renderStep() is set to SHADOW_MAPPING.

This is a depth-only pass and therefore does not have a color attachment. Currently, the cascaded shadow map uses three cascades.

The pass calls MActor::render() on the actors rendered in this pass.

If supported by the selected OIT method, this pass uses Order independent transparency to render transparent shadows. The overall process is described in Shadow mapping.

DVR volume lighting pass

Only the Volume raycaster (3D iso-surfaces and DVR) with DVR enabled participate.

The pass calls MActor::render() for all actors using the VOLUMETRIC_SHADOW_MAPPING render pass.

Only raycasters with Direct Volume Rendering enabled participate in this pass. Raycasters update their volumetric light maps when required and when volumetric lighting is enabled. Because updating DVR light maps is expensive, updates are performed only when necessary.

Single fullscreen actor pass

If single fullscreen actor mode is enabled for the scene view, only one actor is rendered. During this pass, MSceneViewGLWidget::renderStep() is set to RENDER_SCENE.

The actor to render must be selected in the scene view properties. The scene view renders the actor by calling MActor::renderToFullScreen().

This pass uses an internal rendering resolution instead of the viewport resolution. This allows rendering at a fixed resolution or using upscaling techniques to reach the target resolution.

Multisampled 3-D actors pass

If single fullscreen actor mode is disabled, the scene view renders all enabled actors in the scene that participate in the RENDER_SCENE pass.

This pass is similar to Single fullscreen actor pass, but calls MActor::render() for all enabled actors. It also uses an internal rendering resolution instead of the viewport resolution.

This pass uses Order independent transparency for transparency rendering.

Multisampled DVR pass

This pass is executed only when single fullscreen actor mode is disabled.

During this pass, MSceneViewGLWidget::renderStep() is set to RENDER_DVR. The scene view renders all actors participating in the RENDER_DVR pass.

Currently, only the Volume raycaster (3D iso-surfaces and DVR) uses this pass. A warning is logged if more than one actor is rendered, since overlapping volumes are currently composited incorrectly.

Multisample resolve

This pass resolves the multisampled framebuffer produced by the previous render passes.

Subsequent passes do not support multisampling and therefore require a single-sample framebuffer.

When using Simple OIT (Alpha-to-coverage) or Stochastic transparency, this pass also resolves transparency.

FSR Upscaling

If enabled, this pass uses FSR 1.0 to upscale the framebuffer to the target resolution.

This is especially useful for scenes containing an expensive raycaster.

The upscaled image is rendered into a new framebuffer at the target resolution. The pass also reuses the depth values from the original, non-upscaled depth buffer.

If FSR is disabled, the original framebuffer is copied into a new framebuffer at the target resolution instead.

2-D UI actors pass

This pass renders all actors participating in the RENDER_UI pass. During this pass, MSceneViewGLWidget::renderStep() is set to RENDER_UI.

The scene view calls MActor::renderToUiLayer() for each participating actor.

If single fullscreen actor mode is enabled, only the fullscreen actor is rendered during this pass.

This pass is primarily used for rendering 2-D interface elements, such as colour bars, at the target resolution without upscaling.

Label pass

The label pass renders all labels in the scene into the framebuffer produced by the previous pass.

Because this framebuffer still contains depth information, depth testing can be enabled for labels.

At this point the scene is fully rendered. When saving a screenshot, this framebuffer is used instead of the viewport contents.

Present to viewport

Finally, the resulting framebuffer is rendered to the viewport.

This step resizes the internal rendering resolution to match the viewport resolution. If the aspect ratio differs from the viewport, the image may appear stretched.