Cull invisible gaussian splat chunks in prepare pass
This commit is contained in:
@@ -50,6 +50,53 @@ constexpr uint32_t kFrameWidth = 1280;
|
||||
constexpr uint32_t kFrameHeight = 720;
|
||||
constexpr uint32_t kBaselineSubsetSplatCount = 65536u;
|
||||
|
||||
XCEngine::Core::uint16 FloatToHalfBits(float value) {
|
||||
uint32_t bits = 0u;
|
||||
std::memcpy(&bits, &value, sizeof(bits));
|
||||
|
||||
const uint32_t sign = (bits >> 16u) & 0x8000u;
|
||||
uint32_t mantissa = bits & 0x007fffffu;
|
||||
int32_t exponent = static_cast<int32_t>((bits >> 23u) & 0xffu) - 127 + 15;
|
||||
|
||||
if (exponent <= 0) {
|
||||
if (exponent < -10) {
|
||||
return static_cast<XCEngine::Core::uint16>(sign);
|
||||
}
|
||||
|
||||
mantissa = (mantissa | 0x00800000u) >> static_cast<uint32_t>(1 - exponent);
|
||||
if ((mantissa & 0x00001000u) != 0u) {
|
||||
mantissa += 0x00002000u;
|
||||
}
|
||||
|
||||
return static_cast<XCEngine::Core::uint16>(sign | (mantissa >> 13u));
|
||||
}
|
||||
|
||||
if (exponent >= 31) {
|
||||
return static_cast<XCEngine::Core::uint16>(sign | 0x7c00u);
|
||||
}
|
||||
|
||||
if ((mantissa & 0x00001000u) != 0u) {
|
||||
mantissa += 0x00002000u;
|
||||
if ((mantissa & 0x00800000u) != 0u) {
|
||||
mantissa = 0u;
|
||||
++exponent;
|
||||
if (exponent >= 31) {
|
||||
return static_cast<XCEngine::Core::uint16>(sign | 0x7c00u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<XCEngine::Core::uint16>(
|
||||
sign |
|
||||
(static_cast<uint32_t>(exponent) << 10u) |
|
||||
(mantissa >> 13u));
|
||||
}
|
||||
|
||||
uint32_t PackHalfRange(float minValue, float maxValue) {
|
||||
return static_cast<uint32_t>(FloatToHalfBits(minValue)) |
|
||||
(static_cast<uint32_t>(FloatToHalfBits(maxValue)) << 16u);
|
||||
}
|
||||
|
||||
std::filesystem::path GetRoomPlyPath() {
|
||||
return std::filesystem::path(XCENGINE_TEST_ROOM_PLY_PATH);
|
||||
}
|
||||
@@ -153,21 +200,39 @@ GaussianSplat* CreateGaussianSplatSubset(
|
||||
-std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max());
|
||||
Vector3 minScale(
|
||||
std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max());
|
||||
Vector3 maxScale(
|
||||
-std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max());
|
||||
|
||||
for (uint32_t subsetIndex = startIndex; subsetIndex < endIndex; ++subsetIndex) {
|
||||
const Vector3& position = subsetPositions[subsetIndex].position;
|
||||
const Vector3& scale = subsetOther[subsetIndex].scale;
|
||||
minPosition.x = std::min(minPosition.x, position.x);
|
||||
minPosition.y = std::min(minPosition.y, position.y);
|
||||
minPosition.z = std::min(minPosition.z, position.z);
|
||||
maxPosition.x = std::max(maxPosition.x, position.x);
|
||||
maxPosition.y = std::max(maxPosition.y, position.y);
|
||||
maxPosition.z = std::max(maxPosition.z, position.z);
|
||||
minScale.x = std::min(minScale.x, scale.x);
|
||||
minScale.y = std::min(minScale.y, scale.y);
|
||||
minScale.z = std::min(minScale.z, scale.z);
|
||||
maxScale.x = std::max(maxScale.x, scale.x);
|
||||
maxScale.y = std::max(maxScale.y, scale.y);
|
||||
maxScale.z = std::max(maxScale.z, scale.z);
|
||||
}
|
||||
|
||||
GaussianSplatChunkRecord chunk = {};
|
||||
chunk.posX = Vector2(minPosition.x, maxPosition.x);
|
||||
chunk.posY = Vector2(minPosition.y, maxPosition.y);
|
||||
chunk.posZ = Vector2(minPosition.z, maxPosition.z);
|
||||
chunk.sclX = PackHalfRange(minScale.x, maxScale.x);
|
||||
chunk.sclY = PackHalfRange(minScale.y, maxScale.y);
|
||||
chunk.sclZ = PackHalfRange(minScale.z, maxScale.z);
|
||||
subsetChunks[chunkIndex] = chunk;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user