TripoSplat-WebGPU / e2e-lab.html
Yosun's picture
Publish prebuilt WebGPU demo
c18dbb7 verified
Raw
History Blame Contribute Delete
6.94 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="dark" />
<meta name="theme-color" content="#070a12" />
<meta name="description" content="Run the TripoSplat five-stage image-to-Gaussian pipeline locally with WebGPU." />
<title>TripoSplat WebGPU · Spatial Generation Lab</title>
<script type="module" crossorigin src="/assets/e2eLab-yJ57WL8T.js"></script>
<link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="modulepreload" crossorigin href="/assets/preload-helper-BXl3LOEh.js">
<link rel="stylesheet" crossorigin href="/assets/e2eLab-tgRBtYNi.css">
</head>
<body>
<div class="ambient ambient-one" aria-hidden="true"></div>
<div class="ambient ambient-two" aria-hidden="true"></div>
<nav class="topbar" aria-label="Primary navigation">
<a class="brand" href="/e2e-lab.html" aria-label="TripoSplat WebGPU home">
<span class="brand-mark" aria-hidden="true"><span></span></span>
<span>TRIPOSPLAT <b>WEBGPU</b></span>
</a>
<div class="topbar-meta">
<span class="capability" id="webgpu-capability"><i></i>Checking WebGPU</span>
<a href="https://github.com/yosun/TripoSplatWebGPU" rel="noreferrer">GitHub <span aria-hidden="true"></span></a>
</div>
</nav>
<main class="app-shell">
<header class="hero">
<div class="eyebrow"><span>01</span> Browser-native spatial intelligence</div>
<h1>Turn pixels into<br /><em>spatial worlds.</em></h1>
<p>Run the complete five-stage TripoSplat pipeline on your GPU. Your prepared image stays in the browser—from neural encoding to an interactive Gaussian scene.</p>
<div class="pipeline" aria-label="Pipeline stages">
<span>DINOv3</span><i></i><span>Flux VAE</span><i></i><span>Flow</span><i></i><span>Octree</span><i></i><span>Gaussians</span>
</div>
</header>
<div class="workspace-grid">
<aside class="control-panel panel">
<div class="panel-heading">
<div><span class="section-index">CONTROL / 01</span><h2>Generation setup</h2></div>
<span class="local-badge">LOCAL</span>
</div>
<p class="panel-copy">Connect immutable model artifacts and deterministic fixtures. Nothing is uploaded by this interface.</p>
<div class="field-stack">
<label for="model-base"><span>Model base URL</span><small>Manifest and ONNX graph directory</small></label>
<input id="model-base" value="/models/triposplat/" autocomplete="url" spellcheck="false" />
<label for="cache"><span>Artifact cache</span><small>Persistent storage reduces repeat downloads</small></label>
<select id="cache">
<option value="none" selected>Ephemeral · release after each graph</option>
<option value="opfs">OPFS · persistent device cache</option>
<option value="cache-api">Cache API · persistent browser cache</option>
</select>
</div>
<details class="advanced">
<summary><span>Fixture endpoints</span><small>Advanced</small></summary>
<div class="advanced-fields">
<label for="prepared-image">Prepared image</label>
<input id="prepared-image" value="/fixtures/generated/dinov3-fp32/prepared.png" autocomplete="url" spellcheck="false" />
<label for="vae-noise">VAE epsilon</label>
<input id="vae-noise" value="/fixtures/generated/flux2-vae-fp32/epsilon.f32" autocomplete="url" spellcheck="false" />
<label for="flow-fixture">Flow fixture directory</label>
<input id="flow-fixture" value="/fixtures/generated/flow4-fp32-compute" autocomplete="url" spellcheck="false" />
</div>
</details>
<div class="run-actions">
<button class="run-button" id="run" type="button"><span>Run spatial generation</span><b aria-hidden="true"></b></button>
<button class="cancel-button" id="cancel" type="button" disabled>Cancel</button>
</div>
<div class="status-card">
<span class="status-pulse" aria-hidden="true"></span>
<div><small>PIPELINE STATUS</small><p role="status" data-testid="e2e-status">Ready. The default non-persistent mode verifies and stages one graph at a time.</p></div>
</div>
</aside>
<section class="viewer-panel panel" aria-labelledby="e2e-viewer-heading">
<div class="panel-heading viewer-heading">
<div><span class="section-index">VIEWPORT / 02</span><h2 id="e2e-viewer-heading">Gaussian scene</h2></div>
<p data-testid="e2e-viewer-status" data-viewer-state="waiting">Waiting for exported PLY</p>
</div>
<div id="e2e-preview-root">
<div class="viewer-placeholder" aria-hidden="true">
<div class="orbital"><span></span><i></i></div>
<p>Spatial viewport armed</p>
<small>Your generated scene will appear here</small>
</div>
</div>
<div class="viewer-footer" aria-hidden="true"><span>262K GAUSSIANS</span><span>BROWSER GPU</span><span>PLY + SPLAT</span></div>
</section>
</div>
<section class="notice" aria-label="Demo requirements">
<span>NOTE</span>
<p>This public interface is an engineering preview. A run requires a current desktop Chromium browser with WebGPU and separately hosted model artifacts with CORS and byte-range support.</p>
</section>
<pre class="error" data-testid="e2e-error" hidden></pre>
<pre data-testid="e2e-result" hidden></pre>
</main>
<footer><span>TRIPOSPLAT WEBGPU · 2027 INTERFACE</span><span>INFERENCE STAYS ON DEVICE</span></footer>
<script>
const publishBootstrapError = (value) => {
const target = document.querySelector('[data-testid="e2e-error"]')
if (!target) return
const error = value instanceof Error ? value : new Error(String(value))
target.textContent = `Bootstrap error: ${error.name}: ${error.message}`
target.hidden = false
}
const capability = document.querySelector('#webgpu-capability')
if (capability) {
const supported = 'gpu' in navigator
capability.classList.toggle('is-ready', supported)
capability.classList.toggle('is-missing', !supported)
capability.lastChild.textContent = supported ? 'WebGPU ready' : 'WebGPU unavailable'
}
window.addEventListener('error', (event) => publishBootstrapError(event.error ?? event.message))
window.addEventListener('unhandledrejection', (event) => publishBootstrapError(event.reason))
</script>
</body>
</html>