diff --git a/README.md b/README.md index c172749..f820f9e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Version 2.2.0. ## Introduction -**RTX** **D**ynamic **I**llumination is a framework that originally facilitated implementation of efficient direct light sampling in real-time renderers. It is based on the **ReSTIR** algorithm published in the paper called "Spatiotemporal reservoir resampling for real-time ray tracing with dynamic direct lighting" by B. Bitterli et al. +**RTX** **D**ynamic **I**llumination is a framework that facilitates the implementations of efficient direct light sampling in real-time renderers. It is based on the **ReSTIR** algorithm published in the paper called "Spatiotemporal reservoir resampling for real-time ray tracing with dynamic direct lighting" by B. Bitterli et al. Starting with version 2.0, RTXDI also includes **ReSTIR GI** functionality, which allows applications to apply importance resampling to indirect illumination rendered using path tracing. For more information about the indirect illumination algorithm, see the paper called "ReSTIR GI: Path Resampling for Real-Time Path Tracing" by Y. Ouyang et al. The feature is described in more detail in [this document](doc/RestirGI.md). diff --git a/doc/ShaderAPI-RestirGI.md b/doc/ShaderAPI-RestirGI.md index 1fce407..770de44 100644 --- a/doc/ShaderAPI-RestirGI.md +++ b/doc/ShaderAPI-RestirGI.md @@ -57,12 +57,12 @@ Returns `true` if the provided reservoir contains a valid GI sample. ### `RTXDI_LoadGIReservoir` RTXDI_GIReservoir RTXDI_LoadGIReservoir( - RTXDI_ResamplingRuntimeParameters params, + RTXDI_ReservoirBufferParameters reservoirParams, uint2 reservoirPosition, uint reservoirArrayIndex) RTXDI_GIReservoir RTXDI_LoadGIReservoir( - RTXDI_ResamplingRuntimeParameters params, + RTXDI_ReservoirBufferParameters reservoirParams, uint2 reservoirPosition, uint reservoirArrayIndex, out uint miscFlags) @@ -73,14 +73,14 @@ Loads and unpacks a GI reservoir from the provided reservoir storage buffer. The void RTXDI_StoreGIReservoir( const RTXDI_GIReservoir reservoir, - RTXDI_ResamplingRuntimeParameters params, + RTXDI_ReservoirBufferParameters reservoirParams, uint2 reservoirPosition, uint reservoirArrayIndex) void RTXDI_StoreGIReservoir( const RTXDI_GIReservoir reservoir, const uint miscFlags, - RTXDI_ResamplingRuntimeParameters params, + RTXDI_ReservoirBufferParameters reservoirParams, uint2 reservoirPosition, uint reservoirArrayIndex) @@ -140,14 +140,16 @@ Creates a GI reservoir from a raw light sample. uint maxReservoirAge; bool enablePermutationSampling; bool enableFallbackSampling; + uint uniformRandomNumber; }; GI_GIReservoir RTXDI_GITemporalResampling( const uint2 pixelPosition, const RAB_Surface surface, const RTXDI_GIReservoir inputReservoir, inout RAB_RandomSamplerState rng, - const RTXDI_GITemporalResamplingParameters tparams, - const RTXDI_ResamplingRuntimeParameters params) + const RTXDI_RuntimeParameters params, + const RTXDI_ReservoirBufferParameters reservoirParams, + const RTXDI_GITemporalResamplingParameters tparams) Implements the core functionality of the temporal resampling pass. Takes the previous G-buffer, motion vectors, and two GI reservoir buffers - current and previous - as inputs. Tries to match the surfaces in the current frame to surfaces in the previous frame. If a match is found for a given pixel, the current and previous reservoirs are combined. @@ -171,8 +173,9 @@ For more information on the members of the `RTXDI_GITemporalResamplingParameters const RAB_Surface surface, const RTXDI_GIReservoir inputReservoir, inout RAB_RandomSamplerState rng, - const RTXDI_GISpatialResamplingParameters sparams, - const RTXDI_ResamplingRuntimeParameters params) + const RTXDI_RuntimeParameters params, + const RTXDI_ReservoirBufferParameters reservoirParams, + const RTXDI_GISpatialResamplingParameters sparams) Implements the core functionality of the spatial resampling pass. Operates on the current frame G-buffer and its reservoirs. For each pixel, considers a number of its neighbors and, if their surfaces are similar enough to the current pixel, combines their reservoirs. @@ -197,14 +200,16 @@ For more information on the members of the `RTXDI_GISpatialResamplingParameters` uint biasCorrectionMode; bool enablePermutationSampling; bool enableFallbackSampling; + uint uniformRandomNumber; }; RTXDI_GIReservoir RTXDI_GISpatioTemporalResampling( const uint2 pixelPosition, const RAB_Surface surface, RTXDI_GIReservoir inputReservoir, inout RAB_RandomSamplerState rng, - const RTXDI_GISpatioTemporalResamplingParameters stparams, - const RTXDI_ResamplingRuntimeParameters params) + const RTXDI_RuntimeParameters params, + const RTXDI_ReservoirBufferParameters reservoirParams, + const RTXDI_GISpatioTemporalResamplingParameters stparams) Implements the core functionality of a combined spatiotemporal resampling pass. This is similar to a sequence of `RTXDI_GITemporalResampling` and `RTXDI_GISpatialResampling`, with the exception that the input reservoirs are all taken from the previous frame. This function is useful for implementing a lighting solution in a single shader, which generates the initial samples, applies spatiotemporal resampling, and shades the final samples. diff --git a/doc/ShaderAPI.md b/doc/ShaderAPI.md index 1d58d7c..94fd46f 100644 --- a/doc/ShaderAPI.md +++ b/doc/ShaderAPI.md @@ -206,35 +206,37 @@ The function returns the position of the final selected texel in the `position` ### `RTXDI_PresampleLocalLights` void RTXDI_PresampleLocalLights( - inout RAB_RandomSamplerState rng, + inout RAB_RandomSamplerState rng, RTXDI_TEX2D pdfTexture, uint2 pdfTextureSize, uint tileIndex, uint sampleInTile, - RTXDI_ResamplingRuntimeParameters params) + RTXDI_LightBufferRegion localLightBufferRegion, + RTXDI_RISBufferSegmentParameters localLightsRISBufferSegmentParams) Selects one local light using the provided PDF texture and stores its information in the RIS buffer at the position identified by the `tileIndex` and `sampleInTile` parameters. Additionally, stores compact light information in the companion buffer that is managed by the application, through the `RAB_StoreCompactLightInfo` function. ### `RTXDI_PresampleEnvironmentMap` void RTXDI_PresampleEnvironmentMap( - inout RAB_RandomSamplerState rng, + inout RAB_RandomSamplerState rng, RTXDI_TEX2D pdfTexture, uint2 pdfTextureSize, uint tileIndex, uint sampleInTile, - RTXDI_ResamplingRuntimeParameters params) + RTXDI_RISBufferSegmentParameters risBufferSegmentParams) Selects one environment map texel using the provided PDF texture and stores its information in the RIS buffer at the position identified by the `tileIndex` and `sampleInTile` parameters. ### `RTXDI_PresampleLocalLightsForReGIR` void RTXDI_PresampleLocalLightsForReGIR( - inout RAB_RandomSamplerState rng, + inout RAB_RandomSamplerState rng, inout RAB_RandomSamplerState coherentRng, uint lightSlot, - RTXDI_SampleParameters sampleParams, - RTXDI_ResamplingRuntimeParameters params) + RTXDI_LightBufferRegion localLightBufferRegion, + RTXDI_RISBufferSegmentParameters localLightRISBufferSegmentParams, + ReGIR_Parameters regirParams) Selects one local light using RIS with `sampleParams.numRegirSamples` proposals weighted relative to a specific ReGIR world space cell. The cell position and size are derived from its index; the cell index is derived from the `lightSlot` parameter: each cell contains a number of light slots packed together and stored in the RIS buffer. Additionally, stores compact light information in the companion buffer that is managed by the application, through the `RAB_StoreCompactLightInfo` function. @@ -243,51 +245,44 @@ The weights of lights relative to ReGIR cells are computed using the [`RAB_GetLi ### `RTXDI_SampleLocalLights` RTXDI_DIReservoir RTXDI_SampleLocalLights( - inout RAB_RandomSamplerState rng, + inout RAB_RandomSamplerState rng, inout RAB_RandomSamplerState coherentRng, - RAB_Surface surface, + RAB_Surface surface, RTXDI_SampleParameters sampleParams, - RTXDI_ResamplingRuntimeParameters params, + ReSTIRDI_LocalLightSamplingMode localLightSamplingMode, + RTXDI_LightBufferRegion localLightBufferRegion, + #if RTXDI_ENABLE_PRESAMPLING + RTXDI_RISBufferSegmentParameters localLightRISBufferSegmentParams, + #if RTXDI_REGIR_MODE != RTXDI_REGIR_DISABLED + ReGIR_Parameters regirParams, + #endif + #endif out RAB_LightSample o_selectedSample) Selects one local light sample using RIS with `sampleParams.numLocalLightSamples` proposals weighted relative to the provided `surface`, and returns a reservoir with the selected light sample. The sample itself is returned in the `o_selectedSample` parameter. The proposals are picked from a RIS buffer tile that's picked using `coherentRng`, which should generate the same random numbers for a group of adjacent shader threads for performance. If the RIS buffer is not available, this function will fall back to uniform sampling from the local light pool, which is typically much more noisy. The RIS buffer must be pre-filled with samples using the [`RTXDI_PresampleLocalLights`](#rtxdi_presamplelocallights) function in a preceding pass. -### `RTXDI_SampleLocalLightsFromReGIR` - - RTXDI_DIReservoir RTXDI_SampleLocalLightsFromReGIR( - inout RAB_RandomSamplerState rng, - inout RAB_RandomSamplerState coherentRng, - RAB_Surface surface, - uint numRegirSamples, - uint numLocalLightSamples, - RTXDI_ResamplingRuntimeParameters params, - out RAB_LightSample o_selectedSample) - -A variant of [`RTXDI_SampleLocalLights`](#rtxdi_samplelocallights) that samples from a ReGIR cell instead of the RIS buffer, if ReGIR is available and a cell exists at the surface position. If ReGIR is not available or the surface is out of bounds of the ReGIR spatial structure, the initial proposals will be drawn from the RIS buffer if that is available, or from the local lights with a uniform PDF. - -The ReGIR cells are matched to the surface with jitter applied, and the magnitude of this jitter is specified in `params.regirCommon.samplingJitter`. The specific jitter offset is determined using the `coherentRng` generator, which should return the same random numbers for a group of adjacent shader threads for performance. - ### `RTXDI_SampleInfiniteLights` RTXDI_DIReservoir RTXDI_SampleInfiniteLights( - inout RAB_RandomSamplerState rng, - RAB_Surface surface, + inout RAB_RandomSamplerState rng, + RAB_Surface surface, uint numSamples, - RTXDI_ResamplingRuntimeParameters params, - out RAB_LightSample o_selectedSample) + RTXDI_LightBufferRegion infiniteLightBufferRegion, + inout RAB_LightSample o_selectedSample) Selects one infinite light sample using RIS with `numSamples` proposals weighted relative to the provided `surface`, and returns a reservoir with the selected light sample. The sample itself is returned in the `o_selectedSample` parameter. ### `RTXDI_SampleEnvironmentMap` RTXDI_DIReservoir RTXDI_SampleEnvironmentMap( - inout RAB_RandomSamplerState rng, + inout RAB_RandomSamplerState rng, inout RAB_RandomSamplerState coherentRng, - RAB_Surface surface, + RAB_Surface surface, RTXDI_SampleParameters sampleParams, - RTXDI_ResamplingRuntimeParameters params, + RTXDI_EnvironmentLightBufferParameters params, + RTXDI_RISBufferSegmentParameters risBufferSegmentParams, out RAB_LightSample o_selectedSample) Selects one sample from the importance sampled environment light using RIS with `sampleParams.numEnvironmentMapSamples` proposals weighted relative to the provided `surface`, and returns a reservoir with the selected light sample. The sample itself is returned in the `o_selectedSample` parameter. @@ -301,7 +296,7 @@ The proposals are picked from a RIS buffer tile, similar to [`RTXDI_SampleLocalL inout RAB_RandomSamplerState rng, RAB_Surface surface, RTXDI_SampleParameters sampleParams, - RTXDI_ResamplingRuntimeParameters params, + RTXDI_LightBufferParameters lightBufferParams, out RAB_LightSample o_selectedSample) ``` @@ -356,11 +351,19 @@ compensates for this overweighting, but it can only happen after all neighbors h inout RAB_RandomSamplerState coherentRng, RAB_Surface surface, RTXDI_SampleParameters sampleParams, - RTXDI_ResamplingRuntimeParameters params, + RTXDI_LightBufferParameters lightBufferParams, + ReSTIRDI_LocalLightSamplingMode localLightSamplingMode, + #if RTXDI_ENABLE_PRESAMPLING + RTXDI_RISBufferSegmentParameters localLightRISBufferSegmentParams, + RTXDI_RISBufferSegmentParameters environmentLightRISBufferSegmentParams, + #if RTXDI_REGIR_MODE != RTXDI_REGIR_DISABLED + ReGIR_Parameters regirParams, + #endif + #endif out RAB_LightSample o_lightSample) ``` -This function is a combination of `RTXDI_SampleLocalLightsFromReGIR` (or `RTXDI_SampleLocalLights` if compiled without ReGIR support), `RTXDI_SampleInfiniteLights`, `RTXDI_SampleEnvironmentMap`, and `RTXDI_SampleBrdf`. Reservoirs returned from each function are combined into one final reservoir, which is returned. +This function is a combination of `RTXDI_SampleLocalLights`, `RTXDI_SampleInfiniteLights`, `RTXDI_SampleEnvironmentMap`, and `RTXDI_SampleBrdf`. Reservoirs returned from each function are combined into one final reservoir, which is returned. ### `RTXDI_TemporalResampling` @@ -379,9 +382,10 @@ This function is a combination of `RTXDI_SampleLocalLightsFromReGIR` (or `RTXDI_ uint2 pixelPosition, RAB_Surface surface, RTXDI_DIReservoir curSample, - RAB_RandomSamplerState rng, - RTXDI_TemporalResamplingParameters tparams, - RTXDI_ResamplingRuntimeParameters params, + inout RAB_RandomSamplerState rng, + RTXDI_RuntimeParameters params, + RTXDI_ReservoirBufferParameters reservoirParams, + RTXDI_DITemporalResamplingParameters tparams, out int2 temporalSamplePixelPos, inout RAB_LightSample selectedLightSample) @@ -408,9 +412,10 @@ For more information on the members of the `RTXDI_TemporalResamplingParameters` uint2 pixelPosition, RAB_Surface centerSurface, RTXDI_DIReservoir centerSample, - RAB_RandomSamplerState rng, - RTXDI_SpatialResamplingParameters sparams, - RTXDI_ResamplingRuntimeParameters params, + inout RAB_RandomSamplerState rng, + RTXDI_RuntimeParameters params, + RTXDI_ReservoirBufferParameters reservoirParams, + RTXDI_DISpatialResamplingParameters sparams, inout RAB_LightSample selectedLightSample) @@ -440,9 +445,10 @@ For more information on the members of the `RTXDI_SpatialResamplingParameters` s uint2 pixelPosition, RAB_Surface surface, RTXDI_DIReservoir curSample, - RAB_RandomSamplerState rng, - RTXDI_SpatioTemporalResamplingParameters stparams, - RTXDI_ResamplingRuntimeParameters params, + inout RAB_RandomSamplerState rng, + RTXDI_RuntimeParameters params, + RTXDI_ReservoirBufferParameters reservoirParams, + RTXDI_DISpatioTemporalResamplingParameters stparams, out int2 temporalSamplePixelPos, inout RAB_LightSample selectedLightSample) @@ -453,8 +459,7 @@ Implements the core functionality of a combined spatiotemporal resampling pass. void RTXDI_BoilingFilter( uint2 LocalIndex, float filterStrength, - RTXDI_ResamplingRuntimeParameters params, - inout RTXDI_DIReservoir state) + inout RTXDI_DIReservoir reservoir) Applies a boiling filter over all threads in the compute shader thread group. This filter attempts to reduce boiling by removing reservoirs whose weight is significantly higher than the weights of their neighbors. Essentially, when some lights are important for a surface but they are also unlikely to be located in the initial sampling pass, ReSTIR will try to hold on to these lights by spreading them around, and if such important lights are sufficiently rare, the result will look like light bubbles appearing and growing, then fading. This filter attempts to detect and remove such rare lights, trading boiling for bias. diff --git a/shaders/LightingPasses/RtxdiApplicationBridge.hlsli b/shaders/LightingPasses/RtxdiApplicationBridge.hlsli index 722f580..d4cc461 100644 --- a/shaders/LightingPasses/RtxdiApplicationBridge.hlsli +++ b/shaders/LightingPasses/RtxdiApplicationBridge.hlsli @@ -845,7 +845,8 @@ bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, floa hitUV = payload.barycentrics; } #endif - + REPORT_RAY(hitAnything); + if (o_lightIndex != RTXDI_InvalidLightIndex) { o_randXY = randomFromBarycentric(hitUVToBarycentric(hitUV)); diff --git a/src/Testing.cpp b/src/Testing.cpp index ed588c5..313ad51 100644 --- a/src/Testing.cpp +++ b/src/Testing.cpp @@ -23,7 +23,7 @@ using namespace donut; namespace fs = std::filesystem; -const char* g_ApplicationTitle = "RTX Direct Illumination SDK Sample"; +const char* g_ApplicationTitle = "RTX Dynamic Illumination SDK Sample"; static void toupper(std::string& s) {