Files
Cielonos/Assets/Plugins/FlexibleUI/FlexibleBlur/Resources/VRComputeBlurs.compute
SoulliesOfficial 649b7a5ddc 更新
2026-05-23 08:27:50 -04:00

407 lines
21 KiB
Plaintext

#define THREADGROUP_DIMENSION_X 8
#define THREADGROUP_DIMENSION_Y 8
#pragma kernel ThreeTapCheckerboardVR
#pragma kernel FourTapCornersVR
#pragma kernel FourTapCrossVR
#pragma kernel FiveTapStarVR
#pragma kernel SevenTapHexagonalVR
#pragma kernel EightTapCornersAndCrossVR
#pragma kernel NineTapOctagonalVR
#pragma kernel QuadraticHorizontalVR
#pragma kernel QuadraticVerticalVR
#pragma kernel GaussianHorizontalVR
#pragma kernel GaussianVerticalVR
Texture2DArray<half4> Source;
RWTexture2DArray<half4> Result;
float2 ResultDimensions;
float SampleDist;
float SampleOffset;
bool OffsetCenter;
uint BlurIteration;
uint TapsPerSideHor;
uint TapsPerSideVert;
SamplerState linearClampSampler;
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void ThreeTapCheckerboardVR(uint3 id : SV_DispatchThreadID)
{
const float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const float2 texelIndex = floor(idf);
const half checker = 1 - 2 * fmod(floor(0.5h * BlurIteration) + texelIndex.x + texelIndex.y, 2);
const half orientation = fmod(BlurIteration, 2);
const half invOrientation = 1.0h - orientation;
const half texelWidth = 1.0h / ResultDimensions.x;
const half texelHeight = 1.0h / ResultDimensions.y;
const half horOffset = texelWidth * SampleDist;
const half vertOffset = texelHeight * SampleDist;
const half2 offset1 = half2(
checker * (0.5h * texelWidth * invOrientation + horOffset * orientation),
checker * (vertOffset * invOrientation + 0.5h * texelHeight * orientation)
);
const half2 offset2 = half2(
lerp(horOffset, -horOffset * checker, orientation),
lerp(-vertOffset * checker, vertOffset, orientation)
);
const half2 offset3 = half2(
lerp(-horOffset, -horOffset * checker, orientation),
lerp(-vertOffset * checker, -vertOffset, orientation)
);
const half4 sumL = 0.334h * Source.SampleLevel(linearClampSampler, uv + half3(offset1, 0), 0)
+ 0.333h * Source.SampleLevel(linearClampSampler, uv + half3(offset2, 0), 0)
+ 0.333h * Source.SampleLevel(linearClampSampler, uv + half3(offset3, 0), 0);
Result[half3(id.xy, 0)] = sumL;
uv.z = 1;
const half4 sumR = 0.334h * Source.SampleLevel(linearClampSampler, uv + half3(offset1, 0), 0)
+ 0.333h * Source.SampleLevel(linearClampSampler, uv + half3(offset2, 0), 0)
+ 0.333h * Source.SampleLevel(linearClampSampler, uv + half3(offset3, 0), 0);
Result[half3(id.xy, 1)] = sumR;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void FourTapCornersVR(uint3 id : SV_DispatchThreadID)
{
const float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half2 sampleDist = SampleDist / ResultDimensions;
const half4 sumL = 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, -sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, -sampleDist.y, 0), 0);
Result[half3(id.xy, 0)] = sumL;
uv.z = 1;
const half4 sumR = 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, -sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, -sampleDist.y, 0), 0);
Result[half3(id.xy, 1)] = sumR;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void FourTapCrossVR(uint3 id : SV_DispatchThreadID)
{
const float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half2 sampleDist = SampleDist / ResultDimensions;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
const half4 sumL = 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, halfTexelOffset.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, halfTexelOffset.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, -sampleDist.y, 0), 0);
Result[half3(id.xy, 0)] = sumL;
uv.z = 1;
const half4 sumR = 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, halfTexelOffset.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, halfTexelOffset.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, sampleDist.y, 0), 0)
+ 0.25h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, -sampleDist.y, 0), 0);
Result[half3(id.xy, 1)] = sumR;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void FiveTapStarVR(uint3 id : SV_DispatchThreadID)
{
const float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half2 offset = SampleDist / ResultDimensions;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
const half4 sumL = 0.5h * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3( offset.x, offset.y, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3(-offset.x, offset.y, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3( offset.x, -offset.y, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3(-offset.x, -offset.y, 0), 0);
Result[half3(id.xy, 0)] = sumL;
uv.z = 1;
const half4 sumR = 0.5h * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3( offset.x, offset.y, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3(-offset.x, offset.y, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3( offset.x, -offset.y, 0), 0)
+ 0.125h * Source.SampleLevel(linearClampSampler, uv + half3(-offset.x, -offset.y, 0), 0);
Result[half3(id.xy, 1)] = sumR;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void SevenTapHexagonalVR(uint3 id : SV_DispatchThreadID)
{
const float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half sampleDistanceX = SampleDist / ResultDimensions.x * 0.57735024648h;
const half sampleDistanceY = SampleDist / ResultDimensions.y;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
const half4 sumL = 0.28h * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX * 2, halfTexelOffset.y, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX * 2, halfTexelOffset.y, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX, sampleDistanceY, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX, -sampleDistanceY, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX, sampleDistanceY, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX, -sampleDistanceY, 0), 0);
Result[half3(id.xy, 0)] = sumL;
uv.z = 1;
const half4 sumR = 0.28h * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX * 2, halfTexelOffset.y, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX * 2, halfTexelOffset.y, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX, sampleDistanceY, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX, -sampleDistanceY, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX, sampleDistanceY, 0), 0)
+ 0.12h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX, -sampleDistanceY, 0), 0);
Result[half3(id.xy, 1)] = sumR;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void EightTapCornersAndCrossVR(uint3 id : SV_DispatchThreadID)
{
const float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half2 sampleDist = SampleDist / ResultDimensions;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
const half4 sumL = 0.165h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, sampleDist.y, 0), 0)
+ 0.165h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, sampleDist.y, 0), 0)
+ 0.165h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, -sampleDist.y, 0), 0)
+ 0.165h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, -sampleDist.y, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, sampleDist.y * 2, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, -sampleDist.y * 2, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x * 2, halfTexelOffset.y, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x * 2, halfTexelOffset.y, 0), 0);
Result[half3(id.xy, 0)] = sumL;
uv.z = 1;
const half4 sumR = 0.165h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, sampleDist.y, 0), 0)
+ 0.165h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, sampleDist.y, 0), 0)
+ 0.165h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, -sampleDist.y, 0), 0)
+ 0.165h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, -sampleDist.y, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, sampleDist.y * 2, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, -sampleDist.y * 2, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x * 2, halfTexelOffset.y, 0), 0)
+ 0.085h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x * 2, halfTexelOffset.y, 0), 0);
Result[half3(id.xy, 1)] = sumR;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void NineTapOctagonalVR(uint3 id : SV_DispatchThreadID)
{
const float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half2 sampleDist = SampleDist / ResultDimensions;
const half2 sampleDist2 = sampleDist * 1.414427h;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
const half4 sumL = 0.2h * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist2.x, halfTexelOffset.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist2.x, halfTexelOffset.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, sampleDist2.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, -sampleDist2.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, sampleDist.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, sampleDist.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, -sampleDist.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, -sampleDist.y, 0), 0);
Result[half3(id.xy, 0)] = sumL;
uv.z = 1;
const half4 sumR = 0.2h * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist2.x, halfTexelOffset.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist2.x, halfTexelOffset.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, sampleDist2.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( halfTexelOffset.x, -sampleDist2.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, sampleDist.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, sampleDist.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3( sampleDist.x, -sampleDist.y, 0), 0)
+ 0.1h * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDist.x, -sampleDist.y, 0), 0);
Result[half3(id.xy, 1)] = sumR;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void QuadraticHorizontalVR(uint3 id : SV_DispatchThreadID)
{
float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half sampleDistanceX = SampleDist / ResultDimensions.x;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
half4 colorL = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
half totalWeight = 1.h;
for (uint slotL = 1; slotL <= TapsPerSideHor; slotL++)
{
const half t = 1 - slotL / (TapsPerSideHor + 1.);
const half weight = t * t;
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX * slotL, halfTexelOffset.y, 0), 0);
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX * slotL, halfTexelOffset.y, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 0)] = colorL / totalWeight;
uv.z = 1;
half4 ColorR = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
totalWeight = 1.h;
for (uint slotR = 1; slotR <= TapsPerSideHor; slotR++)
{
const half t = 1 - slotR / (TapsPerSideHor + 1.);
const half weight = t * t;
ColorR += weight * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX * slotR, halfTexelOffset.y, 0), 0);
ColorR += weight * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX * slotR, halfTexelOffset.y, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 1)] = ColorR / totalWeight;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void QuadraticVerticalVR(uint3 id : SV_DispatchThreadID)
{
float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half sampleDistanceY = SampleDist / ResultDimensions.y;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
half4 colorL = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
half totalWeight = 1.h;
for (uint slotL = 1; slotL <= TapsPerSideVert; slotL++)
{
const half t = 1 - slotL / (TapsPerSideVert + 1.);
const half weight = t * t;
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, sampleDistanceY * slotL, 0), 0);
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, -sampleDistanceY * slotL, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 0)] = colorL / totalWeight;
uv.z = 1;
half4 colorR = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
totalWeight = 1.h;
for (uint slotR = 1; slotR <= TapsPerSideVert; slotR++)
{
const half t = 1 - slotR / (TapsPerSideVert + 1.);
const half weight = t * t;
colorR += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, sampleDistanceY * slotR, 0), 0);
colorR += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, -sampleDistanceY * slotR, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 1)] = colorR / totalWeight;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void GaussianHorizontalVR(uint3 id : SV_DispatchThreadID)
{
float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half lowTapAdjust = 0.8h * max(0, 6 - TapsPerSideHor * 0.2h);
const half sigma = (lowTapAdjust + TapsPerSideHor) * 2 / 6.;
const half weightExpDivisor = -2 * sigma * sigma;
const half sampleDistanceX = SampleDist / ResultDimensions.x;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
half4 colorL = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
half totalWeight = 1.h;
for (uint slotL = 1; slotL <= TapsPerSideHor; slotL++)
{
const half weight = exp(slotL * slotL / weightExpDivisor);
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX * slotL, halfTexelOffset.y, 0), 0);
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX * slotL, halfTexelOffset.y, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 0)] = colorL / totalWeight;
uv.z = 1;
half4 colorR = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
totalWeight = 1.h;
for (uint slotR = 1; slotR <= TapsPerSideHor; slotR++)
{
const half weight = exp(slotR * slotR / weightExpDivisor);
colorR += weight * Source.SampleLevel(linearClampSampler, uv + half3( sampleDistanceX * slotR, halfTexelOffset.y, 0), 0);
colorR += weight * Source.SampleLevel(linearClampSampler, uv + half3(-sampleDistanceX * slotR, halfTexelOffset.y, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 1)] = colorR / totalWeight;
}
[numthreads(THREADGROUP_DIMENSION_X, THREADGROUP_DIMENSION_Y, 1)]
void GaussianVerticalVR(uint3 id : SV_DispatchThreadID)
{
float2 idf = id.xy + 0.5h;
half3 uv = half3(idf / ResultDimensions, 0);
const half lowTapAdjust = 0.8h * max(0, 6 - TapsPerSideVert * 0.2h);
const half sigma = (lowTapAdjust + TapsPerSideVert) * 2 / 6.;
const half weightExpDivisor = -2 * sigma * sigma;
const half sampleDistanceY = SampleDist / ResultDimensions.y;
const half2 texelSize = half2(1.h / ResultDimensions.x, 1.h / ResultDimensions.y);
const half2 halfTexelOffset = texelSize * SampleOffset;
half4 colorL = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
half totalWeight = 1.h;
for (uint slotL = 1; slotL <= TapsPerSideVert; slotL++)
{
const half weight = exp(slotL * slotL / weightExpDivisor);
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, sampleDistanceY * slotL, 0), 0);
colorL += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, -sampleDistanceY * slotL, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 0)] = colorL / totalWeight;
uv.z = 1;
half4 colorR = Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset * OffsetCenter, 0), 0);
totalWeight = 1.h;
for (uint slotR = 1; slotR <= TapsPerSideVert; slotR++)
{
const half weight = exp(slotR * slotR / weightExpDivisor);
colorR += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, sampleDistanceY * slotR, 0), 0);
colorR += weight * Source.SampleLevel(linearClampSampler, uv + half3(halfTexelOffset.x, -sampleDistanceY * slotR, 0), 0);
totalWeight += 2 * weight;
}
Result[half3(id.xy, 1)] = colorR / totalWeight;
}