Files
2026-07-13 13:13:17 +08:00

130 lines
3.7 KiB
HLSL

#include "shared/point.hlsl"
#include "shared/quat-functions.hlsl"
cbuffer Params : register(b0)
{
float DebugParam;
}
cbuffer Params : register(b1)
{
int SourceCount;
int ResultCount;
}
struct MinMax
{
uint3 Min;
uint3 Max;
};
StructuredBuffer<LegacyPoint> SourcePoints : register(t0);
RWStructuredBuffer<LegacyPoint> ResultPoints : register(u0);
RWStructuredBuffer<MinMax> Bounds : register(u1);
groupshared uint3 g_MinValue = 0xffffffffu;
groupshared uint3 g_MaxValue = 0;
inline uint FloatToOInt(float value)
{
// For negative values, the mask becomes 0xffffffff.
// For positive values, the mask becomes 0x80000000.
uint uvalue = asuint(value);
uint mask = -int(uvalue >> 31) | 0x80000000;
return uvalue ^ mask;
}
inline float OIntToFloat(uint value)
{
// If the msb is set, the mask becomes 0x80000000.
// If the msb is unset, the mask becomes 0xffffffff.
uint mask = ((value >> 31) - 1) | 0x80000000;
return asfloat(value ^ mask);
}
[numthreads(1, 1, 1)] void clear2(uint3 DTid : SV_DispatchThreadID)
{
Bounds[0].Min = 0xffffffffu;
Bounds[0].Max = 0;
}
[numthreads(512, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID, uint Gi : SV_GroupIndex)
{
uint stride, sourcePointCount;
SourcePoints.GetDimensions(sourcePointCount, stride);
LegacyPoint sourcePoint = SourcePoints[DTid.x];
float3 position = sourcePoint.Position;
// float isValid = !(DTid.x >= sourcePointCount || isnan(position.x) || isnan(position.y) || isnan(position.z));
float isValid = !(isnan(position.x) || isnan(position.y) || isnan(position.z));
uint3 intPos = uint3(
FloatToOInt(position.x),
FloatToOInt(position.y),
FloatToOInt(position.z));
// This using thread group shared memory to fist compute the group
// bounds. This might be slightly faster but the current implementation
// is glitchy.
// if (isValid)
// {
// InterlockedMin(g_MinValue.x, intPos.x);
// InterlockedMin(g_MinValue.y, intPos.y);
// InterlockedMin(g_MinValue.z, intPos.z);
// InterlockedMax(g_MaxValue.x, intPos.x);
// InterlockedMax(g_MaxValue.y, intPos.y);
// InterlockedMax(g_MaxValue.z, intPos.z);
// }
// //--------------------------------------------
// GroupMemoryBarrierWithGroupSync();
// if (Gi.x == 0)
// {
// InterlockedMin(Bounds[0].Min.x, g_MinValue.x);
// InterlockedMin(Bounds[0].Min.y, g_MinValue.y);
// InterlockedMin(Bounds[0].Min.z, g_MinValue.z);
// InterlockedMax(Bounds[0].Max.x, g_MaxValue.x);
// InterlockedMax(Bounds[0].Max.y, g_MaxValue.y);
// InterlockedMax(Bounds[0].Max.z, g_MaxValue.z);
// }
if (isValid)
{
InterlockedMin(Bounds[0].Min.x, intPos.x);
InterlockedMin(Bounds[0].Min.y, intPos.y);
InterlockedMin(Bounds[0].Min.z, intPos.z);
InterlockedMax(Bounds[0].Max.x, intPos.x);
InterlockedMax(Bounds[0].Max.y, intPos.y);
InterlockedMax(Bounds[0].Max.z, intPos.z);
}
AllMemoryBarrierWithGroupSync();
float3 minPos = float3(
OIntToFloat(Bounds[0].Min.x),
OIntToFloat(Bounds[0].Min.y),
OIntToFloat(Bounds[0].Min.z));
float3 maxPos = float3(
OIntToFloat(Bounds[0].Max.x),
OIntToFloat(Bounds[0].Max.y),
OIntToFloat(Bounds[0].Max.z));
float3 centerPos = (minPos + maxPos) * 0.5;
if (Gi.x == 0)
{
ResultPoints[0].Position = centerPos;
ResultPoints[0].Stretch = maxPos - minPos;
ResultPoints[0].Selected = 1;
ResultPoints[0].Color = 1;
ResultPoints[0].W = 1;
ResultPoints[0].Rotation = float4(0, 0, 0, 1);
}
}