Include all addon workspaces and vendored dependencies in image builds, and expose deploy time plus commit metadata on the home page. Amp-Thread-ID: https://ampcode.com/threads/T-01a033d4-0e44-708e-af0e-6166283416ff Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
276 lines
11 KiB
HTML
276 lines
11 KiB
HTML
<!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="#f7fbff" />
|
||
<meta
|
||
name="description"
|
||
content="Yawn is a WebGPU engine that starts with friendly scene handles and scales down to a programmable Rust/WASM render core."
|
||
/>
|
||
<title>Yawn — a WebGPU engine that grows with you</title>
|
||
<script src="/assets/theme.js"></script>
|
||
<link rel="stylesheet" href="/assets/site.css" />
|
||
<link rel="stylesheet" href="/assets/theme.css" />
|
||
<script type="module" src="/assets/site.js"></script>
|
||
<script>
|
||
console.log(__YAWN_DEPLOYMENT_LOG__);
|
||
</script>
|
||
</head>
|
||
<body>
|
||
<header class="site-header">
|
||
<a class="wordmark" href="/" aria-label="Yawn home">
|
||
<span class="wordmark-mark" aria-hidden="true"
|
||
><i></i><i></i><i></i
|
||
></span>
|
||
<span>Yawn</span>
|
||
</a>
|
||
<nav class="site-nav" aria-label="Main navigation">
|
||
<a href="/docs">Docs</a>
|
||
<a href="/playground">Playground</a>
|
||
<a href="https://git.heaust.org/heaust/yawn">Source</a>
|
||
</nav>
|
||
<select class="theme-select" data-theme-select aria-label="Color theme">
|
||
<option value="auto">Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
<a class="button button-small" href="/docs#first-scene">Get started</a>
|
||
</header>
|
||
|
||
<main>
|
||
<section class="hero section-shell">
|
||
<div class="hero-copy">
|
||
<div class="eyebrow"><span></span> WebGPU without the ceremony</div>
|
||
<h1>Start with a scene.<br />Scale into an engine.</h1>
|
||
<p class="hero-lede">
|
||
Yawn gives you approachable TypeScript handles on day one, direct
|
||
shared-memory performance when you need it, and a programmable
|
||
render core when your ideas outgrow conventions.
|
||
</p>
|
||
<div class="hero-actions">
|
||
<a class="button" href="/playground"
|
||
>Open the playground <span>→</span></a
|
||
>
|
||
<a class="button button-quiet" href="/docs#installation"
|
||
>Read the 5-minute setup</a
|
||
>
|
||
</div>
|
||
<div class="hero-note">
|
||
<span class="browser-dots" aria-hidden="true"
|
||
><i></i><i></i><i></i
|
||
></span>
|
||
Separate Core + Handles modules · No framework required · Rust/WASM
|
||
core
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hero-demo" aria-label="A short Yawn scene example">
|
||
<div class="demo-toolbar">
|
||
<span><i></i> app.ts</span>
|
||
<span class="demo-status"><i></i> 60 FPS</span>
|
||
</div>
|
||
<pre><code><span class="syntax-purple">import</span> { Scene, Mesh, PBRMaterial }
|
||
<span class="syntax-purple">from</span> <span class="syntax-green">"@yawn/handles"</span>;
|
||
|
||
<span class="syntax-purple">const</span> scene = <span class="syntax-purple">new</span> <span class="syntax-blue">Scene</span>(canvas);
|
||
<span class="syntax-purple">await</span> scene.ready;
|
||
|
||
<span class="syntax-purple">const</span> blue = <span class="syntax-purple">new</span> <span class="syntax-blue">PBRMaterial</span>(scene, {
|
||
baseColor: [<span class="syntax-orange">0.12</span>, <span class="syntax-orange">0.58</span>, <span class="syntax-orange">1</span>, <span class="syntax-orange">1</span>],
|
||
roughness: <span class="syntax-orange">0.35</span>,
|
||
});
|
||
|
||
<span class="syntax-purple">const</span> triangle = <span class="syntax-purple">new</span> <span class="syntax-blue">Mesh</span>(scene, {
|
||
material: blue,
|
||
vertexData: { positions, indices },
|
||
});</code></pre>
|
||
<div class="demo-preview" aria-hidden="true">
|
||
<div class="demo-grid"></div>
|
||
<div class="demo-glow"></div>
|
||
<div class="demo-triangle"></div>
|
||
<span>rendering on WebGPU</span>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="trust-strip" aria-label="Yawn principles">
|
||
<div><strong>One</strong><span>shared arena</span></div>
|
||
<div><strong>Zero</strong><span>messages for hot state</span></div>
|
||
<div>
|
||
<strong>Any</strong><span>render graph you can describe</span>
|
||
</div>
|
||
<div><strong>Small</strong><span>Rust/WASM foundation</span></div>
|
||
</section>
|
||
|
||
<section class="section-shell progression" id="progression">
|
||
<div class="section-heading">
|
||
<div class="eyebrow"><span></span> Progressive by design</div>
|
||
<h2>Use exactly as much engine as you need.</h2>
|
||
<p>
|
||
You do not have to choose between an easy API and a serious
|
||
foundation. Yawn keeps those layers separate, so learning more never
|
||
means starting over.
|
||
</p>
|
||
</div>
|
||
<div class="gear-grid">
|
||
<article class="gear-card gear-card-featured">
|
||
<div class="gear-number">01</div>
|
||
<div class="gear-icon"><span class="cube-icon"></span></div>
|
||
<h3>Build with handles</h3>
|
||
<p>
|
||
Start with familiar scenes, meshes, materials, lights, cameras,
|
||
glTF imports, and post effects. Constructors are explicit and
|
||
every async boundary is visible.
|
||
</p>
|
||
<a href="/docs#first-scene">Make your first scene <span>→</span></a>
|
||
</article>
|
||
<article class="gear-card">
|
||
<div class="gear-number">02</div>
|
||
<div class="gear-icon"><span class="rows-icon"></span></div>
|
||
<h3>Move through shared data</h3>
|
||
<p>
|
||
Positions, cameras, lights, materials, and your own application
|
||
rows live in one SharedArrayBuffer. Hot updates become direct
|
||
typed-array writes.
|
||
</p>
|
||
<a href="/docs#shared-memory"
|
||
>Understand the fast path <span>→</span></a
|
||
>
|
||
</article>
|
||
<article class="gear-card">
|
||
<div class="gear-number">03</div>
|
||
<div class="gear-icon"><span class="graph-icon"></span></div>
|
||
<h3>Author the whole graph</h3>
|
||
<p>
|
||
Use core directly when you need custom resources, WGSL pipelines,
|
||
compute, pass dependencies, transient aliasing, and up-front GPU
|
||
loadouts.
|
||
</p>
|
||
<a href="/docs#core-deep-dive">Go beneath handles <span>→</span></a>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="architecture-section">
|
||
<div class="section-shell architecture-grid">
|
||
<div class="architecture-copy">
|
||
<div class="eyebrow eyebrow-light">
|
||
<span></span> A quiet hot path
|
||
</div>
|
||
<h2>Your frame should move data, not negotiate it.</h2>
|
||
<p>
|
||
Yawn pays setup costs when your scene or graph changes. During
|
||
play, ordinary updates stay in shared rows that JavaScript and the
|
||
render worker can both see.
|
||
</p>
|
||
<ul class="check-list">
|
||
<li>
|
||
<span>✓</span> Structure-of-arrays layout with aligned rows
|
||
</li>
|
||
<li>
|
||
<span>✓</span> Render graphs compiled before they become active
|
||
</li>
|
||
<li>
|
||
<span>✓</span> Optional timestamp profiling for physical GPU
|
||
passes
|
||
</li>
|
||
</ul>
|
||
<a class="text-link-light" href="/docs#mental-model"
|
||
>See how the pieces connect →</a
|
||
>
|
||
</div>
|
||
<div class="architecture-visual" aria-label="Yawn data flow">
|
||
<div class="flow-label">Your application</div>
|
||
<div class="flow-nodes flow-top">
|
||
<span>handles</span><span>workers</span><span>game logic</span>
|
||
</div>
|
||
<div class="flow-line"><i></i><i></i><i></i></div>
|
||
<div class="arena-card">
|
||
<div>
|
||
<span></span><strong>SharedArrayBuffer</strong
|
||
><small>aligned SOA arena</small>
|
||
</div>
|
||
<div class="arena-rows">
|
||
<i></i><i></i><i></i><i></i><i></i><i></i>
|
||
</div>
|
||
</div>
|
||
<div class="flow-line flow-line-bottom"><i></i></div>
|
||
<div class="core-card">
|
||
<span>Rust / WASM</span><strong>Render graph core</strong>
|
||
</div>
|
||
<div class="gpu-line"></div>
|
||
<div class="gpu-card">WebGPU</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-shell steps-section">
|
||
<div class="section-heading section-heading-centered">
|
||
<div class="eyebrow"><span></span> From blank page to pixels</div>
|
||
<h2>A small API with visible boundaries.</h2>
|
||
</div>
|
||
<ol class="steps">
|
||
<li>
|
||
<span class="step-index">1</span>
|
||
<div>
|
||
<h3>Create a scene</h3>
|
||
<p>Give Yawn a canvas and await one clear readiness promise.</p>
|
||
</div>
|
||
<code>new Scene(canvas)</code>
|
||
</li>
|
||
<li>
|
||
<span class="step-index">2</span>
|
||
<div>
|
||
<h3>Add what you can see</h3>
|
||
<p>
|
||
Materials and meshes own typed handles, not hidden global state.
|
||
</p>
|
||
</div>
|
||
<code>new Mesh(scene, options)</code>
|
||
</li>
|
||
<li>
|
||
<span class="step-index">3</span>
|
||
<div>
|
||
<h3>Change values directly</h3>
|
||
<p>
|
||
After setup, ordinary property updates write into shared rows.
|
||
</p>
|
||
</div>
|
||
<code>mesh.position.x += 0.1</code>
|
||
</li>
|
||
</ol>
|
||
</section>
|
||
|
||
<section class="cta-section section-shell">
|
||
<div>
|
||
<div class="eyebrow eyebrow-light">
|
||
<span></span> The best way to understand it
|
||
</div>
|
||
<h2>Change the code. Watch the passes.</h2>
|
||
<p>
|
||
The playground includes TypeScript intelligence, reusable snippets,
|
||
live output, shareable SQLite-backed revisions, and the engine’s
|
||
real GPU profiler.
|
||
</p>
|
||
</div>
|
||
<a class="button button-white" href="/playground"
|
||
>Launch playground <span>↗</span></a
|
||
>
|
||
</section>
|
||
</main>
|
||
|
||
<footer class="site-footer section-shell">
|
||
<a class="wordmark" href="/"
|
||
><span class="wordmark-mark"><i></i><i></i><i></i></span
|
||
><span>Yawn</span></a
|
||
>
|
||
<p>Start obvious. Optimize deliberately.</p>
|
||
<nav aria-label="Footer navigation">
|
||
<a href="/docs">Docs</a><a href="/playground">Playground</a
|
||
><a href="https://git.heaust.org/heaust/yawn">Source</a>
|
||
</nav>
|
||
</footer>
|
||
</body>
|
||
</html>
|