diff --git a/README.md b/README.md index ad3d380..f101bf7 100644 --- a/README.md +++ b/README.md @@ -15,525 +15,53 @@ -**Motion GPU** is a minimalist WebGPU framework for writing Shadertoy-style fullscreen shaders in pure WGSL. It provides a framework-agnostic core with Svelte 5, React, and Vue adapters for building fragment-driven GPU programs and multi-pass rendering pipelines. The framework includes a minimal runtime loop, scheduler, and render graph tailored specifically for fullscreen shader execution, focusing on a narrow GPU workflow rather than general-purpose 3D rendering. +Motion GPU is a focused WebGPU library for fullscreen WGSL shaders. It gives you a +framework-neutral runtime and first-class adapters for Svelte, React, and Vue, without the scene +graph and 3D tooling of a general-purpose engine. ---- +Use it for shader-driven visuals, generative art, procedural textures, post-processing, feedback +effects, and GPU compute. Motion GPU handles the canvas, render loop, scheduling, and GPU resources +while your application owns the shaders and interaction. -# When to Use Motion GPU - -Motion GPU is designed for applications where the entire scene is driven by fullscreen shaders. - -Typical use cases include: - -- Shadertoy-style GPU experiments -- Generative art -- Procedural textures -- Multi-pass post-processing pipelines -- GPU simulations -- Shader editors and live-coding tools -- Interactive visual experiments - -If your application is primarily a fullscreen fragment shader pipeline, using a full 3D engine can add unnecessary complexity and bundle size. - ---- - -# Why Not Use Three.js? - -Three.js is a powerful general-purpose 3D engine. -Motion GPU focuses on a much narrower problem: running fullscreen WGSL shader pipelines. - -| Feature | Three.js | Motion GPU | -| ---------------- | --------------------- | --------------------------- | -| Scope | Full 3D engine | Fullscreen shader framework | -| Shader language | TSL / generated WGSL | Native WGSL | -| Bundle size | 186 kB (gzip) | 25.4 kB (gzip) | -| Rendering model | Scene graph | GPU pipeline | -| Shader pipeline | materials | explicit passes | -| Multi-pass | possible but indirect | first-class | -| Shader debugging | generated shaders | direct WGSL | - -Motion GPU is **not a replacement for Three.js**. - -Instead, it is designed for cases where a full 3D engine would be unnecessary overhead. - -**Note:** Bundle size figures are based on measurements from https://bundlejs.com/ - ---- - -# Core Workflow - -Motion GPU follows a simple three-step flow: - -1. Define an immutable material with `defineMaterial(...)`. -2. Render it with ``. -3. Drive runtime updates with `useFrame(...)`, `useMotionGPU()`, and `useTexture(...)`. - ---- - -# What This Package Includes - -- Fullscreen WebGPU renderer for WGSL fragment shaders -- Strict material contract and validation (`fn frag(uv: vec2f) -> vec4f`) -- Runtime uniform and texture updates without rebuilding the pipeline -- Frame scheduler with task ordering, stages, invalidation modes, diagnostics and profiling -- Render graph with built-in post-process passes: - - `ShaderPass` - - `BlitPass` - - `CopyPass` - -- Fragment feedback passes: - - `PingPongShaderPass` — iterative fullscreen fragment simulations with render-texture A/B alternation - -- GPU compute passes with explicit per-pass resource descriptors: - - `ComputePass` — dependency-scheduled, single-dispatch GPU workloads - - `PingPongComputePass` — iterative workloads with private texture A/B alternation - -- Named render targets for multi-pass pipelines -- Structured error normalization with built-in overlay UI and custom renderer support -- Advanced runtime API for namespaced shared user context and scheduler presets - ---- - -# Requirements - -- Svelte 5 is required only for the Svelte adapter entrypoints (`/svelte`, `/svelte/advanced`) -- React 19+ is required only for the React adapter entrypoints (`/react`, `/react/advanced`) -- Vue 3.5+ is required only for the Vue adapter entrypoints (`/vue`, `/vue/advanced`) -- A browser/runtime with WebGPU support -- Secure context (`https://` or `localhost`) - ---- - -# Installation +## Install ```bash -npm i @motion-core/motion-gpu -``` - ---- - -# AI Documentation - -MotionGPU documentation is also available for AI tools via [Context7](https://context7.com/motion-core/motion-gpu). - ---- - -# Quick Start - -## 1. Create a material and render it - -```svelte - - - -
- -
-``` - ---- - -### React equivalent - -```tsx -import { FragCanvas, defineMaterial } from '@motion-core/motion-gpu/react'; - -const material = defineMaterial({ - fragment: ` -fn frag(uv: vec2f) -> vec4f { - return vec4f(uv.x, uv.y, 0.25, 1.0); -} -` -}); - -export function App() { - return ( -
- -
- ); -} -``` - ---- - -## 2. Add animated uniforms via `useFrame` - -```svelte - - - - - - -``` - -```svelte - - -``` - -```tsx -import { useFrame } from '@motion-core/motion-gpu/react'; - -export function Runtime() { - useFrame((state) => { - state.setUniform('uTime', state.time); - }); - - return null; -} -``` - ---- - -## 3. Add a GPU compute pass - -```svelte - - - - - - -``` - -```tsx -import { FragCanvas, defineMaterial, ComputePass } from '@motion-core/motion-gpu/react'; - -const material = defineMaterial({ - fragment: ` -fn frag(uv: vec2f) -> vec4f { - let idx = u32(uv.x * 255.0); - let particle = particles[idx]; - return vec4f(particle.rgb, 1.0); -} -`, - storageBuffers: { - particles: { size: 4096, type: 'array', access: 'read-write' } - } -}); - -const simulate = new ComputePass({ - compute: ` -@compute @workgroup_size(64) -fn compute(@builtin(global_invocation_id) id: vec3u) { - let i = id.x; - let t = motiongpuFrame.time; - particles[i] = vec4f(sin(t + f32(i)), cos(t + f32(i)), 0.0, 1.0); -} -`, - resources: { - particles: { buffer: 'particles', access: 'storage-read-write' } - }, - dispatch: [16] -}); - -export function App() { - return ( -
- -
- ); -} -``` - ---- - -## 4. Add a fragment feedback pass - -Use `PingPongShaderPass` when the simulation is naturally expressed as a fullscreen fragment shader that reads the previous texture state and writes the next one. - -```svelte - - - - -``` - -```tsx -import { FragCanvas, PingPongShaderPass, defineMaterial } from '@motion-core/motion-gpu/react'; - -const feedbackShader = ` -fn frag(uv: vec2f) -> vec4f { - let previous = textureSampleLevel(motiongpuPrevious, motiongpuPreviousSampler, uv, 0.0); - let pulse = smoothstep(0.04, 0.0, distance(uv, vec2f(0.5))); - return max(previous * 0.96, vec4f(pulse, pulse * 0.4, 0.0, 1.0)); -} -`; - -const material = defineMaterial({ - fragment: ` -fn frag(uv: vec2f) -> vec4f { - return textureSample(uTrail, uTrailSampler, uv); -} -`, - textures: { - uTrail: { format: 'rgba16float', filter: 'linear' } - } -}); - -const trail = new PingPongShaderPass({ - fragment: feedbackShader, - target: 'uTrail', - width: 512, - height: 512, - format: 'rgba16float', - iterations: 4 -}); - -export function App() { - return ( -
- -
- ); -} -``` - ---- - -# Core Runtime Model - -## Material Phase (compile-time contract) - -`defineMaterial(...)` validates and freezes: - -- WGSL fragment source -- Uniform declarations -- Texture declarations -- Compile-time `defines` -- Shader `includes` -- Storage buffer declarations - -A deterministic material signature is generated from resolved shader/layout metadata. - ---- - -## Frame Phase (runtime updates) - -Inside `useFrame(...)` callbacks you update per-frame values: - -- `state.setUniform(name, value)` -- `state.setTexture(name, value)` -- `state.writeStorageBuffer(name, data, { offset? })` -- `state.readStorageBuffer(name)` — returns `Promise` -- `state.invalidate(token?)` -- `state.advance()` - ---- - -## Renderer Phase - -`FragCanvas` resolves material state, schedules tasks, and decides whether to render based on: - -- `renderMode` (`always`, `on-demand`, `manual`) -- invalidation / advance state -- `autoRender` - ---- - -# Hard Contracts and Validation Rules - -These are enforced by runtime validation. - -1. Material entrypoint must be: - -``` -fn frag(uv: vec2f) -> vec4f -``` - -2. Fragment and `ShaderPass` colors are authored as straight alpha. Motion GPU premultiplies only at final canvas presentation so internal render targets and pass inputs remain straight-alpha. - -3. `ShaderPass` fragment entrypoint must be: - -``` -fn shade(inputColor: vec4f, uv: vec2f) -> vec4f -``` - -4. `PingPongShaderPass` fragment entrypoint must be: - -``` -fn frag(uv: vec2f) -> vec4f -``` - -5. Material, `ShaderPass`, and `PingPongShaderPass` helper functions can read the current Y-up coordinates from `motiongpuFragment.uv`. Motion GPU declares it as invocation-local `var` state and assigns it immediately before calling the required entrypoint. It is not available in compute shaders and does not add a GPU binding or buffer. - -6. `PingPongShaderPass` `iterations` must be `>= 1`. Its `target` must reference a fragment-visible texture declared in `defineMaterial({ textures })` and must not be declared as a compute storage target. - -7. `useFrame()` and `useMotionGPU()` must be called inside `` subtree. - -8. You can only set uniforms/textures that were declared in `defineMaterial(...)`. - -9. Uniform/texture/include/define names must match WGSL-safe identifiers: - -``` -[A-Za-z_][A-Za-z0-9_]* +npm install @motion-core/motion-gpu ``` -10. `needsSwap: true` is valid only for `input: 'source'` and `output: 'target'`. - -11. Render passes cannot read from `input: 'canvas'`. - -12. `maxDelta` and profiling window must be finite and greater than `0`. +Import from the entry point that matches your application: -13. `ComputePass` shader must contain `@compute @workgroup_size(...)` and a `fn compute(...)` entrypoint with a `@builtin(global_invocation_id)` parameter. +| Application | Entry point | +| --------------------- | -------------------------------- | +| Framework-independent | `@motion-core/motion-gpu` | +| Svelte | `@motion-core/motion-gpu/svelte` | +| React | `@motion-core/motion-gpu/react` | +| Vue | `@motion-core/motion-gpu/vue` | -14. A compute shader receives only the bindings declared in its pass-local `resources` map. Map keys are WGSL aliases; descriptor values point to material keys or borrowed WebGPU resources and declare access. +## What you get -15. `PingPongComputePass` `iterations` must be `>= 1`. Its required `resources` map must contain one sampled `pingPong: 'read'` descriptor and one storage-write `pingPong: 'write'` descriptor for the same storage texture. +- Validated WGSL materials for fullscreen rendering +- Runtime updates for uniforms, textures, and storage buffers +- Render, feedback, and compute passes for multi-step GPU work +- Explicit render modes and a scheduler for frame-level control +- The same core API across Svelte, React, and Vue -16. Compute and fragment feedback passes do not participate in render pass slot routing (no `input`/`output`/`needsSwap`). Consecutive compute passes are dependency-scheduled from their resource read/write sets. +## Before you start -17. Storage buffer `size` must be `> 0` and a multiple of 4. Material-owned storage buffers must be declared in `defineMaterial({ storageBuffers })`. +Motion GPU needs WebGPU and a secure context such as HTTPS or localhost. It is built for fullscreen +shader and compute workflows. If your project needs meshes, cameras, lighting, or a scene graph, a +3D engine will be a better fit. ---- - -# Pipeline Rebuild Rules - -## Rebuilds renderer - -- Material signature changes (shader/layout/bindings) -- `FragCanvas` `color` pipeline option changes - ---- - -## Does not rebuild renderer - -- Runtime uniform value changes -- Runtime texture source changes -- `PingPongShaderPass.setFragment(...)` changes (only that pass pipeline is rebuilt on next render) -- Clear color changes -- Canvas resize (resources are resized/reallocated as needed) - ---- - -# Development - -Run from `packages/motion-gpu`: - -```bash -pnpm run build -pnpm run check -pnpm run test -pnpm run test:e2e -pnpm run lint -pnpm run format -``` - ---- - -## Performance - -```bash -pnpm run perf:core -pnpm run perf:core:check -pnpm run perf:core:baseline -pnpm run perf:runtime -pnpm run perf:runtime:check -pnpm run perf:runtime:baseline -pnpm run perf:gpu -pnpm run perf:gpu:check -pnpm run perf:gpu:baseline -pnpm run perf:gpu:headed -``` +## Documentation ---- +[Start with the installation guide](https://motion-gpu.dev/docs/getting-started), then use the +[full documentation](https://motion-gpu.dev/docs) for materials, shaders, passes, runtime behavior, +and API contracts. You can also explore complete applications in the +[playground](https://motion-gpu.dev/playground). -# License +AI tools can access the documentation through +[Context7](https://context7.com/motion-core/motion-gpu). -This project is licensed under the MIT License. +## License -See the `LICENSE` file for details. +Motion GPU is available under the [MIT License](./LICENSE). diff --git a/packages/motion-gpu/README.md b/packages/motion-gpu/README.md index 091a743..47e14cd 100644 --- a/packages/motion-gpu/README.md +++ b/packages/motion-gpu/README.md @@ -1,3 +1,7 @@ +
+

Motion GPU

+
+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) @@ -10,525 +14,53 @@
-**Motion GPU** is a minimalist WebGPU framework for writing Shadertoy-style fullscreen shaders in pure WGSL. It provides a framework-agnostic core with Svelte 5, React, and Vue adapters for building fragment-driven GPU programs and multi-pass rendering pipelines. The framework includes a minimal runtime loop, scheduler, and render graph tailored specifically for fullscreen shader execution, focusing on a narrow GPU workflow rather than general-purpose 3D rendering. - ---- - -# When to Use Motion GPU - -Motion GPU is designed for applications where the entire scene is driven by fullscreen shaders. - -Typical use cases include: - -- Shadertoy-style GPU experiments -- Generative art -- Procedural textures -- Multi-pass post-processing pipelines -- GPU simulations -- Shader editors and live-coding tools -- Interactive visual experiments - -If your application is primarily a fullscreen fragment shader pipeline, using a full 3D engine can add unnecessary complexity and bundle size. - ---- - -# Why Not Use Three.js? - -Three.js is a powerful general-purpose 3D engine. -Motion GPU focuses on a much narrower problem: running fullscreen WGSL shader pipelines. - -| Feature | Three.js | Motion GPU | -| ---------------- | --------------------- | --------------------------- | -| Scope | Full 3D engine | Fullscreen shader framework | -| Shader language | TSL / generated WGSL | Native WGSL | -| Bundle size | 186 kB (gzip) | 25.4 kB (gzip) | -| Rendering model | Scene graph | GPU pipeline | -| Shader pipeline | materials | explicit passes | -| Multi-pass | possible but indirect | first-class | -| Shader debugging | generated shaders | direct WGSL | - -Motion GPU is **not a replacement for Three.js**. - -Instead, it is designed for cases where a full 3D engine would be unnecessary overhead. - -**Note:** Bundle size figures are based on measurements from https://bundlejs.com/ - ---- - -# Core Workflow +Motion GPU is a focused WebGPU library for fullscreen WGSL shaders. It gives you a +framework-neutral runtime and first-class adapters for Svelte, React, and Vue, without the scene +graph and 3D tooling of a general-purpose engine. -Motion GPU follows a simple three-step flow: +Use it for shader-driven visuals, generative art, procedural textures, post-processing, feedback +effects, and GPU compute. Motion GPU handles the canvas, render loop, scheduling, and GPU resources +while your application owns the shaders and interaction. -1. Define an immutable material with `defineMaterial(...)`. -2. Render it with ``. -3. Drive runtime updates with `useFrame(...)`, `useMotionGPU()`, and `useTexture(...)`. - ---- - -# What This Package Includes - -- Fullscreen WebGPU renderer for WGSL fragment shaders -- Strict material contract and validation (`fn frag(uv: vec2f) -> vec4f`) -- Runtime uniform and texture updates without rebuilding the pipeline -- Frame scheduler with task ordering, stages, invalidation modes, diagnostics and profiling -- Render graph with built-in post-process passes: - - `ShaderPass` - - `BlitPass` - - `CopyPass` - -- Fragment feedback passes: - - `PingPongShaderPass` — iterative fullscreen fragment simulations with render-texture A/B alternation - -- GPU compute passes with explicit per-pass resource descriptors: - - `ComputePass` — dependency-scheduled, single-dispatch GPU workloads - - `PingPongComputePass` — iterative workloads with private texture A/B alternation - -- Named render targets for multi-pass pipelines -- Structured error normalization with built-in overlay UI and custom renderer support -- Advanced runtime API for namespaced shared user context and scheduler presets - ---- - -# Requirements - -- Svelte 5 is required only for the Svelte adapter entrypoints (`/svelte`, `/svelte/advanced`) -- React 19+ is required only for the React adapter entrypoints (`/react`, `/react/advanced`) -- Vue 3.5+ is required only for the Vue adapter entrypoints (`/vue`, `/vue/advanced`) -- A browser/runtime with WebGPU support -- Secure context (`https://` or `localhost`) - ---- - -# Installation +## Install ```bash -npm i @motion-core/motion-gpu -``` - ---- - -# AI Documentation - -MotionGPU documentation is also available for AI tools via [Context7](https://context7.com/motion-core/motion-gpu). - ---- - -# Quick Start - -## 1. Create a material and render it - -```svelte - - - -
- -
-``` - ---- - -### React equivalent - -```tsx -import { FragCanvas, defineMaterial } from '@motion-core/motion-gpu/react'; - -const material = defineMaterial({ - fragment: ` -fn frag(uv: vec2f) -> vec4f { - return vec4f(uv.x, uv.y, 0.25, 1.0); -} -` -}); - -export function App() { - return ( -
- -
- ); -} -``` - ---- - -## 2. Add animated uniforms via `useFrame` - -```svelte - - - - - - -``` - -```svelte - - -``` - -```tsx -import { useFrame } from '@motion-core/motion-gpu/react'; - -export function Runtime() { - useFrame((state) => { - state.setUniform('uTime', state.time); - }); - - return null; -} -``` - ---- - -## 3. Add a GPU compute pass - -```svelte - - - - - - +npm install @motion-core/motion-gpu ``` -```tsx -import { FragCanvas, defineMaterial, ComputePass } from '@motion-core/motion-gpu/react'; - -const material = defineMaterial({ - fragment: ` -fn frag(uv: vec2f) -> vec4f { - let idx = u32(uv.x * 255.0); - let particle = particles[idx]; - return vec4f(particle.rgb, 1.0); -} -`, - storageBuffers: { - particles: { size: 4096, type: 'array', access: 'read-write' } - } -}); - -const simulate = new ComputePass({ - compute: ` -@compute @workgroup_size(64) -fn compute(@builtin(global_invocation_id) id: vec3u) { - let i = id.x; - let t = motiongpuFrame.time; - particles[i] = vec4f(sin(t + f32(i)), cos(t + f32(i)), 0.0, 1.0); -} -`, - resources: { - particles: { buffer: 'particles', access: 'storage-read-write' } - }, - dispatch: [16] -}); - -export function App() { - return ( -
- -
- ); -} -``` - ---- - -## 4. Add a fragment feedback pass +Import from the entry point that matches your application: -Use `PingPongShaderPass` when the simulation is naturally expressed as a fullscreen fragment shader that reads the previous texture state and writes the next one. +| Application | Entry point | +| --------------------- | -------------------------------- | +| Framework-independent | `@motion-core/motion-gpu` | +| Svelte | `@motion-core/motion-gpu/svelte` | +| React | `@motion-core/motion-gpu/react` | +| Vue | `@motion-core/motion-gpu/vue` | -```svelte - - +Motion GPU needs WebGPU and a secure context such as HTTPS or localhost. It is built for fullscreen +shader and compute workflows. If your project needs meshes, cameras, lighting, or a scene graph, a +3D engine will be a better fit. - -``` - -```tsx -import { FragCanvas, PingPongShaderPass, defineMaterial } from '@motion-core/motion-gpu/react'; - -const feedbackShader = ` -fn frag(uv: vec2f) -> vec4f { - let previous = textureSampleLevel(motiongpuPrevious, motiongpuPreviousSampler, uv, 0.0); - let pulse = smoothstep(0.04, 0.0, distance(uv, vec2f(0.5))); - return max(previous * 0.96, vec4f(pulse, pulse * 0.4, 0.0, 1.0)); -} -`; - -const material = defineMaterial({ - fragment: ` -fn frag(uv: vec2f) -> vec4f { - return textureSample(uTrail, uTrailSampler, uv); -} -`, - textures: { - uTrail: { format: 'rgba16float', filter: 'linear' } - } -}); - -const trail = new PingPongShaderPass({ - fragment: feedbackShader, - target: 'uTrail', - width: 512, - height: 512, - format: 'rgba16float', - iterations: 4 -}); - -export function App() { - return ( -
- -
- ); -} -``` - ---- - -# Core Runtime Model - -## Material Phase (compile-time contract) - -`defineMaterial(...)` validates and freezes: - -- WGSL fragment source -- Uniform declarations -- Texture declarations -- Compile-time `defines` -- Shader `includes` -- Storage buffer declarations - -A deterministic material signature is generated from resolved shader/layout metadata. - ---- - -## Frame Phase (runtime updates) - -Inside `useFrame(...)` callbacks you update per-frame values: - -- `state.setUniform(name, value)` -- `state.setTexture(name, value)` -- `state.writeStorageBuffer(name, data, { offset? })` -- `state.readStorageBuffer(name)` — returns `Promise` -- `state.invalidate(token?)` -- `state.advance()` - ---- - -## Renderer Phase - -`FragCanvas` resolves material state, schedules tasks, and decides whether to render based on: - -- `renderMode` (`always`, `on-demand`, `manual`) -- invalidation / advance state -- `autoRender` - ---- - -# Hard Contracts and Validation Rules - -These are enforced by runtime validation. - -1. Material entrypoint must be: - -``` -fn frag(uv: vec2f) -> vec4f -``` - -2. Fragment and `ShaderPass` colors are authored as straight alpha. Motion GPU premultiplies only at final canvas presentation so internal render targets and pass inputs remain straight-alpha. - -3. `ShaderPass` fragment entrypoint must be: - -``` -fn shade(inputColor: vec4f, uv: vec2f) -> vec4f -``` - -4. `PingPongShaderPass` fragment entrypoint must be: - -``` -fn frag(uv: vec2f) -> vec4f -``` - -5. Material, `ShaderPass`, and `PingPongShaderPass` helper functions can read the current Y-up coordinates from `motiongpuFragment.uv`. Motion GPU declares it as invocation-local `var` state and assigns it immediately before calling the required entrypoint. It is not available in compute shaders and does not add a GPU binding or buffer. - -6. `PingPongShaderPass` `iterations` must be `>= 1`. Its `target` must reference a fragment-visible texture declared in `defineMaterial({ textures })` and must not be declared as a compute storage target. - -7. `useFrame()` and `useMotionGPU()` must be called inside `` subtree. - -8. You can only set uniforms/textures that were declared in `defineMaterial(...)`. - -9. Uniform/texture/include/define names must match WGSL-safe identifiers: - -``` -[A-Za-z_][A-Za-z0-9_]* -``` - -10. `needsSwap: true` is valid only for `input: 'source'` and `output: 'target'`. - -11. Render passes cannot read from `input: 'canvas'`. - -12. `maxDelta` and profiling window must be finite and greater than `0`. - -13. `ComputePass` shader must contain `@compute @workgroup_size(...)` and a `fn compute(...)` entrypoint with a `@builtin(global_invocation_id)` parameter. - -14. A compute shader receives only the bindings declared in its pass-local `resources` map. Map keys are WGSL aliases; descriptor values point to material keys or borrowed WebGPU resources and declare access. - -15. `PingPongComputePass` `iterations` must be `>= 1`. Its required `resources` map must contain one sampled `pingPong: 'read'` descriptor and one storage-write `pingPong: 'write'` descriptor for the same storage texture. - -16. Compute and fragment feedback passes do not participate in render pass slot routing (no `input`/`output`/`needsSwap`). Consecutive compute passes are dependency-scheduled from their resource read/write sets. - -17. Storage buffer `size` must be `> 0` and a multiple of 4. Material-owned storage buffers must be declared in `defineMaterial({ storageBuffers })`. - ---- - -# Pipeline Rebuild Rules - -## Rebuilds renderer - -- Material signature changes (shader/layout/bindings) -- `FragCanvas` `color` pipeline option changes - ---- - -## Does not rebuild renderer - -- Runtime uniform value changes -- Runtime texture source changes -- `PingPongShaderPass.setFragment(...)` changes (only that pass pipeline is rebuilt on next render) -- Clear color changes -- Canvas resize (resources are resized/reallocated as needed) - ---- - -# Development - -Run from `packages/motion-gpu`: - -```bash -pnpm run build -pnpm run check -pnpm run test -pnpm run test:e2e -pnpm run lint -pnpm run format -``` - ---- - -## Performance - -```bash -pnpm run perf:core -pnpm run perf:core:check -pnpm run perf:core:baseline -pnpm run perf:runtime -pnpm run perf:runtime:check -pnpm run perf:runtime:baseline -pnpm run perf:gpu -pnpm run perf:gpu:check -pnpm run perf:gpu:baseline -pnpm run perf:gpu:headed -``` +## Documentation ---- +[Start with the installation guide](https://motion-gpu.dev/docs/getting-started), then use the +[full documentation](https://motion-gpu.dev/docs) for materials, shaders, passes, runtime behavior, +and API contracts. You can also explore complete applications in the +[playground](https://motion-gpu.dev/playground). -# License +AI tools can access the documentation through +[Context7](https://context7.com/motion-core/motion-gpu). -This project is licensed under the MIT License. +## License -See the `LICENSE` file for details. +Motion GPU is available under the [MIT License](./LICENSE).