RTXGI SDK

repository·main·Indexed 43 days ago

https://github.com/nvidia-rtx/rtxgi

An SDK providing real-time radiance caching techniques, including Neural Radiance Cache (NRC) and Spatially Hashed Radiance Cache (SHaRC), to enable high-quality indirect illumination in path-traced scenes by replacing expensive indirect bounces with world-space cache lookups.

Tokens
7.5K
Snippets
13
Records
29
Agent score
57%

What's inside RTXGI

  1. Overview of RTXGI SDK techniques

    main

    RTXGI SDK implements two state-of-the-art radiance caching techniques designed to replace traditional probe-based irradiance caching with a world-space radiance cache. This allows for real-time indirect illumination by sampling cached radiance when scene geometry is hit during path tracing. These techniques can be combined with a regular path tracing pipeline for primary rays, reducing costs by using cache lookups for indirect bounce evaluation.

    Supported techniques:

    • Neural Radiance Cache (NRC): An experimental AI-based approach that requires NVIDIA Tensor Cores.
    • Spatially Hashed Radiance Cache (SHaRC): A technique supported on a wider range of hardware (any DXR GPU) without vendor-specific requirements, though it has certain limitations.
  2. Overview of the Neural Radiance Cache (NRC) algorithm

    main

    The Neural Radiance Cache (NRC) is an AI-driven technique used to improve signal quality and performance in path tracing. It works by predicting radiance at any point in the virtual world using live-trained data.

    Unlike irradiance caching which targets diffuse lighting, NRC learns radiance, making it effective for glossy reflections. It is agnostic to scene data (materials, BRDFs, geometry) because it continuously adapts by tracing training paths at full length to optimize the underlying neural network each frame.

    Workflow:

    1. Update Pass: Run a path tracer at lower-than-target resolution to write training radiance for the neural network.
    2. Query Pass: Run a full-resolution pathtracer pass to create query points where predicted radiance is needed.
    3. Resolve Pass: The neural network predicts radiance at the queried points (performed via an internal compute pass).

    Path Termination Heuristic: To reduce noise and cost, paths can be terminated early. The decision is based on a path spread (ray cone) heuristic. When the cone's radius reaches a user-specified threshold ($t$), the path is considered safe to terminate and query the cache instead of continuing the trace.

  3. Understand the RTXGI project structure

    main

    The repository is organized into the following directories:

    DirectoryDetails
    /DocsDocumentation for showcased technologies
    /ExternalHelper dependencies used by the samples
    /AssetsAssets and scene definitions
    /SamplesSamples showcasing usage of NRC and SHaRC
    /LibrariesBinaries, source code, and includes for NRC and SHaRC
  4. Manage NRC Memory: Internal vs. App-managed

    main

    The NRC library supports two memory management modes, controlled by globalSettings.enableGPUMemoryAllocation:

    1. Internal Management (SDK-managed):

    • Set globalSettings.enableGPUMemoryAllocation = true during initialization.
    • The SDK manages all buffers.
    • Use GetBuffers() to obtain handles/views to these buffers for use in path tracing or custom resolve passes.

    2. Application-managed:

    • Set globalSettings.enableGPUMemoryAllocation = false during initialization.
    • The application is responsible for creating and managing buffers.
    • During the Configure step, use GetBuffersAllocationInfo(const ContextSettings& contextSettings, BuffersAllocationInfo& outBuffersAllocationInfo) to determine the required element size, stride, and allowed view types.
    • Pass these buffers to the Configure method.
  5. Configure NRC pathtracer passes (Update vs Query)

    main

    NRC requires two distinct pathtracer passes. The dispatch sizes for these passes depend on the contextSettings configuration:

    1. Update Pass: Used for writing path data to train the Neural Network (NN). This pass runs at a lower resolution than the target. It is recommended to use computeIdealTrainingDimensions to determine the optimal resolution and set it in contextSettings.trainingDimensions early on. The dispatch size must match contextSettings.trainingDimensions.
    2. Query Pass: Used to create query points where the NN predicts radiance. The dispatch size for this pass must be equal to contextSettings.frameDimensions.

    Note: The update pass is independent of the query pass, allowing for potential performance optimizations.

    // Recommended way to calculate training resolution
    nrc_uint2 trainingDims = computeIdealTrainingDimensions(frameDimensions, avgTrainingVerticesPerPath);
    // Set this on contextSettings.trainingDimensions early in the setup
  6. NRC API Architecture: CPU vs Shader-side

    main

    Integrating NRC requires interacting with both the CPU and the GPU (shaders):

    CPU-side API (NrcD3d12.h or NrcVk.h):

    • Handles initialization and (re)configuration of the NRC context.
    • Manages resource memory (app-managed vs. internally managed).
    • Invokes neural network operations: creating query data and training the network.
    • Invokes the Resolve pass (an internal compute pass) to resolve radiance at queried points.

    Shader-side API (Nrc.hlsli, NrcHelpers.hlsli, NrcStructures.h):

    • Used within the application's pathtracer to declare and write training and query data to NRC resources.
  7. Debug NRC buffers with Nsight Graphics

    main

    To ensure the application's path tracer is correctly writing to NRC buffers, use Nsight Graphics Frame Capture.

    • Structured Memory Configuration: Use this feature in Nsight to inspect the contents of NRC buffers regardless of their packing. This is useful for verifying the data within buffers like NrcRadianceParameters.
    • Limitation: Neural network calls are currently not available for inspection within Nsight Graphics Frame Debugging.
  8. Configure Vulkan extensions and features for NRC

    main

    If using the Vulkan API, you must specify required extensions and features during device creation. Use the provided helper functions to retrieve the necessary strings:

    uint32_t GetVulkanDeviceExtensions(char const* const*& outStringArray);
    uint32_t GetVulkanInstanceExtensions(char const* const*& outStringArray);
    uint32_t GetVulkanDeviceFeatures(char const* const*& outStringArray);

    The following features must be available and enabled:

    • VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME
    • VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME
    • VK_EXT_scalar_block_layout
    // Example of retrieving required extensions/features
    uint32_t deviceExtCount;
    const char** deviceExts;
    GetVulkanDeviceExtensions(deviceExts);
    // Use deviceExts during vkCreateDevice...
  9. Build the RTXGI pathtracer sample

    main

    To get up and running with the RTXGI SDK pathtracer sample (which demonstrates NRC and SHaRC integration in a unidirectional Monte Carlo path tracer), follow these steps:

    1. Clone the repository: Clone the project recursively to your preferred location.
    2. Configure with CMake: Use CMake GUI or the CLI to configure and generate the solution. Set the source directory to the repository root and the build directory to a new directory within the repository root.
    3. Run the sample: Open the generated rtxgi2_samples.sln in the build directory and run the pathtracer project.

    Note: To run the NVRHI Vulkan rendering backend version, use the -vk debug command line argument.

    git clone --progress --recursive --branch main -v "https://github.com/NVIDIAGameWorks/RTXGI.git" "local-repo-path"
  10. Manage NRC frame lifecycle and shutdown

    main

    To ensure correct execution and resource cleanup, follow this lifecycle:

    1. End of Frame: Once the command list is submitted, call EndFrame(ID3D12CommandQueue* cmdQueue). The command queue must be the same one used for all previous NRC command lists.
    2. Shutdown: When the application closes:
      • Destroy all created contexts using Destroy(Context& context).
      • Call Shutdown() to shut down the NRC library.
    // End of frame
    EndFrame(cmdQueue);
    
    // Application shutdown
    Destroy(myContext);
    Shutdown();
  11. Understand the pathtracer sample UI and settings

    main

    The pathtracer sample is an elementary path tracer that uses NRC or SHaRC to terminate early into radiance/irradiance caches. The UI provides several control panels:

    • Generic settings: Load new scenes via JSON files (specifying GLTF assets, lights, and camera) and toggle four settings affecting the pathtracer and caching techniques.
    • Path tracing settings: Control bounces, samples per pixel, material property dials, and debug views (normals, worldspace positions, etc.). This panel also selects radiance/irradiance caching modes and denoising modes.
    • NRC settings: Toggle NRC, fine-tune parameters, and use Resolve Mode for visual debugging.
    • SHaRC settings: Toggle SHaRC, manually clear the cache, fine-tune hash-grid data factors, and use Enable Debug to inspect direct cache contents.
    • Lighting: Modify initial light data defined in the JSON scene file.
    • Tone mapping: Post-processing for tone mapping and clamping radiance values.
  12. Resolve radiance using the built-in or custom pass

    main

    The final radiance is not produced directly by the pathtracer and requires a resolve pass.

    Built-in Resolve

    If your signal is combined, use the built-in Resolve API. This pass takes predicted radiance from query records, modulates them by the path throughput, and adds them to the final image.

    Status Resolve(ID3D12GraphicsCommandList4* cmdList, ID3D12Resource* outputBuffer);

    Custom Resolve

    If your application uses a split signal (e.g., separate diffuse and specular buffers), you must implement a custom compute pass. You can use NrcGetPathInfoIndex to find the correct path info and NrcUnpackQueryPathInfo / NrcUnpackRadiance to retrieve the data. You must also use an intermediate buffer (like brdfTypeTarget) recorded during the pathtracer pass to know which output buffer to write the unpacked radiance to.

    // Example Custom Resolve snippet
    const uint pathIndex = NrcGetPathInfoIndex(screenResolution, launchIndex, sampleIndex, samplesPerPixel);
    const NrcQueryPathInfo path = NrcUnpackQueryPathInfo(nrcQueryPathInfo[pathIndex]);
    
    if (path.queryBufferIndex < 0xFFFFFFFF)
    {
        float3 radiance = NrcUnpackRadiance(nrcQueryRadiance[path.queryBufferIndex], radianceUnpackMultiplier) * path.prefixThroughput;
        // Write to specific target based on recorded BRDF type
        if(uBrdfType == BRDF_SPECULAR)
            specularPathTracingTarget[launchIndex] += float4(radiance, 0.0f);
        else if(uBrdfType == BRDF_DIFFUSE)
            diffusePathTracingTarget[launchIndex] += float4(radiance, 0.0f);
    }