407 lines
21 KiB
Plaintext
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;
|
|
} |