Files
QuizzinMk5.1/Packages/red.sim.lightvolumes/Shaders/Editor/CountUnoccludedPixels.compute
2025-11-27 01:27:15 +00:00

54 lines
1.5 KiB
Plaintext

#pragma kernel CountUnoccludedPixels
#pragma kernel ComputeOcclusionRatio
#define COUNT_KERNEL_SIZE_X 8
#define COUNT_KERNEL_SIZE_Y 8
uint _TextureWidth;
uint _TextureHeight;
Texture2D _Texture;
uint _CountIndex;
RWStructuredBuffer<uint> _Count; // 2 elements per probe, one for before and one for after occlusion
groupshared uint _GroupSum[COUNT_KERNEL_SIZE_X * COUNT_KERNEL_SIZE_Y];
[numthreads(COUNT_KERNEL_SIZE_X, COUNT_KERNEL_SIZE_Y, 1)]
void CountUnoccludedPixels(uint3 tid : SV_DispatchThreadID, uint3 gid : SV_GroupThreadID) {
uint value = _Texture[tid.xy].r > 0.0;
_GroupSum[gid.y * COUNT_KERNEL_SIZE_X + gid.x] = value;
GroupMemoryBarrierWithGroupSync();
if (gid.x == 0 && gid.y == 0) {
uint sum = 0;
for (uint i = 0; i < COUNT_KERNEL_SIZE_X * COUNT_KERNEL_SIZE_Y; ++i)
{
sum += _GroupSum[i];
}
InterlockedAdd(_Count[_CountIndex], sum);
}
}
#define RATIO_KERNEL_SIZE 128
uint _OcclusionCount;
RWStructuredBuffer<float> _Occlusion;
[numthreads(RATIO_KERNEL_SIZE, 1, 1)]
void ComputeOcclusionRatio(uint3 tid : SV_DispatchThreadID) {
if (tid.x >= _OcclusionCount)
return;
uint after = _Count[tid.x * 2 + 1];
uint before = _Count[tid.x * 2 + 0];
// Don't divide by zero. This can happen if the probe is inside the light.
if (before == 0) {
_Occlusion[tid.x] = 0.0f;
return;
}
// Soft occlusion is the ratio of unoccluded pixels before and after occluders
_Occlusion[tid.x] = 1.0f - float(after) / float(before);
}