What Is a .KSPLAT File? The Three.js-Optimized Gaussian Splatting Format
The streaming-optimized format for Three.js GaussianSplats3D, with progressive loading and optional spherical harmonics.
Updated Mar 2026
What Is a .KSPLAT File?

KSPLAT is a 3D Gaussian Splatting format designed by Mark Kellogg (mkkellogg) for his open-source GaussianSplats3D library — the most widely adopted Three.js implementation for rendering Gaussian Splatting scenes. The library has accumulated over 4,200 GitHub stars since its 2023 release, and KSPLAT is its native file format.
KSPLAT's core differentiating feature is progressive streaming: the file is organized into depth-sorted "chunks," with each chunk decoded and rendered immediately upon arrival. Users see a recognizable scene within 0.5–1 seconds, even for files exceeding 100 MB — a critical UX advantage that no other 3DGS format offers as of early 2026.
An important technical distinction from SPLAT: KSPLAT supports optional spherical harmonics (SH) at up to degree 2, while SPLAT never supports SH. Whether a KSPLAT file contains SH depends on the settings used when creating it — the default is no SH, which is why most KSPLAT files in the wild behave similarly to SPLAT in terms of visual quality. Enabling SH during creation produces noticeably better view-dependent lighting effects at the cost of larger file size.
KSPLAT's limitation is ecosystem portability — the format is specific to the GaussianSplats3D ecosystem, and other tools do not natively support it. For cross-platform needs, SPLAT (broadest compatibility) and SPZ (best compression with full SH) are more portable choices. However, within the Three.js ecosystem, KSPLAT remains the optimal format for production deployment.
Technical Specifications: KSPLAT File Format Internals
KSPLAT has two independent parameters that control its output: a compression level (0 = no compression/full float32 precision, 1 = half-float 16-bit precision, 2 = 8-bit integer/maximum compression) and a spherical harmonics level (0 = no SH, 1 = degree 1 with 9 coefficients, 2 = degree 2 with 24 coefficients). These two parameters are orthogonal — you can have high compression with full SH, or no compression with no SH.
The KSPLAT binary format begins with a file header containing: a 4-byte magic identifier, a 2-byte version number (current version is 0), a 2-byte section count, and a 4-byte total section data size. Following the header, each section has its own sub-header specifying the data type (splat data, SH data, or section header), compression level, SH level, and the number of Gaussians in that section.
At compression level 0 (no compression), each Gaussian stores: position as 3×float32 (12 bytes), covariance as 6×float32 (24 bytes), color as 4×float32 (16 bytes), and optional SH coefficients. Total per Gaussian: ~52 bytes without SH, ~148 bytes with degree-2 SH. At compression level 1 (half-float), position remains float32 but covariance, color, and SH are stored as float16, reducing per-Gaussian size to ~32 bytes without SH, ~80 bytes with degree-2 SH. At compression level 2 (8-bit), all non-position data is quantized to uint8, yielding ~20 bytes without SH, ~44 bytes with degree-2 SH.
KSPLAT organizes Gaussians into depth-sorted chunks. Each chunk contains a configurable number of Gaussians (default: 256). Within each chunk, Gaussians are pre-sorted by depth relative to a reference viewpoint, which reduces runtime sorting overhead by approximately 30–40% compared to unsorted formats. The chunk boundaries are stored in the section header, enabling precise HTTP range request loading — a client can request exactly the bytes for chunks 0–10 without downloading the rest of the file.
Compared to SPLAT internally: KSPLAT at compression level 2 without SH uses approximately 20 bytes per Gaussian versus SPLAT's fixed 32 bytes — KSPLAT is actually smaller in this configuration. However, KSPLAT's chunk headers and section metadata add approximately 2–3% overhead, so real-world file sizes are comparable. The key difference is structural: KSPLAT's chunked organization enables progressive loading and random access, while SPLAT's flat sequential layout does not.
Progressive Loading — KSPLAT's Key Advantage
Progressive loading is KSPLAT's most important feature and the primary reason developers choose it over SPLAT or SPZ. The loading sequence works as follows: (1) The browser issues an HTTP range request for the file header and first N chunks. (2) GaussianSplats3D decodes the first chunk and establishes an initial Gaussian set (typically 5–10% of the full scene). (3) The renderer immediately displays a low-density but recognizable scene — users see the overall structure within 0.5–1 seconds on a typical broadband connection. (4) Remaining chunks continue loading in the background, with each chunk adding more Gaussians and increasing visual density. (5) Once all chunks are loaded, full quality is achieved.
The perceptual impact is significant. In user testing with scenes containing 1–2 million Gaussians (typical for room-scale captures), KSPLAT's progressive loading reduces perceived wait time by 60–80% compared to SPLAT or SPZ, even though total download time is similar. Users report the experience as "instant" because they see meaningful content immediately, rather than staring at a loading spinner.
Compare this with SPLAT and SPZ: SPLAT must be fully downloaded before any rendering can begin (its flat layout means partial data is not useful). SPZ's column-based gzip storage is even worse for streaming — the gzip container must be fully decompressed before individual Gaussians can be extracted. Only KSPLAT's chunk-based architecture supports true progressive rendering.
For developers implementing progressive loading, GaussianSplats3D exposes configuration options including: dynamicScene (enables re-sorting as new chunks arrive), chunkSize (number of Gaussians per chunk, default 256), and showLoadingUI (displays a progress indicator during background loading). The optimal chunkSize depends on scene complexity — smaller chunks mean faster first paint but more HTTP overhead; larger chunks mean fewer requests but longer initial wait.
Performance Benchmarks: KSPLAT vs Other 3DGS Formats
The following benchmarks use a standardized test scene: a room-scale 3DGS capture with 1,000,000 Gaussians trained with degree-2 spherical harmonics. All file sizes are measured after format conversion from the original PLY training output.
File size comparison: PLY (full float32) = 236 MB (baseline). KSPLAT compression 0, no SH = 153 MB (65% of PLY). KSPLAT compression 1, no SH = 94 MB (40% of PLY). KSPLAT compression 1, SH degree 2 = 142 MB (60% of PLY). KSPLAT compression 2, no SH = 72 MB (31% of PLY). KSPLAT compression 2, SH degree 2 = 108 MB (46% of PLY). SPLAT (no SH, always) = 32 MB (14% of PLY). SPZ (full SH) = 24 MB (10% of PLY).
First-frame rendering time on 100 Mbps connection: KSPLAT (any compression) = 0.5–1.2 seconds (progressive, shows ~10% of scene). SPLAT = 2.6 seconds (must download full 32 MB). SPZ = 2.0 seconds (must download full 24 MB then decompress). PLY = 19+ seconds (must download full 236 MB). Note that KSPLAT's first frame appears fastest despite having a larger total file size than SPLAT or SPZ — this is the progressive loading advantage.
Visual quality comparison at the same file size budget (~70–80 MB): KSPLAT compression 2 with SH degree 2 (108 MB) preserves view-dependent lighting effects with 8-bit precision — noticeable quantization artifacts in specular highlights but overall good quality. KSPLAT compression 1 without SH (94 MB) has no view-dependent effects but higher geometric precision. Two SPLAT files of the same scene from different viewpoints (64 MB total) cannot be combined. The takeaway: if you need SH within the Three.js ecosystem, KSPLAT compression 1 with SH degree 1 offers the best quality-to-size ratio.
KSPLAT in Production: Real-World Implementation Patterns
For Three.js developers, the standard KSPLAT integration uses the GaussianSplats3D Viewer class. The minimal setup involves creating a Viewer instance with a target DOM element, calling loadFile() with the .ksplat URL, and the library handles progressive loading, sorting, and rendering automatically. Key configuration options include: cameraUp (coordinate system alignment), initialCameraPosition, and splatAlphaRemovalThreshold (controls transparency culling for performance).
In React Three Fiber applications, the community has developed wrapper components that integrate GaussianSplats3D with R3F's declarative scene graph. The typical pattern is a <GaussianSplat> component that accepts a url prop pointing to the .ksplat file and handles lifecycle management (loading, cleanup, resize). Important: GaussianSplats3D manages its own WebGL state, so developers must configure sharedMemory: false to avoid conflicts with R3F's renderer.
Large scene optimization strategies for production: (1) Pre-sort with an optimal viewpoint — KSPLAT's depth sorting is relative to the viewpoint used during file creation. Choose a viewpoint that matches your application's default camera position for the best initial visual quality. (2) Use compression level 1 as the default — it offers the best balance of file size and quality. Level 0 is unnecessarily large for web delivery; level 2 introduces visible artifacts in many scenes. (3) Enable SH only when the scene has strong specular or reflective surfaces — for matte/diffuse scenes, the SH data adds file size without visible benefit. (4) Set appropriate maxMemoryMB limits — GaussianSplats3D can consume significant GPU memory for scenes with 2M+ Gaussians.
Common production issues and solutions: "Scene appears mirrored" — coordinate system mismatch; set cameraUp to [0, -1, 0] for scenes exported from COLMAP. "Progressive loading stalls at 50%" — CDN is not supporting HTTP range requests; ensure your hosting supports the Range header (Cloudflare Pages and Vercel both support this by default). "Memory crash on mobile" — mobile GPUs typically support 500K–1M Gaussians maximum; use splatAlphaRemovalThreshold to cull transparent Gaussians and reduce memory usage by 20–40%.
Who Should Use KSPLAT?
Three.js and React Three Fiber developers: If your tech stack includes the GaussianSplats3D npm package, KSPLAT is your native format. Converting PLY to KSPLAT avoids runtime format conversion overhead and directly leverages the library's optimized rendering path. The format's progressive loading is especially valuable for applications where first-paint speed affects user retention.
Web applications embedding large 3DGS scenes: Any web application containing scenes with over 500,000 Gaussians (about 50 MB PLY) will benefit noticeably from KSPLAT's progressive loading. E-commerce product showcases, architectural walkthroughs, and virtual tour platforms are common use cases where the "instant preview" experience justifies KSPLAT's ecosystem lock-in.
Developers needing partial SH effects in Three.js: Creating KSPLAT with SH enabled preserves spherical harmonics data — better view-dependent lighting than SPLAT's "no SH at all." For scenes with reflective surfaces (glass, metal, water), enabling SH degree 1 at compression level 1 provides a good balance of visual quality and file size.
When NOT to use KSPLAT: Maximum cross-platform compatibility needed (KSPLAT is not supported outside the Three.js ecosystem — use SPLAT for broadest viewer support or SPZ for modern web delivery). Long-term archival (SPZ is a better archival format with Khronos standardization and full SH preservation). Projects not using Three.js (Babylon.js supports SPZ natively; other renderers support SPLAT). File size is the top priority (SPZ at 10% of PLY size is 3–6x smaller than any KSPLAT configuration).
The GaussianSplats3D Ecosystem and KSPLAT's Future
In late 2024, Mark Kellogg (mkkellogg) posted a notice on the GaussianSplats3D repository recommending that users consider migrating to Spark (luma-ai/luma-web), citing better performance and more active development. This announcement raised questions about KSPLAT's long-term viability.
The current state as of early 2026: GaussianSplats3D remains functional and receives occasional bug fixes, but major feature development has shifted to Spark. However, KSPLAT files created with GaussianSplats3D continue to work — the format is a static binary specification, not a live service. Existing .ksplat files will remain readable as long as any compatible decoder exists.
Community response has been mixed. Several developers have forked GaussianSplats3D to maintain KSPLAT support independently. The @mkkellogg/gaussian-splats-3d npm package still receives 2,000–3,000 weekly downloads as of February 2026, indicating significant ongoing production usage. Some teams have written their own KSPLAT decoders based on the open-source reference implementation, decoupling their applications from the library's maintenance trajectory.
For new projects starting in 2026, the pragmatic recommendation is: if you are already using GaussianSplats3D and KSPLAT in production, there is no urgent reason to migrate — the format works and the library is stable. For new projects, evaluate SPZ first (Khronos standardization, smaller files, full SH) and only choose KSPLAT if progressive loading is a hard requirement that SPZ cannot meet. Polyvia3D supports KSPLAT viewing and conversion regardless of the upstream library's status.