Skip to main content

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?

Interactive 3D visualization design showcasing modern web-based 3D rendering capabilities
KSPLAT is optimized for browser-based Gaussian Splatting viewers with progressive loading

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.

Frequently Asked Questions

Mark Kellogg (mkkellogg) created KSPLAT as the native format for his GaussianSplats3D library for Three.js. He open-sourced both the library and the format specification. The GaussianSplats3D library is the most widely used Three.js implementation for rendering Gaussian Splatting scenes, with over 4,200 GitHub stars and thousands of developers using it in web applications.
Yes — unlike SPLAT which never supports SH, KSPLAT supports optional spherical harmonics at up to degree 2. When creating a KSPLAT file, two independent parameters control SH: the spherical harmonics level (0 = no SH, 1 = degree 1, 2 = degree 2) and the compression level (which determines data precision — 16-bit or 8-bit — when SH is present). The SH level defaults to 0 (no SH), so most KSPLAT files do not contain spherical harmonics unless explicitly enabled during creation. Enabling SH degree 1 at compression level 1 is the recommended starting point for scenes with reflective surfaces.
Yes, for large scenes — but the advantage is in perceived speed, not total download time. KSPLAT's chunked structure enables progressive loading: the viewer starts rendering with the first chunk before the full file downloads. For a 100 MB scene (about 1 million Gaussians), KSPLAT shows initial visuals in under 1 second while SPLAT requires the full file to download first (2–3 seconds on broadband). For small scenes under 10 MB, the difference is negligible. Note that KSPLAT files are typically larger than SPLAT files for the same scene, so total download time may actually be longer — the benefit is purely in time-to-first-frame.
Not easily. KSPLAT is a format with no formal specification outside of the GaussianSplats3D library. Most other web viewers and desktop tools do not support it. If you need cross-platform compatibility, convert to PLY (for desktop tools), SPLAT (for broadest web viewer support), or SPZ (for modern web delivery with SH preservation). Polyvia3D supports viewing and converting KSPLAT files to all other 3DGS formats.
The GaussianSplats3D library author (mkkellogg) posted a notice in late 2024 recommending users consider migrating to Spark (luma-ai/luma-web) for better performance. However, GaussianSplats3D remains functional, receives occasional updates, and still has 2,000–3,000 weekly npm downloads as of early 2026. The KSPLAT format itself is a static binary specification — existing .ksplat files will continue to work regardless of the library's development pace. Several community forks also maintain KSPLAT support independently.
Compression level 1 (half-float/16-bit) is the recommended default for most use cases — it reduces file size by approximately 40% compared to level 0 with minimal visual quality loss. Level 0 (full float32) is only needed for scientific or measurement applications where sub-millimeter precision matters. Level 2 (8-bit) provides the smallest files but introduces visible quantization artifacts, especially in smooth gradients and specular highlights — use it only when bandwidth is severely constrained (mobile networks, embedded IoT displays).
Only if the KSPLAT was created at compression level 0 (no compression). At compression levels 1 and 2, the conversion to KSPLAT is lossy — float32 values are quantized to float16 or uint8, and this precision loss cannot be recovered. Converting a level-1 or level-2 KSPLAT back to PLY will produce a valid PLY file, but it will contain the quantized values, not the original full-precision data. If you need lossless round-trip conversion, always keep your original PLY training output as the archival copy.
The KSPLAT format itself has no hard limit on Gaussian count. In practice, the bottleneck is GPU memory: desktop GPUs (8–16 GB VRAM) can typically handle 3–5 million Gaussians, while mobile GPUs are limited to 500K–1M Gaussians before performance degrades significantly. For very large scenes (5M+ Gaussians), consider using splatAlphaRemovalThreshold to cull near-transparent Gaussians (typically 20–40% of total), or split the scene into multiple KSPLAT files loaded on demand based on camera position.

How-to Guides

Related Guides