Stabilize 3DGS D3D12 phase 3 and sort key setup
This commit is contained in:
@@ -53,6 +53,15 @@ struct RawGaussianSplat {
|
||||
Float4 rotation = {};
|
||||
};
|
||||
|
||||
struct GaussianPlyPropertyLayout {
|
||||
const PlyProperty* position[3] = {};
|
||||
const PlyProperty* dc0[3] = {};
|
||||
const PlyProperty* opacity = nullptr;
|
||||
const PlyProperty* scale[3] = {};
|
||||
const PlyProperty* rotation[4] = {};
|
||||
std::array<const PlyProperty*, GaussianSplatRuntimeData::kShCoefficientCount * 3> sh = {};
|
||||
};
|
||||
|
||||
std::string TrimTrailingCarriageReturn(std::string line) {
|
||||
if (!line.empty() && line.back() == '\r') {
|
||||
line.pop_back();
|
||||
@@ -243,6 +252,39 @@ bool RequireProperty(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildGaussianPlyPropertyLayout(
|
||||
const std::unordered_map<std::string_view, const PlyProperty*>& propertyMap,
|
||||
GaussianPlyPropertyLayout& outLayout,
|
||||
std::string& outErrorMessage) {
|
||||
outLayout = {};
|
||||
|
||||
if (!RequireProperty(propertyMap, "x", outLayout.position[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "y", outLayout.position[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "z", outLayout.position[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "f_dc_0", outLayout.dc0[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "f_dc_1", outLayout.dc0[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "f_dc_2", outLayout.dc0[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "opacity", outLayout.opacity, outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "scale_0", outLayout.scale[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "scale_1", outLayout.scale[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "scale_2", outLayout.scale[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_0", outLayout.rotation[0], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_1", outLayout.rotation[1], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_2", outLayout.rotation[2], outErrorMessage) ||
|
||||
!RequireProperty(propertyMap, "rot_3", outLayout.rotation[3], outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < outLayout.sh.size(); ++index) {
|
||||
const std::string propertyName = "f_rest_" + std::to_string(index);
|
||||
if (!RequireProperty(propertyMap, propertyName, outLayout.sh[index], outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Float3 Min(const Float3& a, const Float3& b) {
|
||||
return {
|
||||
std::min(a.x, b.x),
|
||||
@@ -390,32 +432,31 @@ void WriteFloat4(std::vector<std::byte>& bytes, size_t offset, float x, float y,
|
||||
|
||||
bool ReadGaussianSplat(
|
||||
const std::byte* vertexBytes,
|
||||
const std::unordered_map<std::string_view, const PlyProperty*>& propertyMap,
|
||||
const GaussianPlyPropertyLayout& propertyLayout,
|
||||
RawGaussianSplat& outSplat,
|
||||
std::string& outErrorMessage) {
|
||||
const PlyProperty* property = nullptr;
|
||||
|
||||
auto readFloat = [&](std::string_view name, float& outValue) -> bool {
|
||||
if (!RequireProperty(propertyMap, name, property, outErrorMessage)) {
|
||||
auto readFloat = [&](const PlyProperty* property, float& outValue) -> bool {
|
||||
if (property == nullptr) {
|
||||
outErrorMessage = "Gaussian PLY property layout is incomplete.";
|
||||
return false;
|
||||
}
|
||||
return ReadPropertyAsFloat(vertexBytes, *property, outValue);
|
||||
};
|
||||
|
||||
if (!readFloat("x", outSplat.position.x) ||
|
||||
!readFloat("y", outSplat.position.y) ||
|
||||
!readFloat("z", outSplat.position.z) ||
|
||||
!readFloat("f_dc_0", outSplat.dc0.x) ||
|
||||
!readFloat("f_dc_1", outSplat.dc0.y) ||
|
||||
!readFloat("f_dc_2", outSplat.dc0.z) ||
|
||||
!readFloat("opacity", outSplat.opacity) ||
|
||||
!readFloat("scale_0", outSplat.scale.x) ||
|
||||
!readFloat("scale_1", outSplat.scale.y) ||
|
||||
!readFloat("scale_2", outSplat.scale.z) ||
|
||||
!readFloat("rot_0", outSplat.rotation.x) ||
|
||||
!readFloat("rot_1", outSplat.rotation.y) ||
|
||||
!readFloat("rot_2", outSplat.rotation.z) ||
|
||||
!readFloat("rot_3", outSplat.rotation.w)) {
|
||||
if (!readFloat(propertyLayout.position[0], outSplat.position.x) ||
|
||||
!readFloat(propertyLayout.position[1], outSplat.position.y) ||
|
||||
!readFloat(propertyLayout.position[2], outSplat.position.z) ||
|
||||
!readFloat(propertyLayout.dc0[0], outSplat.dc0.x) ||
|
||||
!readFloat(propertyLayout.dc0[1], outSplat.dc0.y) ||
|
||||
!readFloat(propertyLayout.dc0[2], outSplat.dc0.z) ||
|
||||
!readFloat(propertyLayout.opacity, outSplat.opacity) ||
|
||||
!readFloat(propertyLayout.scale[0], outSplat.scale.x) ||
|
||||
!readFloat(propertyLayout.scale[1], outSplat.scale.y) ||
|
||||
!readFloat(propertyLayout.scale[2], outSplat.scale.z) ||
|
||||
!readFloat(propertyLayout.rotation[0], outSplat.rotation.x) ||
|
||||
!readFloat(propertyLayout.rotation[1], outSplat.rotation.y) ||
|
||||
!readFloat(propertyLayout.rotation[2], outSplat.rotation.z) ||
|
||||
!readFloat(propertyLayout.rotation[3], outSplat.rotation.w)) {
|
||||
if (outErrorMessage.empty()) {
|
||||
outErrorMessage = "Failed to read required Gaussian splat PLY properties.";
|
||||
}
|
||||
@@ -424,8 +465,7 @@ bool ReadGaussianSplat(
|
||||
|
||||
std::array<float, GaussianSplatRuntimeData::kShCoefficientCount * 3> shRaw = {};
|
||||
for (uint32_t index = 0; index < shRaw.size(); ++index) {
|
||||
const std::string propertyName = "f_rest_" + std::to_string(index);
|
||||
if (!readFloat(propertyName, shRaw[index])) {
|
||||
if (!readFloat(propertyLayout.sh[index], shRaw[index])) {
|
||||
if (outErrorMessage.empty()) {
|
||||
outErrorMessage = "Failed to read SH rest coefficients from PLY.";
|
||||
}
|
||||
@@ -478,6 +518,11 @@ bool LoadGaussianSceneFromPly(
|
||||
return false;
|
||||
}
|
||||
|
||||
GaussianPlyPropertyLayout propertyLayout;
|
||||
if (!BuildGaussianPlyPropertyLayout(propertyMap, propertyLayout, outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outData.splatCount = header.vertexCount;
|
||||
outData.colorTextureWidth = GaussianSplatRuntimeData::kColorTextureWidth;
|
||||
outData.colorTextureHeight =
|
||||
@@ -513,7 +558,7 @@ bool LoadGaussianSceneFromPly(
|
||||
}
|
||||
|
||||
RawGaussianSplat splat;
|
||||
if (!ReadGaussianSplat(vertexBytes.data(), propertyMap, splat, outErrorMessage)) {
|
||||
if (!ReadGaussianSplat(vertexBytes.data(), propertyLayout, splat, outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user