Lysa Nodes  0.0
Lysa Nodes — Scene Graph for the Lysa Engine
Rendering window

MainWindow.ixx : window and renderer configuration

The window configuration and the MainWindow class are co-located in src/MainWindow.ixx. lysa::RenderingWindowConfiguration is an aggregate that describes everything from the window title down to the post-processing stack:

export module main_window;
import lysa;
lysa::RenderingWindowConfiguration renderingWindowConfiguration {
.title = "Lysa – Rotating Asset",
.mode = lysa::RenderingWindowMode::WINDOWED,
.width = 1280,
.height = 720,
.renderTargetConfiguration = {
.presentMode = vireo::PresentMode::VSYNC,
.rendererConfiguration = {
.rendererType = lysa::RendererType::DEFERRED,
.depthStencilFormat = vireo::ImageFormat::D32_SFLOAT,
.clearColor = lysa::float3{0.05f, 0.05f, 0.10f},
.toneMappingType = lysa::ToneMappingType::ACES,
.postProcessAntiAliasingType = lysa::PostProcessAntiAliasingType::SMAA,
.bloomEnabled = true,
.ambientOcclusionType = lysa::AmbientOcclusionType::GTAO,
}
}
};

MainWindow class

MainWindow subscribes to READY and CLOSING exactly as in the basic tutorial:

class MainWindow : public lysa::RenderingWindow {
public:
MainWindow() : RenderingWindow(renderingWindowConfiguration) {
lysa::ctx().events.subscribe(lysa::RenderingWindowEvent::READY, id,
[&](const lysa::Event&) {
auto title = renderingWindowConfiguration.title;
title += (lysa::ctx().config.backendConfiguration.backend
== vireo::Backend::VULKAN)
? " (Vulkan)" : " (DirectX)";
setTitle(title);
show();
});
lysa::ctx().events.subscribe(lysa::RenderingWindowEvent::CLOSING, id,
[&](const lysa::Event&) { lysa::ctx().exit = true; });
}
};

READY fires once the GPU swapchain is initialised. The window is hidden by default and shown only at this point so the first visible frame is already rendered.

Renderer type

rendererType selects the rendering pipeline:

Value Description
DEFERRED G-buffer pass → lighting pass → post-processing. Best for many dynamic lights.
FORWARD Single forward color pass. Simpler; fewer lights per draw call.

The deferred path writes albedo, normals, roughness/metallic, and depth into G-buffers during the geometry pass, then resolves all lighting in a single compute pass. This decouples the cost of lighting from the number of rendered triangles, making it efficient for scenes with many overlapping lights.

Present mode and depth format

presentMode:

Value Effect
VSYNC Locks to the display refresh rate; no tearing
IMMEDIATE No synchronisation; lowest latency but may tear

depthStencilFormat: D32_SFLOAT gives full 32-bit depth precision. Use D24_UNORM_S8_UINT when a stencil buffer is needed alongside depth.

Post-processing options

Field Options
toneMappingType NONE, REINHARD, ACES
postProcessAntiAliasingType NONE, FXAA, SMAA
ambientOcclusionType NONE, SSAO, GTAO
bloomEnabled true / false

ACES tone mapping maps HDR radiance values to the display range with a cinematic contrast curve. SMAA (Subpixel Morphological Anti-Aliasing) is a post-process filter that reduces jaggies without accumulation artefacts. GTAO (Ground Truth Ambient Occlusion) is a screen-space technique that darkens concavities for added depth.

All post-processing passes run as compute shaders on the GPU and can be individually disabled for performance profiling.

Next : Node