Skip to content

Commit 8bfd44d

Browse files
committed
Updated packman;
Improved UI (Removed Debug val, Changing Resampling mode now also changes caustic resampling mode); Adjusted comments; Fixed Tone Mapper Mode for NRD script
1 parent 9704da0 commit 8bfd44d

15 files changed

+167
-122
lines changed

Source/RenderPasses/ReSTIR_FG/ReSTIR_FG.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,11 @@ void ReSTIR_FG::renderUI(Gui::Widgets& widget)
289289
{
290290
mClearReservoir = true;
291291
changed = true;
292+
//Switch Caustic Collection mode to fit the algorithm
293+
if (mRenderMode == RenderMode::FinalGather)
294+
mCausticCollectMode = CausticCollectionMode::All;
295+
if (mRenderMode == RenderMode::ReSTIRFG)
296+
mCausticCollectMode = CausticCollectionMode::Reservoir;
292297
}
293298

294299
if (auto group = widget.group("Specular Trace Options"))
@@ -603,9 +608,6 @@ void ReSTIR_FG::renderUI(Gui::Widgets& widget)
603608
group.tooltip("Stores the Sample generator state and uses them for the next pass instead of generating a new one");
604609
}
605610

606-
if (mpScene)
607-
widget.text(std::to_string(length(mpScene->getSceneBounds().extent())));
608-
609611
mOptionsChanged |= changed;
610612
}
611613

Source/RenderPasses/ReSTIR_FG/Shader/CausticResamplingPass.cs.slang

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,6 @@ cbuffer Constant
5151
float2 gPhotonRadius; //Caustic Photon Radius
5252
}
5353

