TripoSplat-WebGPU-v2 / e2e-web.html
Yosun's picture
Deploy exact Mac 20-step v2 runner
4ad9d34 verified
Raw
History Blame Contribute Delete
15.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 TripoSplat V2 with browser WebGPU and the bit-exact official 20-step fp32 sampler on local Mac MPS." />
<meta property="og:type" content="website" />
<meta property="og:title" content="TripoSplat WebGPU V2 · Exact 20-Step Mac Runner" />
<meta property="og:description" content="Browser WebGPU around the bit-exact official 20-step fp32 sampler on local Mac MPS." />
<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 V2 · Exact 20-Step Mac Runner" />
<meta name="twitter:description" content="Browser WebGPU around the bit-exact official 20-step fp32 sampler on local Mac MPS." />
<meta name="twitter:image" content="https://triposplat-webgpu.vercel.app/corgi.ceo_image_header.social.jpg" />
<title>TripoSplat WebGPU V2 · Exact 20-Step Mac Runner</title>
<script type="module" crossorigin src="/assets/modulepreload-polyfill-B5Qt9EMX.js"></script>
<script type="module" crossorigin src="/assets/index-CMkL1IIy.js"></script>
<script type="module" crossorigin src="/assets/client-CiuGHKKk.js"></script>
<script type="module" crossorigin src="/assets/preload-helper-BXl3LOEh.js"></script>
<script type="module" crossorigin src="/assets/index-Bu_7fOn4.js"></script>
<script type="module" crossorigin src="/assets/SplatPreview-D3bCUQ8P.js"></script>
<script type="module" crossorigin src="/assets/e2eWebMain-DZ_gL9lP.js"></script>
<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">
<div class="eyebrow"><span>Image to 3D Model. </span></div>
<h1>Exact 20-Step.<br /><em>On Your Mac.</em></h1>
<p>V2 combines browser WebGPU conditioning and spatial decoding with the untouched official fp32 flow sampler on local Apple MPS.<br />
The final 20-step latent and camera match the official fixture bit-for-bit, while the inaccurate and slower WebGPU DiT is not downloaded.<br />
Your image and flow tensors stay on your device.</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>
</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 / EXACT MAC 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">V2 keeps image conditioning and spatial decoding in WebGPU, then runs all 40 flow calls through the bit-exact official fp32 sampler on your Mac. The inaccurate 1.64 GB WebGPU DiT artifact is skipped.</p>
<section class="mps-connection" id="mps-connection" data-state="idle" aria-labelledby="mps-connection-heading">
<div class="mps-connection-heading"><div><span class="section-index">REQUIRED / MAC V2</span><h3 id="mps-connection-heading">Connect the local MPS sampler</h3></div><span id="mps-connection-badge">NOT CONNECTED</span></div>
<p>Start the v2 Mac launcher, then use its authenticated link or paste the printed token here. Tensor traffic stays on loopback; the service refuses non-official source and weight revisions.</p>
<div class="mps-connection-fields">
<label for="mps-service-url"><span>Local service</span><input id="mps-service-url" type="url" inputmode="url" value="http://127.0.0.1:8765/" autocomplete="off" spellcheck="false" /></label>
<label for="mps-service-token"><span>Startup token</span><input id="mps-service-token" type="password" autocomplete="off" spellcheck="false" placeholder="Paste the launcher token" /></label>
<button id="mps-connect" type="button">Connect exact 20-step engine</button>
</div>
<p id="mps-connection-status" role="status" aria-live="polite">Waiting for the authenticated local Mac service.</p>
</section>
<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>Exact Mac flow</strong><span>20 official fp32 steps · 40 MPS 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>