stable-fast-3d-webgpu / index.html
coderofpears's picture
Deploy Stable Fast 3D WebGPU demo
227cca9 verified
Raw
History Blame Contribute Delete
7.73 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#111218" />
<meta
name="description"
content="Run Stable Fast 3D locally in your browser with WebGPU."
/>
<title>Stable Fast 3D · WebGPU</title>
<link rel="preconnect" href="https://huggingface.co" />
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="stylesheet" href="./styles.css" />
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.179.1/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.179.1/examples/jsm/"
}
}
</script>
</head>
<body>
<div class="page-shell">
<header class="topbar">
<a class="brand" href="https://huggingface.co/" target="_blank" rel="noreferrer">
<span class="brand-mark">hf</span>
<span>Hugging Face · Static Space</span>
</a>
<div class="topbar-meta">
<span class="status-dot" id="webgpu-dot"></span>
<span id="webgpu-label">Checking WebGPU…</span>
</div>
</header>
<main>
<section class="hero">
<div class="eyebrow"><span></span> STABLE FAST 3D / BROWSER LAB</div>
<h1>One image.<br /><em>One mesh.</em></h1>
<p class="hero-copy">
Reconstruct a clean, orbit-ready 3D asset from a single image —
locally, privately, and accelerated by your GPU.
</p>
<div class="hero-links">
<a href="https://huggingface.co/stabilityai/stable-fast-3d" target="_blank" rel="noreferrer">Original model ↗</a>
<a href="https://huggingface.co/needle-tools/SF3D-webgpu" target="_blank" rel="noreferrer">Browser export ↗</a>
</div>
</section>
<section class="workspace-grid">
<aside class="control-card card">
<div class="card-heading">
<div>
<span class="section-kicker">01 / INPUT</span>
<h2>Choose an image</h2>
</div>
<span class="mini-badge">512 × 512</span>
</div>
<label class="dropzone" id="dropzone" for="image-file">
<input id="image-file" type="file" accept="image/png,image/jpeg,image/webp" />
<div class="upload-icon"></div>
<strong>Drop an object image here</strong>
<span>PNG with transparency works best</span>
<span class="browse-link">Browse files</span>
</label>
<div class="preview-wrap is-hidden" id="preview-wrap">
<img id="input-preview" alt="Selected input" />
<div class="preview-label"><span id="preview-name">Input image</span><span id="preview-size"></span></div>
</div>
<button class="sample-button" id="sample-button" type="button">
<span>Try a sample</span><span class="sample-arrow"></span>
</button>
<label class="toggle-row">
<span class="toggle-copy">
<strong>Clean the background</strong>
<small>Transformers.js · WebGPU</small>
</span>
<input id="remove-background" type="checkbox" checked />
<span class="toggle-ui"></span>
</label>
<div class="tip-box">
<span class="tip-icon"></span>
<span>Use one centered object with good contrast. Transparent PNGs skip the cleanup model.</span>
</div>
<button class="primary-button" id="generate-button" type="button" disabled>
<span id="generate-label">Select an image</span>
<span class="button-arrow"></span>
</button>
</aside>
<section class="viewer-card card">
<div class="viewer-head">
<div>
<span class="section-kicker">02 / OUTPUT</span>
<h2>Inspect your mesh</h2>
</div>
<span class="live-badge"><i></i> LOCAL INFERENCE</span>
</div>
<div class="viewer-stage" id="viewer-stage">
<canvas id="viewer-canvas" aria-label="3D mesh viewer"></canvas>
<div class="viewer-empty" id="viewer-empty">
<div class="empty-orbit"></div>
<strong>Your mesh will appear here</strong>
<span>Drag to orbit · scroll to zoom</span>
</div>
<div class="viewer-progress is-hidden" id="viewer-progress">
<div class="progress-ring"><span id="progress-percent">0%</span></div>
<strong id="progress-title">Preparing pipeline</strong>
<span id="progress-detail">The first run downloads the model into your browser cache.</span>
</div>
<div class="viewer-error is-hidden" id="viewer-error">
<div class="error-icon">!</div>
<strong id="error-title">Something went wrong</strong>
<span id="error-detail"></span>
<button id="error-dismiss" type="button">Dismiss</button>
</div>
<div class="viewer-toolbar">
<button id="reset-view" type="button" title="Reset camera">Reset view</button>
<span id="mesh-stats">No mesh loaded</span>
</div>
</div>
<div class="viewer-foot">
<div class="metric"><span>RUNTIME</span><strong id="runtime-metric"></strong></div>
<div class="metric"><span>VERTICES</span><strong id="vertices-metric"></strong></div>
<div class="metric"><span>FACES</span><strong id="faces-metric"></strong></div>
<button class="download-button" id="download-button" type="button" disabled>
Download GLB <span></span>
</button>
</div>
</section>
</section>
<section class="how-section">
<div class="section-heading-row">
<div>
<span class="section-kicker">03 / UNDER THE HOOD</span>
<h2>Private by design</h2>
</div>
<p>No image leaves this tab. Models are fetched once, then cached by your browser.</p>
</div>
<div class="steps-grid">
<article class="step-card">
<span class="step-number">01</span>
<div class="step-icon"></div>
<h3>Prepare</h3>
<p>Optional foreground cleanup runs with Transformers.js on WebGPU.</p>
</article>
<article class="step-card step-accent">
<span class="step-number">02</span>
<div class="step-icon"></div>
<h3>Reconstruct</h3>
<p>SF3D’s ONNX graphs predict a triplane and decode its surface locally.</p>
</article>
<article class="step-card">
<span class="step-number">03</span>
<div class="step-icon"></div>
<h3>Explore</h3>
<p>Orbit the mesh, inspect its topology, and export a portable GLB.</p>
</article>
</div>
</section>
</main>
<footer class="footer">
<span>Powered by Stability AI · Stable Fast 3D Community License</span>
<span>WebGPU / Transformers.js / ONNX Runtime Web</span>
</footer>
</div>
<script type="module" src="./src/main.js"></script>
</body>
</html>