54-
struct LightSample{
55-
float3 dir;
56-
float Li;
57-
};
58-
59-
struct PhotonLight{
60-
float4 pos;
61-
float4 flux;
62-
};
63-
6454
static const float kRayEpsilon = 0.99f;
6555
static const float kRayNearEpsilon = 0.01f;
6656
static const bool kCollectDirectPhotons = RESERVOIR_PHOTON_DIRECT;
@@ -344,7 +334,7 @@ void spatiotemporalResampling(uint2 pixel, inout SampleGenerator sg, inout Reser
344334

345335
//Get light pdf
346336
float ps = 0.0f;
347-
//Skip Sample if it was rejected by jacobian
337+
//Check if sample could be generated at the bias surface
348338
if (biasSurface.valid)
349339
{
350340
float NdotL = dot(causticSample.dir, biasSurface.normal);
@@ -378,20 +368,20 @@ void main(uint2 dTid : SV_DispatchThreadID)
378368
SurfaceFG surface = SurfaceFG(gSurface[index2Dto1D(dTid, gFrameDim.x)],viewDir.xyz);
379369

380370
bool collectDirect = (viewDir.w > 0.1) && kCollectDirectPhotons; // Check for direct photon collection
381-
//SurfaceFG surface = getSurface(dTid, false);
382371
if (!surface.valid)
383372
return;
384373

385374
#if STORE_SAMPLE_GEN_STATE
386375
SampleGenerator sg = gSampleGenState[index2Dto1D(dTid, gFrameDim.x)];
387376
#else
388377
SampleGenerator sg = SampleGenerator(dTid, gFrameCount + 8 * 32);
389-
#endif
378+
#endif
379+
390380
//Load reservoir from current iteration
391381
Reservoir r = {};
392382
CausticSample causticData = CausticSample();
393383

394-
//Load current reservoir in
384+
//Load current reservoir
395385
Reservoir current = Reservoir(gReservoir[0][dTid]);
396386
if (current.M > 0)
397387
{
@@ -400,7 +390,7 @@ void main(uint2 dTid : SV_DispatchThreadID)
400390

401391
r.combineReservoir(current, current.targetFunc, 0.5 /* random */);
402392

403-
393+
//Resampling
404394
#if MODE_SPATIOTEMPORAL
405395
spatiotemporalResampling(dTid, sg, r, causticData, surface);
406396
#elif MODE_TEMPORAL
@@ -416,20 +406,21 @@ void main(uint2 dTid : SV_DispatchThreadID)
416406
#endif
417407
gCausticSample[0][index2Dto1D(dTid, gFrameDim.x)] = causticData;
418408

419-
//Final Gather sample
409+
//Second Resample pass for directly collected photons on some metal surfaces
420410
if(collectDirect)
421411
{
422412
r = {};
423413
causticData = CausticSample();
424414

425-
//Load current reservoir in
415+
//Load current reservoir
426416
current = Reservoir(gReservoir[1][dTid]);
427417
if (current.M > 0)
428418
{
429419
causticData = gCausticSample[1][index2Dto1D(dTid, gFrameDim.x)];
430420
}
431421
r.combineReservoir(current, current.targetFunc, 0.5 /* random */);
432422

423+
//Resampling
433424
#if MODE_SPATIOTEMPORAL
434425
spatiotemporalResampling(dTid, sg, r, causticData, surface, 1);
435426
#elif MODE_TEMPORAL

Source/RenderPasses/ReSTIR_FG/Shader/CollectPhotons.rt.slang

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,9 @@ void anyHitReservoir(inout RayDataReservoir rayDataRes : SV_RayPayload, SphereAt
205205
IgnoreHit();
206206
}
207207

208-
//float target = (luminance(pd.flux) * M_1_PI) / surface.diffuseProb;
209-
208+
//RIS resampling
210209
float target = surface.getPdf(pd.dir, luminance(pd.flux))/ NdotL;
211210
if(rayDataRes.r.updateReservoir(gPhotonWeight[InstanceIndex()], target, sampleNext1D(rayDataRes.sg)))
212-
//if(rayDataRes.r.updateReservoir(1.0, target, sampleNext1D(rayDataRes.sg)))
213211
rayDataRes.idx = primIndex;
214212
IgnoreHit();
215213
}
@@ -340,32 +338,32 @@ void intersection()
340338
float3 stochPhotonContribution(in const ShadingData sd, in IMaterialInstance bsdf, float3 N , inout RayData rayData, bool isCaustic)
341339
{
342340
#if USE_STOCHASTIC_COLLECT
343-
//Get the size of the list to loop through.
344-
uint maxIdx = min(rayData.counter, STOCH_NUM_PHOTONS);
345-
float3 radiance = float3(0);
341+
//Get the size of the list to loop through.
342+
uint maxIdx = min(rayData.counter, STOCH_NUM_PHOTONS);
343+
float3 radiance = float3(0);
346344

347-
//Return when there is no element
348-
if (maxIdx == 0)
349-
return radiance;
345+
//Return when there is no element
346+
if (maxIdx == 0)
347+
return radiance;
350348

351-
//loop through the list and accumulate photons
352-
for (uint i = 0; i < maxIdx; i++)
353-
{
354-
//Get Photon info
355-
uint instanceIndex = isCaustic ? 1 : 0;
356-
PhotonData pd = PhotonData(gPackedPhotonData[instanceIndex][rayData.photonIdx[i]]);
357-
358-
float3 f_r = bsdf.eval(sd, pd.dir, rayData.sg);
359-
float NdotL = dot(N, pd.dir);
360-
if(NdotL > kMinCosTheta)
361-
radiance += max(0.f, (f_r * pd.flux) / NdotL);
362-
}
349+
//loop through the list and accumulate photons
350+
for (uint i = 0; i < maxIdx; i++)
351+
{
352+
//Get Photon info
353+
uint instanceIndex = isCaustic ? 1 : 0;
354+
PhotonData pd = PhotonData(gPackedPhotonData[instanceIndex][rayData.photonIdx[i]]);
355+
356+
float3 f_r = bsdf.eval(sd, pd.dir, rayData.sg);
357+
float NdotL = dot(N, pd.dir);
358+
if(NdotL > kMinCosTheta)
359+
radiance += max(0.f, (f_r * pd.flux) / NdotL);
360+
}
363361

364-
//Weight output radiance with number of photons for this pixel.
365-
//The weight equals 1 if there is less or equal than the maximum list size in the photon array. (Reservoir sampling)
366-
return radiance * (float(rayData.counter) / float(maxIdx));
362+
//Weight output radiance with number of photons for this pixel.
363+
//The weight equals 1 if there is less or equal than the maximum list size in the photon array. (Reservoir sampling)
364+
return radiance * (float(rayData.counter) / float(maxIdx));
367365
#else
368-
return float3(0);
366+
return float3(0);
369367
#endif
370368
}
371369

@@ -398,7 +396,7 @@ void causticPhotonCollection(in ShadingData sd, inout RayData rayData, bool coll
398396
rayDataRes.idx = -1;
399397
ray.Direction = -sd.V;
400398
#endif
401-
399+
//Second Reservoir Payload for directly resampled photons
402400
#if (CAUSTIC_COLLECTION_MODE == CAUSTIC_COLLECT_MODE_RESERVOIR) && RESERVOIR_PHOTON_DIRECT
403401
RayDataReservoir rayDataResDirect;
404402
rayDataResDirect.r = Reservoir();
@@ -416,19 +414,19 @@ void causticPhotonCollection(in ShadingData sd, inout RayData rayData, bool coll
416414
#endif // USE_STOCHASTIC_COLLECT
417415

418416

419-
//Collect Caustic Photons
417+
//Collect Caustic Photons as Reservoirs
420418
#if (CAUSTIC_COLLECTION_MODE == CAUSTIC_COLLECT_MODE_RESERVOIR)
421419
TraceRay(gPhotonAS, kRayFlags, 2 /* instanceInclusionMask */, 1 /* hitIdx */, 0 /* rayType count */, 0 /* missIdx */, ray, rayDataRes);
420+
//If a sample is in the reservoir, finalize it
422421
if(rayDataRes.r.M > 0 && rayDataRes.idx >= 0){
423422
rayDataRes.r.finalizeSample(1, 1.f);
424-
//rayDataRes.r.weightSum = rayDataRes.r.M / (M_PI * gPhotonRadius.y * gPhotonRadius.y);
425423
}
426-
rayDataRes.r.M = 1;
424+
rayDataRes.r.M = 1; //Set confidence weight
427425
rayData.sg = rayDataRes.sg;
428426
#if USE_STOCHASTIC_COLLECT
429427
ray.Direction = sd.faceN;
430428
#endif
431-
#else // (CAUSTIC_COLLECTION_MODE == CAUSTIC_COLLECT_MODE_RESERVOIR) Usual collection
429+
#else // (CAUSTIC_COLLECTION_MODE == CAUSTIC_COLLECT_MODE_RESERVOIR) | Usual collection
432430
TraceRay(gPhotonAS, kRayFlags, 2 /* instanceInclusionMask */, 0 /* hitIdx */, 0 /* rayType count */, 0 /* missIdx */, ray, rayData);
433431
float w = gPhotonWeight.y;
434432
#if USE_STOCHASTIC_COLLECT
@@ -470,12 +468,11 @@ void causticPhotonCollection(in ShadingData sd, inout RayData rayData, bool coll
470468
rayData.countPhotons = 0; //delete flag
471469
directRadiance += w * rayData.radiance;
472470
#endif // USE_STOCHASTIC_COLLECT
473-
//if((kEmissionToCausticFilter || MODE_FINAL_GATHER) && collectEmissive) directRadiance += miProperties.emission;
474471
#endif
475472
}
476473
} //end if(validSurface)
477474

478-
//Temporal Caustic Filter
475+
//Temporal Caustic Filter (non Reservoir based)
479476
#if (CAUSTIC_COLLECTION_MODE == CAUSTIC_COLLECT_MODE_TEMPORAL)
480477
//Get Motion Vector and get reprojected pixel
481478
float2 motionOffset = gMVec[launchIndex] * float2(launchDim);
@@ -539,6 +536,7 @@ void causticPhotonCollection(in ShadingData sd, inout RayData rayData, bool coll
539536
#endif
540537
}
541538

539+
//Collect photons for the final gather sample
542540
void fgSampleCollection(float3 genPosW, inout RayData rayData, bool valid){
543541
const uint2 launchIndex = DispatchRaysIndex().xy;
544542
const uint2 launchDim = DispatchRaysDimensions().xy;

Source/RenderPasses/ReSTIR_FG/Shader/FinalShading.cs.slang

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ void main(uint2 pixel : SV_DispatchThreadID)
150150

151151
float3 viewDir;
152152
HitInfo hitInfo;
153+
154+
//Evaluate RTXDI sample
153155
#if USE_RTXDI
154156
viewDir = -gViewDI[pixel].xyz;
155157

@@ -193,6 +195,8 @@ void main(uint2 pixel : SV_DispatchThreadID)
193195
}
194196
#endif //RTXDI
195197

198+
//Evaluate ReSTIR FG sample
199+
196200
//Load final gather and ReSTIR FG data
197201
float4 viewTmp = gView[pixel];
198202
viewDir = -viewTmp.xyz;
@@ -266,13 +270,12 @@ void main(uint2 pixel : SV_DispatchThreadID)
266270
if(needEmissive)
267271
emission += bsdfProperties.emission * thp;
268272

273+
// Add caustics
269274
#if !USE_RESTIR_GI
270-
271275
#if (USE_CAUSTIC_FILTER_RESERVOIR && !RESERVOIR_PHOTON_DIRECT) || !USE_CAUSTIC_FILTER_RESERVOIR
272276
caustic += gCausticRadiance[pixel].xyz * thp;
273277
#endif
274278
#if USE_CAUSTIC_FILTER_RESERVOIR
275-
//sd.mtl.setActiveLobes((uint)LobeType::All);
276279
Reservoir causticReservoir = Reservoir(gCausticReservoir[pixel]);
277280
float3 causticReservoirRadianceDiffuse = float3(0);
278281
float3 causticResRadianceSpec = float3(0);

Source/RenderPasses/ReSTIR_FG/Shader/GenerateFinalGatherSamples.rt.slang

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ cbuffer Constant{
3131
uint gHashSize; //Size is always 2^x
3232
bool gUseAlphaTest; //Alpha test
3333
bool gDeltaRejection; //Accept every non delta surface as diffuse
34-
//bool gCreateFallbackSample; //Creates a reference sample if current sample was invalid
3534
uint _pad2;
3635
}
3736

Source/RenderPasses/ReSTIR_FG/Shader/GeneratePhotons.rt.slang

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,6 @@ void rayGen()
351351
return;
352352

353353
ray.Direction = fromLocalToWorld(pls.normal, woLocal);
354-
//pls.flux /= lightDirPDF;
355354
pls.flux *= M_PI; //Lambert Emitter
356355
}
357356
#endif
@@ -395,23 +394,24 @@ void rayGen()
395394
photon.dir = ray.Direction;
396395
reflectedDiffuse = rayData.diffuseHit;
397396

398-
//rejection
397+
//Gen Roulette value for rejecting
399398
float rndRoulette = sampleNext1D(rayData.sg);
400399
bool roulette = rndRoulette <= gRejection;
401400
bool minDistanceRoulette = true;
402401

402+
//Check if photon should be rejected if it is too close to the light source
403403
if(rayData.distance < gGenerationLampIntersectGuard){
404404
minDistanceRoulette = sampleNext1D(rayData.sg) < gGenerationLampIntersectGuardStoreProbability;
405405
photon.flux *= 1.f/gGenerationLampIntersectGuardStoreProbability;
406406
}
407407

408-
//store photon light
408+
//Store photons
409409
if (reflectedDiffuse && (roulette || storeAsCaustic) && minDistanceRoulette)
410410
{
411411
uint photonType = storeAsCaustic ? 1 : 0; //Global = 0 or caustic = 1
412412
bool storePhoton = true;
413413
if (kUsePhotonCulling && (kUseCausticCulling || photonType == 0))
414-
storePhoton = cullingTest(photonPos);
414+
storePhoton = cullingTest(photonPos); //Photon Culling
415415
if(storePhoton){
416416
uint photonIndex = 0;
417417
if(photonType == 0)

Source/RenderPasses/ReSTIR_FG/Shader/TraceTransmissionDelta.rt.slang

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,12 @@ void rayGen()
204204
invalidSample = true;
205205
}
206206

207+
//Determine if surface is diffuse
207208
bool isTransmission = validBSDF ? bsdfSample.isLobe(LobeType::Transmission) : false;
208209
float3 diffuseProb = bsdfProperties.diffuseReflectionAlbedo / (bsdfProperties.diffuseReflectionAlbedo + bsdfProperties.specularReflectionAlbedo + bsdfProperties.diffuseTransmissionAlbedo + bsdfProperties.specularTransmissionAlbedo);
209210
float meanDiffuseProb = (diffuseProb.x + diffuseProb.y + diffuseProb.z) / 3;
210211
bool hasDiffuseParts = gRequDiffParts ? (meanDiffuseProb > kDiffuseCutoff) || bsdfProperties.roughness > kRoughnessCutoff : true;
211-
isDiffuse = hasDiffuseParts;// && bsdfSample.isLobe(LobeType::NonDeltaReflection);
212+
isDiffuse = hasDiffuseParts;
212213

213214
if(isDiffuse || invalidSample)
214215
break;

scripts/ReSTIR_FG_NRD.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def render_graph_ReSTIR_FG_NRD():
99
g.create_pass('ReSTIR_FG', 'ReSTIR_FG', {})
1010
g.create_pass('NRD', 'NRD', {'enabled': True, 'outputSize': 'Default', 'worldSpaceMotion': True, 'disocclusionThreshold': 2.0, 'maxIntensity': 500.0, 'diffusePrepassBlurRadius': 16.0, 'specularPrepassBlurRadius': 16.0, 'diffuseMaxAccumulatedFrameNum': 31, 'specularMaxAccumulatedFrameNum': 31, 'diffuseMaxFastAccumulatedFrameNum': 2, 'specularMaxFastAccumulatedFrameNum': 2, 'diffusePhiLuminance': 2.0, 'specularPhiLuminance': 1.0, 'diffuseLobeAngleFraction': 0.800000011920929, 'specularLobeAngleFraction': 0.8999999761581421, 'roughnessFraction': 0.5, 'diffuseHistoryRejectionNormalThreshold': 0.0, 'specularVarianceBoost': 1.0, 'specularLobeAngleSlack': 10.0, 'disocclusionFixEdgeStoppingNormalPower': 8.0, 'disocclusionFixMaxRadius': 32.0, 'disocclusionFixNumFramesToFix': 4, 'historyClampingColorBoxSigmaScale': 2.0, 'spatialVarianceEstimationHistoryThreshold': 4, 'atrousIterationNum': 6, 'minLuminanceWeight': 0.0, 'depthThreshold': 0.019999999552965164, 'luminanceEdgeStoppingRelaxation': 0.5, 'normalEdgeStoppingRelaxation': 0.30000001192092896, 'roughnessEdgeStoppingRelaxation': 0.30000001192092896, 'enableAntiFirefly': False, 'enableReprojectionTestSkippingWithoutMotion': False, 'enableSpecularVirtualHistoryClamping': False, 'enableRoughnessEdgeStopping': True, 'enableMaterialTestForDiffuse': False, 'enableMaterialTestForSpecular': False})
1111
g.create_pass('GBufferRT', 'GBufferRT', {'outputSize': 'Default', 'samplePattern': 'Stratified', 'sampleCount': 16, 'useAlphaTest': True, 'adjustShadingNormals': True, 'forceCullMode': False, 'cull': 'Back', 'texLOD': 'Mip0', 'useTraceRayInline': False, 'useDOF': True})
12-
g.create_pass('ToneMapper', 'ToneMapper', {'outputSize': 'Default', 'useSceneMetadata': True, 'exposureCompensation': 0.0, 'autoExposure': False, 'filmSpeed': 100.0, 'whiteBalance': False, 'whitePoint': 6500.0, 'operator': 'Aces', 'clamp': True, 'whiteMaxLuminance': 1.0, 'whiteScale': 11.199999809265137, 'fNumber': 1.0, 'shutter': 1.0, 'exposureMode': 'AperturePriority'})
12+
g.create_pass('ToneMapper', 'ToneMapper', {'outputSize': 'Default', 'useSceneMetadata': True, 'exposureCompensation': 0.0, 'autoExposure': False, 'filmSpeed': 100.0, 'whiteBalance': False, 'whitePoint': 6500.0, 'operator': 'Linear', 'clamp': True, 'whiteMaxLuminance': 1.0, 'whiteScale': 11.199999809265137, 'fNumber': 1.0, 'shutter': 1.0, 'exposureMode': 'AperturePriority'})
1313
g.add_edge('ReSTIR_FG.residualRadiance', 'ModulateIllumination.residualRadiance')
1414
g.add_edge('AccumulatePass.output', 'ToneMapper.src')
1515
g.add_edge('NRD.filteredSpecularRadianceHitDist', 'ModulateIllumination.specularRadiance')

0 commit comments

Comments
 (0)