An innovative online shopping demo that showcases products using Gaussian Splatting technology powered by WebGPU/WebGL2 and PlayCanvas's SOG format.
- Cutting-edge 3D Visualization: Display products using Gaussian Splatting technology
- Multiple Format Support: Load Gaussian Splats in
.sog(compressed),.splat(standard), or.ply(raw) formats - SOG Format Optimization: Utilizes PlayCanvas's open-source SOG (Spatially Ordered Gaussians) format for efficient compression
- Modern Graphics: Leverages WebGPU (preferred) or WebGL2 (fallback) for high-performance rendering
- Interactive 3D Viewer:
- Rotate products with left-click and drag
- Pan view with right-click and drag
- Zoom with mouse wheel
- Product Catalog: Sample toys and beverages included
- Responsive Design: Works on desktop and mobile devices
- A modern web browser with WebGPU or WebGL2 support (Chrome 113+, Edge 113+, Firefox, Safari, or other compatible browsers)
It's that simple - just open the file!
- Download or clone this repository
- Double-click
index.htmlto open it in your default browser- Or right-click → "Open with" → Choose your browser
That's it! The demo runs entirely in your browser with no installation, no server, and no build steps required. 🎉
Note: The demo works great directly from the file system. If you add actual SOG files later and encounter CORS issues, you can optionally use a local server, but it's not required for the basic demo.
online-shopping/
├── index.html # Main HTML file
├── styles.css # Styling
├── app.js # Application logic
├── assets/ # Bundled SOG files (see list below)
│ ├── birthday-cake.sog
│ ├── building-blocks.sog
│ ├── …
│ └── water-bottle.sog
└── README.md
The repository now ships with 21 synthetic .sog files so every product card loads a real Gaussian Splat locally—no network fetches required. Each file was generated with PlayCanvas' open-source SplatTransform CLI using the gen-grid.mjs generator (also vendored in tools/).
| Product | SOG file |
|---|---|
| Nezuko Burger | assets/nezuko-burger.sog |
| Birthday Cake | assets/birthday-cake.sog |
| Building Blocks | assets/building-blocks.sog |
| Orange Juice | assets/orange-juice.sog |
| Cola Bottle | assets/cola-bottle.sog |
| Coffee Cup | assets/coffee-cup.sog |
| Race Car | assets/race-car.sog |
| Dinosaur Figure | assets/dinosaur.sog |
| Puzzle Set | assets/puzzle-set.sog |
| Green Tea | assets/green-tea.sog |
| Smoothie | assets/smoothie.sog |
| Energy Drink | assets/energy-drink.sog |
| Action Figure | assets/action-figure.sog |
| Doll House | assets/doll-house.sog |
| Water Bottle | assets/water-bottle.sog |
| Robot Toy | assets/robot-toy.sog |
| Teddy Bear | assets/teddy-bear.sog |
| Chocolate Box | assets/chocolate-box.sog |
| Pizza Slice | assets/pizza-slice.sog |
| Ice Cream | assets/ice-cream.sog |
| Sushi Set | assets/sushi-set.sog |
You can now choose between two pipelines depending on whether you want placeholder grids or real captures:
- Synthetic grid builder –
tools/generate-sogs.ps1(existing workflow) - Real capture pipeline –
tools/download-ply-and-convert.ps1(new.ply → .sogworkflow)
- Open Windows PowerShell
- Run:
The script calls
powershell -ExecutionPolicy Bypass -File tools/generate-sogs.ps1
npx @playcanvas/splat-transformfor each product, usingtools/gen-grid.mjsand the per-product parameters defined inside the script. Tweak those values to update the look.
ℹ️ This builder deletes the intermediate WebP textures generated by SplatTransform, keeping only the final
.sogoutputs to avoid clutter.
- Populate
tools/ply-assets.jsonwith the.plycaptures you want to ingest (details below). - Preview the run without touching the network:
powershell -ExecutionPolicy Bypass -File tools/download-ply-and-convert.ps1 -DryRun
- Once the plan looks good, drop
-DryRunto actually download (ifplyUrlis provided), verify checksums, and convert everything intoassets/*.sogvianpx @playcanvas/splat-transform. - Use
-Names <asset>to target a subset,-SkipDownloadto reuse already-downloaded.plyfiles, or-SkipConvertif you only want to refresh the cache. - If your GPU driver crashes during compression (WebGPU device lost), pass
-UseCputo fall back to the CPU implementation—slower, but rock solid.
Downloads land in tmp/ply-cache/, keeping your repository clean, while the .sog files continue to live under assets/ for easy loading inside the viewer.
Because .sog is just the compressed delivery format, start by gathering high-quality .ply splats (Gaussian point clouds). Great sources include:
- Luma AI – Export your own captures as "Gaussian Splat (.ply)" from the desktop uploader.
- Polycam – Public Explore feed items often allow
.plydownloads; check the creator’s license before redistributing. - Hugging Face Datasets – Search for "Gaussian Splat" or "NeRF" datasets (many researchers share sample
.plypoint clouds). - GitHub / Research repos – e.g., Stanford’s 3D Scanning models (bun_zipper.ply), Inria’s "Truck" / "Garden" scenes, or any dataset released for academic reuse.
- Community drops – Discords and forums dedicated to Gaussian Splatting frequently share
.plyexports ready for experimentation.
Always confirm usage rights before mirroring someone else’s capture in this repository. Many creators limit redistribution outside their platform of choice.
Each entry describes how to fetch and convert a .ply capture:
[
{
"name": "polycam-sushi-set",
"enabled": true,
"plyUrl": "https://example.com/polycam/sushi-set/gaussians.ply",
"localPath": "C:/Captures/polycam/sushi-set/gaussians.ply",
"sogFile": "assets/sushi-set-real.sog",
"sha256": "<optional checksum>",
"notes": "Creator: Jane Doe (CC BY 4.0)"
}
]plyUrl(optional) lets the script download directly. Leave it empty if the host requires authentication and instead pointlocalPathto a manually-downloaded file.localPathmay be absolute or relative to the repo root. The script verifies the file exists before conversion.sha256(optional) adds tamper detection—grab it viaGet-FileHashafter your first download.- Toggle
enabledto control which entries run; combine with-Namesto filter on demand.
Once configured, execute tools/download-ply-and-convert.ps1 (see the regeneration section above) to populate assets/ with the freshly compressed .sog bundles.
💡 Tip: keep large
.plyfiles out of Git by leaving them insidetmp/ply-cache/(ignored) or an external drive. Only the compressed.sogartifacts need to live in the repo.
PlayCanvas' splat-transform only understands Gaussian Splat point clouds—the .ply must already contain Morton-ordered splats with properties such as scale_0, rot_0, f_dc_0, opacity, etc. Traditional mesh PLYs (e.g., Stanford Bunny, OBJ-to-PLY exports, CAD meshes) lack these attributes, so the converter throws Error: Invalid ply header.
Where to get valid Gaussian .ply exports:
- Luma AI / Polycam / KIRI – export "Gaussian Splat" or
.plywith spherical harmonics enabled. - Nerfstudio & gsplat datasets – many Hugging Face repos publish pre-trained splats (look for files named
point_cloud.ply,gaussians.ply, etc.). - SuperSplat / Gaustudio – when creators allow downloads, the exported
.plyalready contains the full Gaussian attribute set.
If you only have a triangle mesh, you'll need to run a photogrammetry→Gaussian pipeline (e.g., train a NeRF + convert to splats) before this tooling can help.
- The new
tools/download-ply-and-convert.ps1script now inspects the.plyheader before callingsplat-transformand fails fast with a descriptive error listing any missing Gaussian columns. - To bypass the check (not recommended), pass
-SkipSchemaValidation, though the downstream converter will still reject unsupported files. - Open the
.plyin a text editor and confirm you see lines likeproperty float scale_0,property float opacity, andproperty float f_dc_0. If they aren't there, the file isn't a Gaussian splat export.
Edit app.js and add your product to the products array. New products are automatically displayed first (the array is rendered in reverse order), so simply append new products at the end with incrementing IDs:
{
id: 23, // Just increment from the last ID
name: "Your Product",
icon: "🎁",
description: "Product description",
price: "$XX.XX",
category: "toys", // or "beverages"
sogFile: "assets/your-product.sog", // or .splat, .ply
status: "available", // or "sample"
dateAdded: "2025-11-16" // Optional: adds "NEW" badge
}The viewer displays products in reverse ID order, so higher IDs appear first. This means you never need to renumber existing products when adding new ones!
Create an assets/ folder in the project root and place your Gaussian Splat files there. Supported formats:
.sog- Compressed SOG format (recommended, ~95% smaller than PLY).splat- Standard Gaussian Splat format.ply- Raw PLY format (Gaussian Splat point clouds only)
The viewer automatically detects the format based on file extension.
- Browse Products: Click on any product card in the left sidebar
- View in 3D: The product will load in the 3D viewer
- Interact:
- Rotate: Left-click and drag
- Pan: Right-click and drag
- Zoom: Scroll mouse wheel
- Reset View: Click the "🔄 Reset View" button to return to default camera position
- PlayCanvas Engine: Real-time 3D graphics engine
- WebGPU/WebGL2: Modern graphics APIs with automatic fallback
- SOG Format: Spatially Ordered Gaussians - highly compressed format for Gaussian Splats
- JavaScript: Application logic
- HTML5/CSS3: User interface
| Format | Description | File Size | Best For |
|---|---|---|---|
.sog |
SOG (Spatially Ordered Gaussians) - Compressed format | ~5% of PLY | Production (recommended) |
.splat |
Standard Gaussian Splat format | ~50% of PLY | Balanced size/quality |
.ply |
Raw Gaussian Splat point cloud | 100% (largest) | Development/testing |
- 📦 Convenient: Single
.sogfile format - ⚡ Fast Loading: GPU-ready Morton order storage
- 🗜️ High Compression: ~95% file size reduction compared to PLY
- 🎯 Precision: Minimized compression artifacts
- 🌐 Cross-platform: Works anywhere WebGPU or WebGL2 is supported
- 🔄 Auto-detection: Viewer automatically recognizes .sog, .splat, and .ply formats
| Browser | Version | Support |
|---|---|---|
| Chrome | 113+ | ✅ Full |
| Edge | 113+ | ✅ Full |
| Firefox | Experimental | 🟡 Partial |
| Safari | Technology Preview | 🟡 Partial |
- PlayCanvas SOG Blog: https://blog.playcanvas.com/playcanvas-open-sources-sog-format-for-gaussian-splatting/
- PlayCanvas Engine: https://github.com/playcanvas/engine
- SplatTransform CLI: https://github.com/playcanvas/splat-transform
- SuperSplat: https://superspl.at/ (Platform for creating and sharing Gaussian Splats)
- PlayCanvas Documentation: https://developer.playcanvas.com/
Note: The default experience already loads real Gaussian Splat bundles from assets/, so you can inspect the entire flow without hitting the network. To swap in your own captures:
- Generate or download
.sogfiles (see "Adding Your Own Products" above) - Replace the files in
assets/or update thesogFilepaths inapp.js - Refresh the page—no bundler or server required
Because the viewer now supports both local and remote URLs, you can mix-and-match: keep certain hero products online while iterating on offline samples.
No installation, no build process, no dependencies to manage. Just add the files and refresh your browser. 🚀
Edit styles.css to customize:
- Color scheme (CSS variables in
:root) - Layout and spacing
- Animation effects
Add new categories by:
- Adding products with new category values
- Optionally filtering by category in the UI
Adjust camera behavior in app.js:
const orbitCamera = {
distance: 5, // Initial distance
distanceMin: 2, // Minimum zoom
distanceMax: 20, // Maximum zoom
pitch: 15, // Initial pitch angle
yaw: 0 // Initial yaw angle
};This is a demo project, but feel free to:
- Add more product categories
- Improve the UI/UX
- Optimize loading and rendering
- Add shopping cart functionality
- Implement product filtering and search
This demo is provided as-is for educational and demonstration purposes.
PlayCanvas Engine is licensed under the MIT License.
- PlayCanvas Team for the amazing engine and SOG format
- Wieland Morgenstern (Fraunhofer HHI) for the original SOGS format
- Vincent Woo for SOGS integration into PlayCanvas
For questions about:
- PlayCanvas: Visit the PlayCanvas Forum
- SOG Format: Check the PlayCanvas Discord
- This Demo: Open an issue in this repository
Built with ❤️ using PlayCanvas