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.
103 lines
4.1 KiB
103 lines
4.1 KiB
#pragma kernel RayBinning RAY_BINNING=RayBinning
|
|
#pragma kernel RayBinningHalf RAY_BINNING=RayBinningHalf HALF_RESOLUTION
|
|
|
|
#pragma only_renderers d3d11 xboxseries ps5
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl"
|
|
|
|
#define RAY_BINNING_TILE_SIZE 16
|
|
#define BINNING_TILE_SIZE 16
|
|
|
|
TEXTURE2D_X(_RaytracingDirectionBuffer);
|
|
RWStructuredBuffer<uint> _RayBinResult;
|
|
RWStructuredBuffer<uint> _RayBinSizeResult;
|
|
uint _RayBinTileCountX;
|
|
uint _RayBinViewOffset;
|
|
uint _RayBinTileViewOffset;
|
|
|
|
groupshared uint gs_binSize[BINNING_TILE_SIZE * BINNING_TILE_SIZE + 1];
|
|
groupshared uint gs_binOffset[BINNING_TILE_SIZE * BINNING_TILE_SIZE];
|
|
|
|
[numthreads(RAY_BINNING_TILE_SIZE, RAY_BINNING_TILE_SIZE, 1)]
|
|
void RAY_BINNING(uint2 groupThreadId : SV_GroupThreadID, uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)
|
|
{
|
|
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
|
|
|
|
// Compute the pixel position to process
|
|
uint2 currentCoord = groupId * RAY_BINNING_TILE_SIZE + groupThreadId.xy;
|
|
|
|
#if HALF_RESOLUTION
|
|
currentCoord = ComputeSourceCoordinates(currentCoord, _RayTracingCheckerIndex);
|
|
#endif
|
|
|
|
// Initialize the invalid counter to 0
|
|
if(groupThreadId.x == 0 && groupThreadId.y == 0)
|
|
{
|
|
gs_binSize[256] = 0;
|
|
}
|
|
|
|
// Every tile initializes a counter to 0
|
|
gs_binSize[groupThreadId.y * RAY_BINNING_TILE_SIZE + groupThreadId.x] = 0;
|
|
|
|
// Sync all threads
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
// is this sample valid
|
|
uint binIndex = 256;
|
|
|
|
// Is this sample valid ? otherwise its bin index is 256
|
|
if (LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, currentCoord).w > 0.0 && (float)currentCoord.x < _ScreenSize.x && (float)currentCoord.y < _ScreenSize.y)
|
|
{
|
|
// Fetch the current direction
|
|
const float3 currentDirection = LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, currentCoord).xyz;
|
|
|
|
// Generate its bin index
|
|
float2 octahedralDirection = PackNormalOctQuadEncode(currentDirection);
|
|
uint2 binCoordinates = (uint2)((octahedralDirection * 0.5 + 0.5) * BINNING_TILE_SIZE);
|
|
binIndex = binCoordinates.y * BINNING_TILE_SIZE + binCoordinates.x;
|
|
}
|
|
|
|
// Increment the bin size of the bin where this sample goes
|
|
int rayBinIndex = 0;
|
|
UNITY_BRANCH if (binIndex != 256)
|
|
{
|
|
InterlockedAdd(gs_binSize[binIndex], 1, rayBinIndex);
|
|
}
|
|
|
|
// Sync all threads
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
if(groupThreadId.x == 0 && groupThreadId.y == 0)
|
|
{
|
|
// Build the offset list of the bins
|
|
gs_binOffset[0] = 0;
|
|
for(int i = 1; i < 256; ++i)
|
|
{
|
|
gs_binOffset[i] = gs_binOffset[i - 1] + gs_binSize[i - 1];
|
|
}
|
|
}
|
|
|
|
// Sync all threads
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
// We only want to store it if it's bin is valid
|
|
if(binIndex < 256)
|
|
{
|
|
// Output the indices of the original pixels
|
|
uint groupdIndex = groupId.y * _RayBinTileCountX + groupId.x;
|
|
uint globalOffset = groupdIndex * RAY_BINNING_TILE_SIZE * RAY_BINNING_TILE_SIZE + gs_binOffset[binIndex] + rayBinIndex + _RayBinViewOffset * dispatchThreadId.z;
|
|
_RayBinResult[globalOffset] = ((currentCoord.x & 0xffff) << 16) + (currentCoord.y & 0xffff);
|
|
}
|
|
|
|
// Then output the size of every bin
|
|
if(groupThreadId.x == 0 && groupThreadId.y == 0)
|
|
{
|
|
uint groupdIndex = groupId.y * _RayBinTileCountX + groupId.x + _RayBinTileViewOffset * dispatchThreadId.z;
|
|
_RayBinSizeResult[groupdIndex] = gs_binOffset[255] + gs_binSize[255];
|
|
}
|
|
}
|