#define SAMPLE_TYPE_HIT 0
#define SAMPLE_TYPE_ENV 1
struct Sample
{
float3 radiance;
float3 hitPointOrDirection;
float3 rayOrigin;
float3 rayDirection;
uint sampleType; // SAMPLE_TYPE_HIT is hit, SAMPLE_TYPE_ENV is env.
};
struct Realization
{
Sample sample;
float weight;
float confidence;
};
float TargetFunction(Sample sample)
{
return sample.radiance.r + sample.radiance.g + sample.radiance.b;
}
struct Reservoir
{
Sample sample;
float weightSum;
float confidenceSum;
void InitWithSample(in Sample newSample, float confidence, float weight)
{
confidenceSum = confidence;
weightSum = weight;
sample = newSample;
}
void Update(in Sample newSample, float confidence, float weight, float u)
{
confidenceSum += confidence;
weightSum += weight;
if (u * weightSum < weight)
sample = newSample;
}
};
Realization CreateRealizationFromReservoir(in Reservoir reservoir)
{
Realization realization;
realization.sample = reservoir.sample;
realization.confidence = reservoir.confidenceSum;
if (reservoir.weightSum == 0.0f)
realization.weight = 0.0f;
else
realization.weight = reservoir.weightSum / (TargetFunction(reservoir.sample) * reservoir.confidenceSum);
return realization;
}