Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/MotionBlurMergeTilePass.compute
2024-08-26 23:07:20 +03:00

49 lines
1.8 KiB
Plaintext

#pragma kernel TileMerge MERGE_PASS SCATTERING
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/MotionBlurTileCommon.hlsl"
TEXTURE2D_X_UINT(_TileToScatterMax);
TEXTURE2D_X(_TileToScatterMin);
RW_TEXTURE2D_X(float3, _TileMaxNeighbourhood);
[numthreads(8, 8, 1)]
void TileMerge(uint3 dispatchID : SV_DispatchThreadID)
{
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchID.z);
int2 id = dispatchID.xy;
// If we scattered wider than a 3 tile radius, then we do an additional neighbourhood search.
float2 maxVelData = UnpackMotionVec(_TileToScatterMax[COORD_TEXTURE2D_X(id)]);
float maxVelLen = MotionVecLengthInPixelsFromEncoded(maxVelData);
// TODO: In theory this could have to be even wider. In general, we need a better way to determine min velocities.
float minVel = 0.0f;
int2 maxCoords = int2(_TileTargetSize.xy - 1);
if (maxVelLen > TILE_SIZE*0.5f)
{
int tileCount = maxVelLen / TILE_SIZE;
if (tileCount > 4) tileCount = 4;
minVel = 999999.0f;
// This is sub-optimal, but the texture is tiny and should be fairly cache efficient.
for (int x = -tileCount; x < tileCount; ++x)
{
for (int y = -tileCount; y < tileCount; ++y)
{
int2 tapCoord = clamp(id + int2(x, y), 0, _TileTargetSize.xy - 1);
float data = _TileToScatterMin[COORD_TEXTURE2D_X(tapCoord)].x;
minVel = min(minVel, data);
}
}
}
else
{
minVel = _TileToScatterMin[COORD_TEXTURE2D_X(id)].x;
}
_TileMaxNeighbourhood[COORD_TEXTURE2D_X(id)] = float3(UnpackMotionVec(_TileToScatterMax[COORD_TEXTURE2D_X(id)]), (minVel));
}