TripoSplat-WebGPU-v2 / e2e-web-anim.html
Yosun's picture
Deploy exact Mac 20-step v2 runner
4ad9d34 verified
Raw
History Blame Contribute Delete
14.9 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 full TripoSplat image-to-3D pipeline locally in WebGPU. Generate, preview, and export a 3D Gaussian splat as binary PLY or .splat." />
<meta property="og:type" content="website" />
<meta property="og:title" content="TripoSplat WebGPU · Browser-Local Image to 3D Gaussian Splat" />
<meta property="og:description" content="Run the full TripoSplat image-to-3D pipeline locally in WebGPU. Generate, preview, and export a 3D Gaussian splat as binary PLY or .splat." />
<meta property="og:image" content="https://triposplat-webgpu.vercel.app/corgi.ceo_image_header.social.jpg" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="TripoSplat WebGPU · Browser-Local Image to 3D Gaussian Splat" />
<meta name="twitter:description" content="Run the full TripoSplat image-to-3D pipeline locally in WebGPU. Generate, preview, and export a 3D Gaussian splat as binary PLY or .splat." />
<meta name="twitter:image" content="https://triposplat-webgpu.vercel.app/corgi.ceo_image_header.social.jpg" />
<title>TripoSplat WebGPU · Browser-Local Image to 3D Gaussian Splat</title>
<script type="module" crossorigin src="/assets/e2eWebAnim-NEXYgngj.js"></script>
<link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="modulepreload" crossorigin href="/assets/index-CMkL1IIy.js">
<link rel="modulepreload" crossorigin href="/assets/client-CiuGHKKk.js">
<link rel="modulepreload" crossorigin href="/assets/preload-helper-BXl3LOEh.js">
<link rel="modulepreload" crossorigin href="/assets/index-Bu_7fOn4.js">
<link rel="modulepreload" crossorigin href="/assets/SplatPreview-D3bCUQ8P.js">
<link rel="modulepreload" crossorigin href="/assets/e2eWebMain-DZ_gL9lP.js">
<link rel="stylesheet" crossorigin href="/assets/e2eWebMain-DUGDsyWk.css">
</head>
<body>
<a class="skip-link" href="#main-content">Skip to generator</a>
<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-web.html" aria-label="TripoSplat WebGPU image to 3D">
<span class="brand-mark" aria-hidden="true"><span></span></span><span>TRIPOSPLAT <b>WEBGPU</b></span>
</a>
<span class="capability" id="platform-badge"><i></i><span>Checking platform</span></span>
</nav>
<main id="main-content" class="app-shell web-app">
<header class="web-hero web-hero--animated">
<div class="web-hero-copy">
<div class="eyebrow"><span>Image to 3D Model. </span></div>
<h1><em>Offline. Local. Portable.</em></h1>
<p>Your browser uses WebGPU to run the full TripoSplat model locally.<br />
The ≈6.5 GB model package downloads once, verifies, and stays in offline browser storage.<br />
After that, it is ready to run again without another model download.</p>
<div class="hero-actions"><a class="github-link" href="#source-heading">Try it out <span aria-hidden="true"></span></a><a class="hero-text-link" href="#browser-experiment">Why this matters <span aria-hidden="true"></span></a></div>
</div>
<aside id="hero-animation-root" aria-hidden="true"></aside>
</header>
<section class="compatibility-panel" aria-labelledby="compatibility-heading">
<div><span class="section-index">SYSTEM CHECK</span><h2 id="compatibility-heading">Preparing your browser</h2></div>
<ul id="compatibility-list" aria-live="polite"><li>Checking WebGPU and storage…</li></ul>
</section>
<div class="web-workspace">
<section class="web-controls panel" aria-labelledby="source-heading">
<div class="panel-heading"><div><span class="section-index">STEP 1 / IMAGE</span><h2 id="source-heading">Choose a starting image</h2></div><span class="local-badge">ON DEVICE</span></div>
<p class="panel-copy">Use a transparent PNG or WebP, or prepare an opaque photo locally before generation. The processor removes the background, frames the subject, and creates the official 1024px TripoSplat input.</p>
<input id="image-file" type="file" accept="image/png,image/webp,image/jpeg,image/avif" hidden />
<button id="choose-file" class="file-picker" type="button"><span>Choose image from your computer</span><b>Browse</b></button>
<label class="url-label" for="image-url"><span>Or start from an image URL</span><small id="image-url-help">The image host must allow browser CORS access.</small></label>
<div class="url-row"><input id="image-url" type="url" inputmode="url" placeholder="https://example.com/object.png" autocomplete="url" aria-describedby="image-url-help image-url-error" /><button id="load-image-url" type="button">Use URL</button></div>
<div id="image-url-error" class="image-url-error" role="alert" hidden></div>
<figure id="image-preview" class="image-preview" hidden>
<img id="image-preview-image" alt="Selected source image preview" />
<figcaption>Loaded source image</figcaption>
</figure>
<div id="image-summary" class="image-summary" data-state="empty" aria-live="polite">No image selected yet.</div>
<section class="image-preparation" aria-labelledby="image-preparation-heading">
<div><span class="section-index">OPTIONAL / LOCAL PROCESSING</span><h3 id="image-preparation-heading">Prepare a photo for TripoSplat</h3></div>
<p>Opaque photos start background removal and the official subject crop automatically in this browser. Your pixels stay on this device; use the button to process again.</p>
<button id="prepare-image" type="button" disabled><span>Process image locally</span><b aria-hidden="true"></b></button>
<p id="image-preparation-status" class="image-preparation-status" data-state="idle" role="status" aria-live="polite">Choose an image to enable local processing.</p>
</section>
<button id="drop-zone" class="drop-zone" type="button">Or drag an image here</button>
<a class="continue-to-engine" href="#model-heading">Continue to browser engine <span aria-hidden="true"></span></a>
</section>
<section class="preview-panel-web panel" aria-labelledby="scene-heading">
<div class="panel-heading"><div><span class="section-index">STEP 3 / RESULT</span><h2 id="scene-heading">Your spatial scene</h2></div><span id="viewer-state" class="viewer-state">Waiting</span></div>
<div id="web-preview-root"></div>
<p id="preview-run-state" class="preview-run-state" data-state="waiting" role="status" aria-live="polite">A completed scene will appear here without leaving this page.</p>
<div class="download-row"><button id="download-ply" type="button" disabled>Download PLY</button><button id="download-splat" type="button" disabled>Download .splat</button></div>
</section>
</div>
<section class="model-panel panel" aria-labelledby="model-heading">
<div class="panel-heading"><div><span class="section-index">STEP 2 / BROWSER ENGINE</span><h2 id="model-heading">Preparing the model</h2></div><span id="cache-mode" class="local-badge">CACHE CHECK</span></div>
<p class="panel-copy">Your first run downloads roughly 6.47 GB from the official browser-runtime package, verifies every file, and stores it locally when your browser permits it. You only need to choose an image.</p>
<div class="model-layout"><div id="model-status" class="model-status" aria-live="polite">Checking model and browser storage…</div></div>
<details class="model-advanced"><summary>Use a different model server</summary><label for="model-base"><span>Model CDN directory</span><small>Must contain manifest.json and allow CORS requests from this site.</small><input id="model-base" type="url" inputmode="url" autocomplete="url" spellcheck="false" /></label></details>
<button id="generate" class="primary-action" type="button" disabled><span>Choose an image to begin</span><b aria-hidden="true"></b></button>
<div class="run-feedback"><small id="run-stage">STATUS</small><p id="run-status" aria-describedby="run-stage">Checking browser compatibility…</p><span id="run-announcement" class="visually-hidden" role="status" aria-live="polite" aria-atomic="true"></span><div class="progress-track" role="progressbar" aria-label="Generation progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><span id="progress-fill"></span></div></div>
<section class="generation-flow" aria-labelledby="generation-flow-heading">
<div class="flow-heading"><div><span class="section-index">ENGINEERING PIPELINE</span><h3 id="generation-flow-heading">What this browser is doing</h3></div><div class="progress-detail-switch" role="group" aria-label="Progress detail level"><button type="button" data-progress-detail="guided" aria-pressed="false">Guided</button><button type="button" data-progress-detail="technical" aria-pressed="true">Technical</button></div></div>
<p id="progress-detail-description" class="progress-detail-description">Technical mode shows exact graph stages, sampler steps, CFG invocations, and decode boundaries as they happen.</p>
<ol id="generation-flow" class="flow-steps">
<li data-flow-stage="source" data-state="active" aria-current="step"><span class="flow-marker">01</span><div><strong>Source image</strong><span>Inspect alpha and prepare local pixels.</span></div><small>READY</small></li>
<li data-flow-stage="model" data-state="waiting"><span class="flow-marker">02</span><div><strong>Model package</strong><span>Verify manifest, integrity, and browser cache.</span></div><small>WAITING</small></li>
<li data-flow-stage="conditioning" data-state="waiting"><span class="flow-marker">03</span><div><strong>Conditioning</strong><span>Preprocess → DINOv3 → Flux VAE.</span></div><small>WAITING</small></li>
<li data-flow-stage="sampling" data-state="waiting"><span class="flow-marker">04</span><div><strong>Flow sampler</strong><span>20 official steps · 40 CFG DiT calls.</span></div><small>WAITING</small></li>
<li data-flow-stage="decode" data-state="waiting"><span class="flow-marker">05</span><div><strong>Spatial decode</strong><span>Octree occupancy → Gaussian decoder.</span></div><small>WAITING</small></li>
<li data-flow-stage="preview" data-state="waiting"><span class="flow-marker">06</span><div><strong>Scene handoff</strong><span>Encode PLY / .splat and swap the viewer.</span></div><small>WAITING</small></li>
</ol>
</section>
<section id="benchmark-report" class="benchmark-report" aria-labelledby="benchmark-heading" hidden>
<div class="flow-heading"><div><span class="section-index">RUN REPORT</span><h3 id="benchmark-heading">Copyable benchmark summary</h3></div><button id="copy-benchmark" type="button" disabled>Copy report</button></div>
<p id="benchmark-summary" class="benchmark-summary" role="status" aria-live="polite">Complete a generation to capture its timing and browser environment.</p>
<pre id="benchmark-details" class="benchmark-details" tabindex="0"></pre>
</section>
<div class="secondary-actions"><button id="cancel" type="button" disabled>Cancel current operation</button><button id="clear-cache" type="button">Clear cached model files</button></div>
<div id="diagnostics" class="diagnostics" hidden><p id="diagnostic-message"></p><details><summary>Technical details</summary><pre id="diagnostic-details"></pre></details></div>
<p class="privacy-note">Your image stays on this device. TripoSplat artifacts are requested from the official <a href="https://huggingface.co/Yosun/TripoSplat-WebGPU/">Hugging Face package</a> unless you choose another server. When you select local image processing, its browser-local background-removal model is fetched and cached separately; transparent PNG or WebP files do not need that step.</p>
</section>
<section id="browser-experiment" class="experiment-panel panel" aria-labelledby="experiment-heading">
<div class="experiment-intro"><span class="section-index">WHY THIS MATTERS</span><h2 id="experiment-heading">A monumental attempt to put CUDA-era 3D generation in reach of more people.</h2></div>
<div class="experiment-copy"><p>TripoSplat started as a CUDA-based 3D generation pipeline. With Codex GPT 5.6 Sol Ultra and GPT 5.6 Sol Max in Kiro, this project is porting that work to WebGPU—replacing the usual requirements for NVIDIA hardware, CUDA, terminal commands, environment setup, and local dependency installation with a browser-native workflow.</p><p>The goal is not a cosmetic port. It is an attempt to make advanced AI 3D generation radically more accessible: for GPUPoor MacBook users, students, independent developers, and anyone without an expensive GPU. When a browser passes the system check, they can generate a 3D asset locally on hardware they already own—no terminal, no installation, and no cloud GPU bill for inference.</p><p>This is still an engineering preview, with compatibility and quality under active qualification. But the direction is clear: keep powerful spatial-generation tools inspectable, local, and available to more builders.</p><a class="github-link" href="https://github.com/yosun/TripoSplatWebGPU" target="_blank" rel="noreferrer">Read the source, benchmarks, and open issues on GitHub <span aria-hidden="true"></span></a></div>
</section>
</main>
<footer><span>TRIPOSPLAT WEBGPU · ENGINEERING PREVIEW</span><a href="#source-heading">Try it out</a><a href="https://github.com/yosun/TripoSplatWebGPU" target="_blank" rel="noreferrer">View source on GitHub <span aria-hidden="true"></span></a><a href="https://www.producthunt.com/products/triposplat-webgpu?embed=true&amp;utm_source=badge-featured&amp;utm_medium=badge&amp;utm_campaign=badge-triposplat-webgpu" target="_blank" rel="noopener noreferrer"><img alt="TripoSplat WebGPU - Image to 3D Model: Offline. Local. Portable. | Product Hunt" width="250" height="54" src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1198682&amp;theme=light&amp;t=1784320164461"></a><a href="/e2e-lab.html">Qualification lab</a><a href="/sharp-lab.html">Legacy SHARP lab</a></footer>
</body>
</html>