Files
UnrealEngine/Engine/Shaders/Private/Bloom/BloomFindKernelCenter.usf
2025-05-18 13:04:45 +08:00

136 lines
2.6 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "BloomCommon.ush"
//------------------------------------------------------- CONSTANTS
#define TILE_SIZE 8
//------------------------------------------------------- PARAMETERS
/*
uint
uint
float
uint
* */
uint2 KernelSpatialTextureSize;
Texture2D KernelSpatialTexture;
RWCoherentStructuredBuffer(uint) KernelCenterCoordOutput;
//------------------------------------------------------- LDS
groupshared uint MaxLuminance;
groupshared uint2 MaxLuminancePixelPos;
groupshared uint CurrentMaxLuminance;
groupshared uint bDone;
groupshared uint PrevLock;
//------------------------------------------------------- ENTRY POINT
[numthreads(TILE_SIZE, TILE_SIZE, 1)]
void MainCS(
uint2 GroupId : SV_GroupID,
uint GroupThreadIndex : SV_GroupIndex)
{
// Init LDS
if (GroupThreadIndex == 0)
{
MaxLuminance = 0;
bDone = 0;
}
GroupMemoryBarrierWithGroupSync();
uint2 InputPixelPos = TILE_SIZE * GroupId + uint2(GroupThreadIndex % TILE_SIZE, GroupThreadIndex / TILE_SIZE);
float4 TexelColor = KernelSpatialTexture[InputPixelPos];
bool bValidPixel = all(InputPixelPos < KernelSpatialTextureSize);
if (!bValidPixel)
{
TexelColor = 0.0;
}
// Locate the position of the brightest pixel
{
float TexelLuminance = Luminance(TexelColor.rgb);
InterlockedMax(MaxLuminance, asuint(TexelLuminance));
GroupMemoryBarrierWithGroupSync();
if (MaxLuminance == asuint(TexelLuminance))
{
MaxLuminancePixelPos = InputPixelPos;
}
}
GroupMemoryBarrierWithGroupSync();
if (MaxLuminance == 0)
{
return;
}
while (bDone == 0)
{
if (GroupThreadIndex == 0)
{
CurrentMaxLuminance = KernelCenterCoordOutput[2];
}
GroupMemoryBarrierWithGroupSync();
if (MaxLuminance > CurrentMaxLuminance)
{
if (GroupThreadIndex == 0)
{
uint LocalPrevLock;
InterlockedCompareExchange(
KernelCenterCoordOutput[3],
uint(0),
uint(1),
/* out */ LocalPrevLock);
PrevLock = LocalPrevLock;
}
GroupMemoryBarrierWithGroupSync();
if (PrevLock == 0)
{
AllMemoryBarrier();
if (GroupThreadIndex == 0 && MaxLuminance > KernelCenterCoordOutput[2])
{
KernelCenterCoordOutput[0] = MaxLuminancePixelPos.x;
KernelCenterCoordOutput[1] = MaxLuminancePixelPos.y;
KernelCenterCoordOutput[2] = MaxLuminance;
}
AllMemoryBarrier();
if (GroupThreadIndex == 0)
{
uint Unused;
InterlockedExchange(KernelCenterCoordOutput[3], 0, Unused);
}
bDone += 1;
}
}
else
{
bDone += 1;
}
GroupMemoryBarrierWithGroupSync();
}
}