study/first_study/Library/PackageCache/com.unity.render-pipelines.universal@d10049dfa479/Runtime/RendererFeatures/SurfaceCacheGI/ScreenResolveLookup.compute

105 lines
4.3 KiB
Plaintext
Raw Normal View History

#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal glcore ps5
#pragma kernel Lookup
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl"
#include "SurfaceCacheCore/Common.hlsl"
#include "SurfaceCacheCore/PatchUtil.hlsl"
#include "SurfaceCacheCore/IrradianceCompression.hlsl"
Texture2D<float> _ScreenDepths;
Texture2D<float3> _ScreenFlatNormals;
RWTexture2D<float3> _ResultL0;
RWTexture2D<float3> _ResultL10;
RWTexture2D<float3> _ResultL11;
RWTexture2D<float3> _ResultL12;
RWTexture2D<float> _ResultNdcDepths;
RWStructuredBuffer<PatchUtil::PatchCounterSet> _PatchCounterSets;
StructuredBuffer<SphericalHarmonics::RGBL1> _PatchIrradiances;
StructuredBuffer<uint> _CellPatchIndices;
StructuredBuffer<int3> _CascadeOffsets;
uint _GridSize;
uint _CascadeCount;
uint _SampleCount;
float _VoxelMinSize;
float4x4 _ClipToWorldTransform;
uint _FrameIdx;
float3 _GridTargetPos;
#define GROUP_SIZE 8
[numthreads(GROUP_SIZE, GROUP_SIZE, 1)]
void Lookup(uint2 lowResPixelPos : SV_DispatchThreadID)
{
uint2 lowResSize;
_ResultL0.GetDimensions(lowResSize.x, lowResSize.y);
if (any(lowResPixelPos >= lowResSize))
return;
const uint2 fullResPixelPos = lowResPixelPos * lowResScreenScaling;
uint2 fullResSize;
_ScreenDepths.GetDimensions(fullResSize.x, fullResSize.y);
const float ndcDepth = LoadNdcDepth(_ScreenDepths, fullResPixelPos);
_ResultNdcDepths[lowResPixelPos] = ndcDepth;
if (ndcDepth == invalidNdcDepth)
return;
const float2 uv = PixelPosToUvPos(fullResPixelPos, rcp(float2(fullResSize)));
const float3 worldPos = ComputeWorldSpacePosition(uv, ndcDepth, _ClipToWorldTransform);
const float3 worldNormal = _ScreenFlatNormals[fullResPixelPos];
QrngKronecker rng;
rng.Init(lowResPixelPos, 0);
const int cascadeResolution = PatchUtil::ResolveCascadeIndex(_GridTargetPos, worldPos, _GridSize, _CascadeCount, _VoxelMinSize);
const uint cascadeIdx = cascadeResolution == -1 ? _CascadeCount - 1 : cascadeResolution;
const float voxelSize = PatchUtil::GetVoxelSize(_VoxelMinSize, cascadeIdx);
SphericalHarmonics::RGBL1 irradianceSum = (SphericalHarmonics::RGBL1)0;
float weightSum = 0.0f;
{
uint patchIdx = PatchUtil::FindPatchIndexAndUpdateLastAccess(_GridTargetPos, _CellPatchIndices, _GridSize, _CascadeOffsets, _PatchCounterSets, _CascadeCount, _VoxelMinSize, worldPos, worldNormal, _FrameIdx);
if (patchIdx != PatchUtil::invalidPatchIndex)
{
const float weight = 0.01f;
irradianceSum = SphericalHarmonics::MulPure(_PatchIrradiances[patchIdx], weight);
weightSum = weight;
}
}
const float3x3 orthoBasis = OrthoBasisFromVector(worldNormal);
for (uint sampleIdx = 0; sampleIdx < _SampleCount; ++sampleIdx)
{
float2 jitter = float2(rng.GetFloat(0), rng.GetFloat(1)) * 2.0f - 1.0f;
const float3 jitteredWorldPos = worldPos + (orthoBasis[0] * jitter.x + orthoBasis[1] * jitter.y) * voxelSize;
jitter = float2(rng.GetFloat(2), rng.GetFloat(3));
const float cosSpread = 0.9f; // This constant was empirically determined.
const float3 localJitteredDirection = SampleConeUniform(jitter.x, jitter.y, cosSpread);
const float3 jitteredWorldDir = mul(orthoBasis, localJitteredDirection);
uint patchIdx = PatchUtil::FindPatchIndexAndUpdateLastAccess(_GridTargetPos, _CellPatchIndices, _GridSize, _CascadeOffsets, _PatchCounterSets, _CascadeCount, _VoxelMinSize, jitteredWorldPos, jitteredWorldDir, _FrameIdx);
if (patchIdx != PatchUtil::invalidPatchIndex)
{
SphericalHarmonics::AddMut(irradianceSum, _PatchIrradiances[patchIdx]);
weightSum += 1.0f;
}
rng.NextSample();
}
SphericalHarmonics::RGBL1 output = (SphericalHarmonics::RGBL1)0; // Initialization is theoretically not required. Only done to silence shader compiler warning.
PatchUtil::MarkInvalid(output);
if (weightSum != 0.0f)
output = SphericalHarmonics::MulPure(irradianceSum, rcp(weightSum));
IrradianceCompression::CompressAndStore(output, _ResultL0, _ResultL10, _ResultL11, _ResultL12, lowResPixelPos);
}