3.7 KiB
3.7 KiB
Ray Tracing Manager: BLAS Cache and Per-Frame TLAS
Optional subsystem that enables hybrid or full ray traced shadows via Ray Query. It builds and caches BLAS per mesh and rebuilds a TLAS from the current DrawContext when enabled.
- Files:
src/core/raytracing/raytracing.h/.cpp
Device Feature & Extension Enablement
- Feature detection happens in
DeviceManager::init_vulkan()and sets:VK_KHR_acceleration_structure,VK_KHR_ray_query, andVK_KHR_deferred_host_operations(if supported).- Device features are appended via
DeviceBuilder.add_pNext(...).
DescriptorManager::gpuSceneDataLayout()adds a TLAS binding at(set=0, binding=1)when AS is supported.
BLAS Build & Cache
AccelStructureHandle getOrBuildBLAS(const std::shared_ptr<MeshAsset>& mesh):- One GAS per
MeshAsset, keyed by mesh pointer. - Populated with one triangle geometry per
GeoSurface. - Built with
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHRand device-local storage + scratch. - Cached in
_blasByMeshfor reuse across frames. - When a BLAS does not exist yet, the mesh is queued for an asynchronous build and an empty handle is returned; callers must treat this as "BLAS not ready" and skip the instance for the current frame (see TLAS section below).
pump_blas_builds(max_builds_per_frame)advances an internal BLAS build queue and is called once per frame from the engine main loop to spread work across multiple frames instead of doing all BLAS builds in a single spike.
- One GAS per
TLAS Rebuild Per Frame
VkAccelerationStructureKHR buildTLASFromDrawContext(const DrawContext& dc):- Iterates
dc.OpaqueSurfacesand creates one instance per render object. - Looks up BLAS by
RenderObject::sourceMesh(theMeshAsset*); if a BLAS is not cached yet, it callsgetOrBuildBLASwith a non-owningshared_ptrto queue a build and then skips the instance for this frame. - Uploads instances to a CPU→GPU buffer with device address.
- Builds TLAS with
immediate_submitand stores device address for Ray Query.
- Iterates
Renderer Integration
- In
VulkanEngine::draw()before building passes:- If RT mode is enabled (
shadowSettings.mode != 0) or ray-traced SSR is enabled (enableSSR && reflectionMode != 0), and the manager exists, TLAS is rebuilt from the latest draw context. - TLAS only references BLAS that are already built; instances whose meshes are still in the BLAS build queue are skipped until their BLAS completes.
- If RT mode is enabled (
- In
VulkanEngine::run()at the start of each frame (after waiting for the previous frame fence):- Calls
RayTracingManager::flushPendingDeletes()to safely destroy any BLAS scheduled for deferred deletion. - Calls
RayTracingManager::pump_blas_builds(1)to build at most one queued BLAS per frame (tunable if you want more or fewer builds per frame).
- Calls
- Lighting pass binds the TLAS at
set=0,binding=1when available.
Modes & UI
- Mode 0: Shadow maps only (CSM).
- Mode 1: Hybrid — selected cascades assisted by Ray Query (configurable bitmask).
- Mode 2: Ray Query only (no shadow maps).
Notes & Caveats
- BLAS cache key is the
MeshAsset*. If you destroy or rebuild meshes (or their GPU buffers) you must invalidate associated BLAS viaRayTracingManager::removeBLASForMesh(mesh)orremoveBLASForBuffer(vertexBuffer). - CPU→GPU memory is used for the TLAS instance buffer to simplify updates. On some platforms, you may prefer staging + device-local.
- Because BLAS builds are asynchronous and capped per frame, newly spawned meshes may take a few frames before they appear in the ray-traced path; this is a deliberate tradeoff to avoid large hitches when many meshes are introduced.
- The RT path requires Vulkan 1.2+ with Ray Query and Acceleration Structure features available.