How to Publish and Export Data from SuperSplat: A Complete Technical Guide
SuperSplat provides two distinct data workflows—publishing uploads PLY scenes to the PlayCanvas backend to create shareable .sog files, while exporting serializes splat data locally to PLY, compressed PLY, SOG, or bundled HTML viewer formats using the serialization functions in src/splat-serialize.ts.
SuperSplat, the open-source Gaussian Splat editor maintained by PlayCanvas, offers robust pipelines for both cloud publishing and local file export. Understanding how to publish and export data from SuperSplat requires familiarity with its event-driven architecture and the specific TypeScript modules that handle Gaussian splat transformations. This guide examines the actual implementation in the playcanvas/supersplat repository to show you exactly how these workflows operate under the hood.
Publishing Scenes to the PlayCanvas Cloud
The publishing workflow is triggered by the scene.publish event and implemented primarily in src/publish.ts. This process authenticates users, performs multipart uploads, and creates or updates splat records via the PlayCanvas API.
Authentication and User Credentials
Before uploading, the system retrieves user credentials by calling fetchUser(), which makes a request to <origin>/api/id to obtain a User object containing the user id, authentication token, and API server endpoint.
Multipart Upload Process
The actual file upload uses PublishWriter.create() to initiate a multipart upload on the PlayCanvas upload/start-upload endpoint. The implementation streams PLY data in 10 MiB chunks, tracking progress through the ProgressWriter wrapper, and finalizes with a call to upload/complete-upload.
Creating or Updating Splats Records
After successful upload, the system either creates a new splat record or updates an existing one:
- New publication:
doPublish()sends a POST request to${apiServer}/splats/publishwith the S3 key, title, description, visibility flag, and experience settings. - Republishing: If an
overwriteIdis provided,doRepublish()sends a PUT request to${apiServer}/splats/${overwriteId}/republishto update the existing record.
The request body includes experience settings (camera configuration, animation data, and post-effects) alongside the file metadata.
Publishing Code Example
import { registerPublishEvents, PublishSettings } from './src/publish';
async function publishScene(settings: PublishSettings) {
// Register handlers (typically done once on application startup)
registerPublishEvents(events);
// Trigger the publishing workflow
await events.invoke('scene.publish', settings);
}
// Configure publishing parameters
const settings: PublishSettings = {
user: await fetchUser(),
title: 'My Gaussian Scene',
description: 'Processed with SuperSplat',
listed: true,
serializeSettings: { maxSHBands: 3, selected: false },
experienceSettings: { /* camera & post-effect configuration */ },
overwriteId: 'abc123', // Optional: for updating existing scenes
};
publishScene(settings);
Exporting Scenes Locally
Exporting operates entirely client-side through the functions defined in src/splat-serialize.ts. This module leverages the @playcanvas/splat-transform library to convert in-memory Gaussian data into various binary formats.
Supported Export Formats
SuperSplat supports four primary export targets:
- Standard PLY:
serializePlyoutputs uncompressed binary PLY files - Compressed PLY:
serializePlyCompressedpacks data into 256-splat chunks for reduced file size - SOG format:
serializeSogproduces GPU-compressed binary optimized for PlayCanvas rendering - HTML Viewer:
serializeViewergenerates self-contained HTML files or ZIP bundles with embedded assets
The Serialization Pipeline
All export functions share a common architecture implemented in src/splat-serialize.ts:
- FileSystem setup: Creates either a
WriterFileSystemfor streamed downloads orMemoryFileSystemfor in-memory ZIP generation - Progress wrapping: Instantiates a
ProgressWriterto emitprogressUpdateevents to the UI - Data preparation: Initializes a
SingleSplatreader to extract per-Gaussian values while applying world-space transforms, color tinting, and opacity conversion - Filtering and writing: Uses
GaussianFilterto iterate over valid gaussians, writing vertices to binary buffers and flushing when full - Finalization: Closes the writer to release resources and trigger downloads
Exporting to PLY Format
import { serializePly, SerializeSettings } from './src/splat-serialize';
import { WriterFileSystem } from './src/publish';
async function exportToPly(splats, settings: SerializeSettings) {
// Create a writer that streams to browser download
const writer = await createDownloadWriter('scene.ply');
const fs = new WriterFileSystem(writer);
// Serialize with progress tracking
await serializePly(splats, settings, fs, 'scene.ply');
// Finalize and trigger download
await writer.close();
}
Creating Bundled HTML Viewers
For sharing interactive scenes, serializeViewer generates standalone HTML files:
import { serializeViewer, ViewerExportSettings } from './src/splat-serialize';
async function exportViewer(splats, serializeSettings, experienceSettings) {
const exportOpts: ViewerExportSettings = {
type: 'html', // or 'zip' for packaged assets
experienceSettings,
events // Optional: for UI progress callbacks
};
const writer = await createDownloadWriter('viewer.html');
const fs = new WriterFileSystem(writer);
await serializeViewer(splats, serializeSettings, exportOpts, fs);
await writer.close();
}
Note: The HTML export automatically initializes a WebGPU device via createGpuDevice() for GPU-accelerated SOG compression, falling back to CPU processing if WebGPU is unavailable.
Shared Infrastructure and Utilities
Both publishing and exporting rely on common abstractions defined in src/io/index.ts and the central event bus.
FileSystem Abstractions
The WriterFileSystem class provides a unified interface for file operations, whether streaming to network uploads (publishing) or local blobs (exporting). For ZIP archive creation, the system uses MemoryFileSystem to manage in-memory file structures before final compression.
Progress Tracking and UI Integration
The ProgressWriter wrapper (found in src/io/index.ts) monitors byte-level progress and fires progressStart, progressUpdate, and progressEnd events. These events drive the UI components in src/ui/popup.ts and src/ui/status-bar.ts, displaying upload progress bars and completion notifications.
Event Architecture
The entire workflow is orchestrated through the Events system (src/events.ts), which decouples the serialization logic from UI components. When publishing, the scene.publish event triggers the chain of authentication, upload, and API calls, while export operations use the same event bus for progress feedback without network dependencies.
Summary
- Publishing requires authentication against the PlayCanvas API, streams PLY data via multipart upload in 10 MiB chunks, and creates or updates splat records at the
/splats/publishor/splats/{id}/republishendpoints. - Exporting uses client-side serialization functions (
serializePly,serializeViewer, etc.) insrc/splat-serialize.tsto generate PLY, compressed PLY, SOG, or HTML outputs via thesplat-transformlibrary. - Both workflows utilize shared infrastructure including
WriterFileSystemfor I/O abstraction,ProgressWriterfor feedback, and the centralEventsbus for UI coordination. - File locations: Core publishing logic resides in
src/publish.ts, while export functionality is centralized insrc/splat-serialize.ts, with I/O utilities insrc/io/index.ts.
Frequently Asked Questions
What is the difference between publishing and exporting in SuperSplat?
Publishing uploads your scene to PlayCanvas servers, creating a shareable .sog file accessible via URL, while exporting generates local files (PLY, SOG, or HTML) that remain on your machine. Publishing requires an internet connection and PlayCanvas account authentication, whereas exporting works entirely offline using the serialization pipeline in src/splat-serialize.ts.
How do I update an existing published scene instead of creating a new one?
Provide the overwriteId parameter in your PublishSettings object when invoking the scene.publish event. When overwriteId is present, the system calls doRepublish() which sends a PUT request to ${apiServer}/splats/${overwriteId}/republish rather than creating a new record via POST.
What format should I use for the smallest file size?
Use compressed PLY via serializePlyCompressed for standard editing workflows, or SOG format via serializeSog for web deployment. The compressed PLY format packs gaussians into 256-splat chunks, while SOG applies additional GPU-friendly compression. For maximum compatibility, the compressed PLY offers the best balance between size and software support.
Can I export a scene without installing the full SuperSplat application?
Yes, by utilizing the HTML viewer export via serializeViewer. This generates a self-contained HTML file with embedded WebGPU rendering that opens directly in compatible browsers without requiring the SuperSplat editor. The export process handles all compression and asset bundling automatically, producing either a single .html file or a .zip package depending on the type parameter.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →