![]() |
Lysa
0.0
Lysa 3D Engine
|
As a GPU-driven engine Lysa pre-allocates GPU memory and descriptor space for all managed resources at startup. Every pool has a hard ceiling; exceeding it causes an assertion failure or out-of-memory error at runtime. This page lists every configurable limit, its default value, and how to raise it.
Global resource pools are shared across all scenes and render targets. They are configured through lysa::ResourcesCapacity, which is embedded in lysa::ContextConfiguration:
| Field | Default | Description |
|---|---|---|
images | 500 | Maximum number of images held in CPU and GPU memory simultaneously. Covers all textures loaded from assets packs and any render targets registered with the resource system. |
samplers | 20 | Maximum number of GPU image samplers that can be created. Each unique combination of filtering and address-mode settings consumes one entry. |
material | 100 | Maximum number of standard and shader materials (combined) resident in CPU and GPU memory at once. |
meshes | 1000 | Maximum number of mesh objects in CPU and GPU memory. Every distinct mesh loaded from an assets pack or created at runtime occupies one slot. |
surfaces | meshes × 5 | Maximum number of mesh surfaces across all meshes. A surface maps to one draw call and carries one material assignment. |
vertices | surfaces × 1000 | Maximum number of vertices across all surfaces, stored in a single shared GPU vertex buffer. |
indices | vertices × 10 | Maximum number of indices across all surfaces, stored in a single shared GPU index buffer. |
surfaces, vertices, and indices defaults are computed from meshes at initialisation time. If you set meshes explicitly but leave the others at zero, the engine recalculates them. Override them individually when your meshes are unusually dense or unusually sparse.Each lysa::Scene has its own budget configured through lysa::SceneConfiguration:
| Field | Default | Description |
|---|---|---|
asyncObjectUpdatesPerFrame | 50 | Maximum number of node transform updates processed per frame when instances are added asynchronously via addInstance(..., async=true). Raise this to reduce the lag between spawning objects and them appearing in the scene. |
maxLights | 10 | Maximum number of lights active in the scene at once (point, spot, and directional combined). Backed by a fixed-size GPU buffer; adding more lights beyond this limit is silently ignored. |
maxMeshInstances | 5000 | Maximum number of lysa::MeshInstance objects that can be registered with the scene simultaneously. Drives the size of the per-frame GPU instance buffer used by the GPU-driven draw-command pipeline. |
maxMeshSurfacePerPipeline | 10000 | Maximum number of mesh surface draw calls submitted per graphics pipeline per frame. This is the indirect draw buffer size for the frustum-culling and draw-command generation compute passes. |
maxPipelines | 25 | Maximum number of distinct graphics pipelines (unique material × render-pass combinations) that the scene can manage. |
maxLights directly affects the size of the light uniform buffer uploaded every frame. Setting it very high on scenes that only ever use a handful of lights wastes GPU memory. Conversely, if you add a light beyond the limit the engine will not raise an error : the extra light will be silently discarded.Each lysa::ShaderMaterial exposes a fixed array of generic float4 parameters to the fragment shader:
A shader material therefore has room for 4 × float4 (64 bytes) of user-defined uniform data. This constant is compiled into both the engine and the HLSL/Slang shaders; changing it requires recompiling all shaders.
The following fields in lysa::ContextConfiguration affect global runtime behaviour:
| Field | Default | Description |
|---|---|---|
framesInFlight | 2 | Number of frames rendered concurrently. Affects the size of all per-frame GPU ring-buffers. Values above 3 are unlikely to improve throughput and increase latency and memory usage. |
maxShadowMapsPerScene | 20 | Maximum number of shadow maps allocated per scene. One map is consumed per shadow-casting light; cascaded shadow maps consume one map per cascade. |
eventsReserveCapacity | 100 | Initial capacity of the event queue. The queue grows dynamically, so this is only a hint to avoid early reallocations. |
commandsReserveCapacity | 1000 | Initial capacity of the deferred command buffer. Like the event queue, it grows on demand. |
The default values are intentionally conservative so that a basic application works without any configuration. A production scene will generally need to raise several of them. A rough starting checklist:
resourcesCapacity.meshes to that number plus a margin for runtime-created meshes (e.g. procedural geometry, debug shapes).resourcesCapacity.surfaces explicitly instead of relying on the meshes × 5 default.surfaces first and let the derived defaults cover vertices and indices, unless your meshes are unusually high- or low-polygon.SceneConfiguration::maxMeshInstances must cover the peak number of lysa::MeshInstance objects alive in one scene at the same time, not the total across the game lifetime.maxLights accordingly. Remember that each cascade of a cascaded shadow map counts as one shadow map against maxShadowMapsPerScene.resourcesCapacity.material. Instancing the same material on multiple meshes does not increase this count.