diff --git a/Assets/vfx-graph-gs/Scripts/SplatImporter.cs b/Assets/vfx-graph-gs/Scripts/SplatImporter.cs index 456aff2..6121932 100644 --- a/Assets/vfx-graph-gs/Scripts/SplatImporter.cs +++ b/Assets/vfx-graph-gs/Scripts/SplatImporter.cs @@ -70,9 +70,6 @@ namespace SplatVfx.Editor opacity, scale_0, scale_1, scale_2, rot_0, rot_1, rot_2, rot_3 } - /*********************************************************************** - - TODO: Add support for more data types - ***********************************************************************/ private static readonly Dictionary TypeToByteLengths = new() { @@ -92,10 +89,6 @@ namespace SplatVfx.Editor { "int8", TypeEnum.Int8 } }; - /*********************************************************************** - - TODO: Add endianness - - TODO: Add float size - ***********************************************************************/ private struct HeaderData { public uint NumElements; @@ -234,14 +227,14 @@ namespace SplatVfx.Editor ); int chunkSize = elementsPerChunk * headerData.BytesPerElement; - Debug.Log($"Elements per chunk: {elementsPerChunk}"); - Debug.Log($"Chunk size: {chunkSize}"); + // Debug.Log($"Elements per chunk: {elementsPerChunk}"); + // Debug.Log($"Chunk size: {chunkSize}"); using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); fileStream.Seek(endHeaderPosition, SeekOrigin.Begin); int totalBytes = (int)fileStream.Length - endHeaderPosition; - Debug.Log($"Total bytes: {totalBytes}"); + // Debug.Log($"Total bytes: {totalBytes}"); var splatDataNative = new SplatDataNative(elementsPerChunk); var chunkBuffer = new NativeArray(chunkSize, Allocator.Persistent); @@ -280,10 +273,10 @@ namespace SplatVfx.Editor } totalElemsRead += numElemsRead; - Debug.Log($"Current Elements Read: {totalElemsRead}"); + // Debug.Log($"Current Elements Read: {totalElemsRead}"); } - Debug.Log($"First position Vector3: {splatData.PositionArray[0]}"); + // Debug.Log($"First position Vector3: {splatData.PositionArray[0]}"); headerData.Dispose(); splatDataNative.Dispose(); @@ -354,55 +347,5 @@ namespace SplatVfx.Editor } } } - - // struct ReadData - // { - // public float px, py, pz; - // public float sx, sy, sz; - // public byte r, g, b, a; - // public byte rw, rx, ry, rz; - // } - - // (Vector3[] position, Vector3[] axis, Color[] color) - // LoadDataArrays(string path) - // { - // var bytes = (Span)File.ReadAllBytes(path); - // var count = bytes.Length / 32; - - // var source = MemoryMarshal.Cast(bytes); - - // var position = new Vector3[count]; - // var axis = new Vector3[count * 3]; - // var color = new Color[count]; - - // for (var i = 0; i < count; i++) - // ParseReadData(source[i], - // out position[i], - // out axis[i * 3], - // out axis[i * 3 + 1], - // out axis[i * 3 + 2], - // out color[i]); - - // return (position, axis, color); - // } - - // [BurstCompile] - // void ParseReadData(in ReadData src, - // out Vector3 position, - // out Vector3 axis1, - // out Vector3 axis2, - // out Vector3 axis3, - // out Color color) - // { - // var rv = (math.float4(src.rx, src.ry, src.rz, src.rw) - 128) / 128; - // var q = math.quaternion(-rv.x, -rv.y, rv.z, rv.w); - // position = math.float3(src.px, src.py, -src.pz); - // axis1 = math.mul(q, math.float3(src.sx, 0, 0)); - // axis2 = math.mul(q, math.float3(0, src.sy, 0)); - // axis3 = math.mul(q, math.float3(0, 0, src.sz)); - // color = (Vector4)math.float4(src.r, src.g, src.b, src.a) / 255; - // } - } - } diff --git a/Assets/vfx-graph-gs/VFXGraphHLSL/CalculateSH.hlsl b/Assets/vfx-graph-gs/VFXGraphHLSL/CalculateSH.hlsl index d7d5e46..aca2924 100644 --- a/Assets/vfx-graph-gs/VFXGraphHLSL/CalculateSH.hlsl +++ b/Assets/vfx-graph-gs/VFXGraphHLSL/CalculateSH.hlsl @@ -1,3 +1,7 @@ +/// Index: The splat's index +/// Degrees: The degrees of spherical harmonics to calculate +/// DirClr: A 4x4 matrix with the first row containing a vector from the splat position to the camera, and the second row containing its base color +/// SHBuffer: The spherical harmonics buffer from a SplatData object float3 CalculateSHColor(uint Index, uint Degrees, float4x4 DirClr, StructuredBuffer SHBuffer) { const float SH_C0 = 0.28209479177387814f; const float SH_C1 = 0.4886025119029199f; @@ -31,10 +35,9 @@ float3 CalculateSHColor(uint Index, uint Degrees, float4x4 DirClr, StructuredBuf // } for (int i = 1; i < 16; i++) { - // Access R, G, B values from their separate blocks - sh[i].x = SHBuffer[Index * 45 + (i - 1)]; // R values (indices 0-44) - sh[i].y = SHBuffer[Index * 45 + 15 + (i - 1)]; // G values (indices 45-89) - sh[i].z = SHBuffer[Index * 45 + 30 + (i - 1)]; // B values (indices 90-134) + sh[i].x = SHBuffer[Index * 45 + (i - 1)]; + sh[i].y = SHBuffer[Index * 45 + 15 + (i - 1)]; + sh[i].z = SHBuffer[Index * 45 + 30 + (i - 1)]; } if (Degrees > 0) @@ -73,6 +76,8 @@ float3 CalculateSHColor(uint Index, uint Degrees, float4x4 DirClr, StructuredBuf } /* +> Reference taken from the original Gaussian splatting paper code + // The implementation is loosely based on code for // "Differentiable Point-Based Radiance Fields for // Efficient View Synthesis" by Zhang et al. (2022) diff --git a/Assets/vfx-graph-gs/VFXGraphHLSL/GetMajorAxes.hlsl b/Assets/vfx-graph-gs/VFXGraphHLSL/GetMajorAxes.hlsl index b274905..9125da6 100644 --- a/Assets/vfx-graph-gs/VFXGraphHLSL/GetMajorAxes.hlsl +++ b/Assets/vfx-graph-gs/VFXGraphHLSL/GetMajorAxes.hlsl @@ -1,8 +1,10 @@ +/// Hidden float CrossProduct(float2 A, float2 B) { return A.x * B.y - A.y * B.x; } +/// Hidden float SweepArea(float2 A, float2 B) { return abs(CrossProduct(A, B)); diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..fcfccd4 --- /dev/null +++ b/TODO.md @@ -0,0 +1,12 @@ +# TODO + +- [ ] Rewrite SH Array to use interleaved RGB rather than contiguous data per + channel +- [ ] Switch to using ByteAddressBuffers instead of loops in CalculateSH.hlsl +- [ ] Optimize CalculateAxes.hlsl +- [ ] Allow splat data buffers to be accessible by other VFX Graphs +- [ ] Add exception reporting and handling for incomplete splat data +- [ ] Add support for other PLY data types and endianness +- [ ] Add support for ASCII PLY data +- [ ] Fix the header parsing logic in SplatImporter.cs +- [ ] Add more thorough checks in SplatDataBinder.cs