You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
6.1 KiB
163 lines
6.1 KiB
#pragma kernel DilateCell
|
|
|
|
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Dilate.cs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl"
|
|
|
|
CBUFFER_START(APVDilation)
|
|
float4 _DilationParameters;
|
|
float4 _DilationParameters2;
|
|
CBUFFER_END
|
|
|
|
#define _ProbeCount (uint)_DilationParameters.x
|
|
#define _ValidityThreshold _DilationParameters.y
|
|
#define _SearchRadius _DilationParameters.z
|
|
#define _MinBrickSizeForDilation _DilationParameters.w
|
|
|
|
#define _SquaredDistanceWeight (_DilationParameters2.x > 0)
|
|
#define _EnableSkyOcclusion (_DilationParameters2.y > 0)
|
|
#define _EnableSkyDirection (_DilationParameters2.z > 0)
|
|
|
|
StructuredBuffer<int> _NeedDilating;
|
|
StructuredBuffer<float3> _ProbePositionsBuffer;
|
|
|
|
RWStructuredBuffer<DilatedProbe> _OutputProbes;
|
|
|
|
|
|
// Sampling is copied from SampleAPV()
|
|
void AddProbeSample(APVResources apvRes, float3 uvw, inout DilatedProbe probe, float weight, inout float shWeight, inout float soWeight)
|
|
{
|
|
// SH data
|
|
float4 L0_L1Rx = SAMPLE_TEXTURE3D_LOD(apvRes.L0_L1Rx, s_point_clamp_sampler, uvw, 0).rgba;
|
|
float4 L1G_L1Ry = SAMPLE_TEXTURE3D_LOD(apvRes.L1G_L1Ry, s_point_clamp_sampler, uvw, 0).rgba;
|
|
float4 L1B_L1Rz = SAMPLE_TEXTURE3D_LOD(apvRes.L1B_L1Rz, s_point_clamp_sampler, uvw, 0).rgba;
|
|
|
|
float4 l2_R = SAMPLE_TEXTURE3D_LOD(apvRes.L2_0, s_point_clamp_sampler, uvw, 0).rgba;
|
|
float4 l2_G = SAMPLE_TEXTURE3D_LOD(apvRes.L2_1, s_point_clamp_sampler, uvw, 0).rgba;
|
|
float4 l2_B = SAMPLE_TEXTURE3D_LOD(apvRes.L2_2, s_point_clamp_sampler, uvw, 0).rgba;
|
|
float4 l2_C = SAMPLE_TEXTURE3D_LOD(apvRes.L2_3, s_point_clamp_sampler, uvw, 0).rgba;
|
|
|
|
if (!all(L0_L1Rx.xyz < 0.0001f))
|
|
{
|
|
probe.L0 += L0_L1Rx.xyz * weight;
|
|
probe.L1_0 += float3(L0_L1Rx.w, L1G_L1Ry.x, L1B_L1Rz.x) * weight;
|
|
probe.L1_1 += float3(L1G_L1Ry.w, L1G_L1Ry.y, L1B_L1Rz.y) * weight;
|
|
probe.L1_2 += float3(L1B_L1Rz.w, L1G_L1Ry.z, L1B_L1Rz.z) * weight;
|
|
|
|
probe.L2_0 += float3(l2_R.x, l2_G.x, l2_B.x) * weight;
|
|
probe.L2_1 += float3(l2_R.y, l2_G.y, l2_B.y) * weight;
|
|
probe.L2_2 += float3(l2_R.z, l2_G.z, l2_B.z) * weight;
|
|
probe.L2_3 += float3(l2_R.w, l2_G.w, l2_B.w) * weight;
|
|
probe.L2_4 += float3(l2_C.x, l2_C.y, l2_C.z) * weight;
|
|
|
|
shWeight += weight;
|
|
}
|
|
|
|
// Sky occlusion data
|
|
if (_EnableSkyOcclusion)
|
|
{
|
|
float4 SO_L0L1 = SAMPLE_TEXTURE3D_LOD(apvRes.SkyOcclusionL0L1, s_linear_clamp_sampler, uvw, 0).rgba * weight;
|
|
|
|
if (SO_L0L1.x >= 0.0001f)
|
|
{
|
|
probe.SO_L0L1 += SO_L0L1 * weight;
|
|
|
|
if (_EnableSkyDirection)
|
|
{
|
|
int3 texCoord = uvw * _PoolDim - 0.5f; // No interpolation for sky shading indices
|
|
uint index = LOAD_TEXTURE3D(apvRes.SkyShadingDirectionIndices, texCoord).x * 255.0;
|
|
|
|
probe.SO_Direction = index == 255 ? float3(0, 0, 0) : apvRes.SkyPrecomputedDirections[index].rgb * weight;
|
|
}
|
|
|
|
soWeight += weight;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScaleProbe(inout DilatedProbe probe, float weight)
|
|
{
|
|
probe.L0 *= weight;
|
|
probe.L1_0 *= weight;
|
|
probe.L1_1 *= weight;
|
|
probe.L1_2 *= weight;
|
|
probe.L2_0 *= weight;
|
|
probe.L2_1 *= weight;
|
|
probe.L2_2 *= weight;
|
|
probe.L2_3 *= weight;
|
|
probe.L2_4 *= weight;
|
|
}
|
|
|
|
[numthreads(64, 1, 1)]
|
|
void DilateCell(uint3 id : SV_DispatchThreadID)
|
|
{
|
|
if (id.x < _ProbeCount)
|
|
{
|
|
uint probeIdx = id.x;
|
|
|
|
if (_NeedDilating[probeIdx] > 0)
|
|
{
|
|
float3 centralPosition = _ProbePositionsBuffer[probeIdx] - _WorldOffset;
|
|
DilatedProbe probe = (DilatedProbe)0;
|
|
|
|
float3 uvw;
|
|
uint subdiv;
|
|
float shWeight = 0, soWeight = 0;
|
|
float3 uvwDelta = rcp(_PoolDim);
|
|
|
|
float3 biasedPosWS;
|
|
if (TryToGetPoolUVWAndSubdiv(FillAPVResources(), centralPosition, 0, 0, uvw, subdiv, biasedPosWS))
|
|
{
|
|
float stepSize = _MinBrickSizeForDilation / 3.0f;
|
|
|
|
// Inflate search radius a bit.
|
|
float radius = 1.5f * _SearchRadius;
|
|
|
|
int iterationCount = ceil(radius / stepSize);
|
|
|
|
for (int x = -1; x <= 1; ++x)
|
|
{
|
|
for (int y = -1; y <= 1; ++y)
|
|
{
|
|
for (int z = -1; z <= 1; ++z)
|
|
{
|
|
float3 dir = normalize(float3(x, y, z));
|
|
for (int s = 0; s < iterationCount; ++s)
|
|
{
|
|
float3 samplePos = centralPosition + dir * (stepSize * s);
|
|
float3 sampleUVW;
|
|
if (TryToGetPoolUVW(FillAPVResources(), samplePos, 0, 0, sampleUVW))
|
|
{
|
|
float d = distance(samplePos, centralPosition);
|
|
if (d > 0 && d <= _SearchRadius)
|
|
{
|
|
if (_SquaredDistanceWeight)
|
|
{
|
|
d *= d;
|
|
}
|
|
AddProbeSample(FillAPVResources(), sampleUVW, probe, rcp(d), shWeight, soWeight);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (shWeight > 0)
|
|
ScaleProbe(probe, rcp(shWeight));
|
|
|
|
if (soWeight > 0)
|
|
probe.SO_L0L1 *= rcp(soWeight);
|
|
probe.SO_Direction = SafeNormalize(probe.SO_Direction);
|
|
|
|
_OutputProbes[probeIdx] = probe;
|
|
}
|
|
}
|
|
}
|