Files
UnrealEngine/Engine/Shaders/Private/HeterogeneousVolumes/HeterogeneousVolumesSparseVoxelUtils.ush
2025-05-18 13:04:45 +08:00

90 lines
2.3 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#define INVALID_VOXEL 0xFFFFFFFF;
struct FVoxelData
{
uint3 VoxelIndex;
uint MipLevel;
};
struct FVoxelDataPacked
{
uint LinearIndex;
uint MipLevel;
};
FVoxelDataPacked EncodeVoxelData(uint3 VoxelIndex, uint MipLevel, uint3 VolumeResolutionAtMipLevel)
{
FVoxelDataPacked VoxelDataPacked = (FVoxelDataPacked)0;
// TODO: Morton Order
VoxelDataPacked.LinearIndex =
VoxelIndex.z * VolumeResolutionAtMipLevel.x * VolumeResolutionAtMipLevel.y +
VoxelIndex.y * VolumeResolutionAtMipLevel.x +
VoxelIndex.x;
VoxelDataPacked.MipLevel = MipLevel;
return VoxelDataPacked;
}
FVoxelData DecodeVoxelData(FVoxelDataPacked VoxelDataPacked, uint3 VolumeResolutionAtMip0)
{
FVoxelData VoxelData;
VoxelData.MipLevel = VoxelDataPacked.MipLevel;
// TODO: Morton Order
uint3 VolumeRes = VolumeResolutionAtMip0 >> VoxelData.MipLevel;
VoxelData.VoxelIndex.x = (VoxelDataPacked.LinearIndex % (VolumeRes.x * VolumeRes.y)) % VolumeRes.x;
VoxelData.VoxelIndex.y = (VoxelDataPacked.LinearIndex % (VolumeRes.x * VolumeRes.y)) / VolumeRes.x;
VoxelData.VoxelIndex.z = VoxelDataPacked.LinearIndex / (VolumeRes.x * VolumeRes.y);
return VoxelData;
}
FVoxelData CreateEmptyVoxelData()
{
FVoxelData VoxelData;
VoxelData.VoxelIndex = 0;
VoxelData.MipLevel = INVALID_VOXEL;
return VoxelData;
}
bool IsVoxelDataValid(FVoxelData VoxelData)
{
return VoxelData.MipLevel != INVALID_VOXEL;
}
bool IsVoxelDataEqual(FVoxelData LHS, FVoxelData RHS)
{
return LHS.VoxelIndex.x == RHS.VoxelIndex.x &&
LHS.VoxelIndex.y == RHS.VoxelIndex.y &&
LHS.VoxelIndex.z == RHS.VoxelIndex.z &&
LHS.MipLevel == RHS.MipLevel;
}
struct FBox
{
float3 Min;
float3 Max;
};
FBox GetVoxelBoundingBox(FVoxelData VoxelData, int3 VolumeResolution, float3 ObjectBoundsMin, float3 ObjectBoundsMax)
{
float3 MipResolution = float3(
VolumeResolution.x >> VoxelData.MipLevel,
VolumeResolution.y >> VoxelData.MipLevel,
VolumeResolution.z >> VoxelData.MipLevel
);
float3 UVW0 = VoxelData.VoxelIndex / MipResolution;
float3 UVW1 = (VoxelData.VoxelIndex + 1) / MipResolution;
float3 ObjectBoundsExtent = ObjectBoundsMax - ObjectBoundsMin;
FBox Box;
const float Epsilon = 0.0001;
Box.Min = ObjectBoundsMin + ObjectBoundsExtent * UVW0 - Epsilon;
Box.Max = ObjectBoundsMin + ObjectBoundsExtent * UVW1 + Epsilon;
return Box;
}