#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal glcore ps5
#pragma kernel Estimate
#include "Common.hlsl"
#include "Estimation.hlsl"
#include "RingBuffer.hlsl"
#include "RestirEstimation.hlsl"
StructuredBuffer<uint> _RingConfigBuffer;
StructuredBuffer<Realization> _PatchRealizations;
StructuredBuffer<PatchUtil::PatchGeometry> _PatchGeometries;
RWStructuredBuffer<SphericalHarmonics::RGBL1> _PatchIrradiances;
RWStructuredBuffer<PatchUtil::PatchStatisticsSet> _PatchStatistics;
RWStructuredBuffer<PatchUtil::PatchCounterSet> _PatchCounterSets;
uint _RingConfigOffset;
float _ShortHysteresis;
[numthreads(64, 1, 1)]
void Estimate(uint patchIdx : SV_DispatchThreadID)
{
if (RingBuffer::IsPositionUnused(_RingConfigBuffer, _RingConfigOffset, patchIdx))
return;
const Realization realization = _PatchRealizations[patchIdx];
float3 rayDirection;
if (realization.sample.sampleType == SAMPLE_TYPE_ENV)
{
rayDirection = realization.sample.hitPointOrDirection;
}
else
{
const float3 patchPosition = _PatchGeometries[patchIdx].position;
rayDirection = normalize(realization.sample.hitPointOrDirection - patchPosition);
}
if (realization.weight != 0.0f)
{
SphericalHarmonics::RGBL1 estimate;
estimate.l0 = realization.sample.radiance * SphericalHarmonics::y0;
estimate.l1s[0] = realization.sample.radiance * SphericalHarmonics::y1Constant * rayDirection.y;
estimate.l1s[1] = realization.sample.radiance * SphericalHarmonics::y1Constant * rayDirection.z;
estimate.l1s[2] = realization.sample.radiance * SphericalHarmonics::y1Constant * rayDirection.x;
SphericalHarmonics::MulMut(estimate, realization.weight);
ProcessAndStoreRadianceSample(_PatchIrradiances, _PatchStatistics, _PatchCounterSets, patchIdx, estimate, _ShortHysteresis);
}
}