ralph-gpu作成者: vercel
Minimal WebGPU shader library for creative coding and real-time graphics. Provides fullscreen passes, particles, compute shaders, render targets, and ping-pong…
npx skills add https://github.com/vercel-labs/ralph-gpu --skill ralph-gpuralph-gpu
A minimal WebGPU shader library for creative coding and real-time graphics.
When to Use
Use this skill when:
- Building WebGPU shader effects, creative coding projects, or real-time graphics
- Working with fullscreen shader passes, particle systems, or compute shaders
- Need guidance on ralph-gpu API, render targets, or WGSL shader patterns
- Implementing GPU-accelerated simulations or visual effects
Installation
npm install ralph-gpu
# For TypeScript support:
npm install -D @webgpu/types
Core Concepts
| Concept | Description |
|---|---|
gpu | Module entry point for initialization |
ctx | GPU context — manages state and rendering |
pass | Fullscreen shader (fragment only, uses internal quad) |
material | Shader with custom vertex code (particles, geometry) |
target | Render target (offscreen texture) |
pingPong | Pair of render targets for iterative effects |
compute | Compute shader for GPU-parallel computation |
storage | Storage buffer for large data (particles, simulations) |
sampler | Custom texture sampler with explicit filtering/wrapping |
texture | Load images, canvases, video, or raw data as GPU textures |
Auto-Injected Globals
Every shader automatically has access to these uniforms:
struct Globals {
resolution: vec2f, // Current render target size in pixels
time: f32, // Seconds since init
deltaTime: f32, // Seconds since last frame
frame: u32, // Frame count since init
aspect: f32, // resolution.x / resolution.y
}
@group(0) @binding(0) var<uniform> globals: Globals;
Quick Start
import { gpu } from "ralph-gpu";
// Check support
if (!gpu.isSupported()) {
console.error("WebGPU not supported");
return;
}
// Initialize
const ctx = await gpu.init(canvas, { autoResize: true });
// Create fullscreen shader pass
const pass = ctx.pass(\`
@fragment
fn main(@builtin(position) pos: vec4f) -> @location(0) vec4f {
let uv = pos.xy / globals.resolution;
return vec4f(uv, sin(globals.time) * 0.5 + 0.5, 1.0);
}
\`);
// Render loop
function frame() {
pass.draw();
requestAnimationFrame(frame);
}
frame();
API Overview
Context Creation
const ctx = await gpu.init(canvas, {
autoResize?: boolean, // Auto-handle canvas sizing (default: false)
dpr?: number, // Device pixel ratio
debug?: boolean, // Enable debug mode
events?: { // Event tracking
enabled: boolean,
types?: string[],
historySize?: number
}
});
Fullscreen Passes
// Simple mode (auto-generated bindings)
const pass = ctx.pass(wgslCode, {
uTexture: someTarget,
color: [1, 0, 0],
intensity: 0.5
});
pass.set("intensity", 0.8); // Update uniforms
// Manual mode (explicit bindings)
const pass = ctx.pass(wgslCode, {
uniforms: {
myValue: { value: 1.0 }
}
});
pass.uniforms.myValue.value = 2.0;
Render Targets
const target = ctx.target(512, 512, {
format?: "rgba8unorm" | "rgba16float" | "r16float" | "rg16float",
filter?: "linear" | "nearest",
wrap?: "clamp" | "repeat" | "mirror",
usage?: "render" | "storage" | "both"
});
ctx.setTarget(target); // Render to target
ctx.setTarget(null); // Render to screen
Ping-Pong Buffers
const simulation = ctx.pingPong(128, 128, {
format: "rgba16float"
});
// In render loop:
uniforms.inputTex.value = simulation.read;
ctx.setTarget(simulation.write);
processPass.draw();
simulation.swap();
Particles (Instanced Quads)
const particles = ctx.particles(1000, {
shader: wgslCode, // Full vertex + fragment shader
bufferSize: 1000 * 16, // Buffer size in bytes
blend: "additive"
});
particles.write(particleData); // Float32Array
particles.draw();
Compute Shaders
const compute = ctx.compute(\`
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
// GPU computation
}
\`);
compute.storage("buffer", storageBuffer);
compute.dispatch(Math.ceil(count / 64));
Storage Buffers
const buffer = ctx.storage(byteSize);
buffer.write(new Float32Array([...]));
// Bind to shader
pass.storage("dataBuffer", buffer);
Texture Loading
// From URL (async)
const tex = await ctx.texture("image.png");
// From canvas / video / ImageBitmap (sync)
const tex = ctx.texture(canvas);
// From raw pixel data (sync)
const tex = ctx.texture(new Uint8Array(data), { width: 256, height: 256 });
// Options
const tex = await ctx.texture("photo.jpg", {
filter: "linear", // "linear" | "nearest"
wrap: "repeat", // "clamp" | "repeat" | "mirror"
format: "rgba8unorm", // GPU texture format
flipY: true, // Flip vertically on load
});
// Bind to shader (manual mode)
const pass = ctx.pass(shader, {
uniforms: {
uTex: { value: tex }, // .texture and .sampler auto-bound
}
});
// Update from live source (canvas, video)
tex.update(videoElement);
// Clean up
tex.dispose();
Important Notes
WGSL Alignment: array<vec3f> has 16-byte stride, not 12. Always pad to 16 bytes:
// Correct: [x, y, z, 0.0] per element
const buffer = ctx.storage(count * 16);
Particle Rendering: Use instanced quads, not point-list (WebGPU points are always 1px)
Texture References: Target references stay valid after resize — no need to update uniforms
Screen Readback: Cannot read pixels from screen, only from render targets
Examples
Full working examples extracted from the docs app:
- Simple Gradient — The simplest possible shader — map UV coordinates to colors. This creates a gradient from black (bottom-left) to cyan (top-right).
- Animated Wave — A glowing sine wave with custom uniforms. The wave animates over time using globals.time.
- Time-Based Color Cycling — A hypnotic pattern that cycles through colors over time. Combines time, distance, and angle for a mesmerizing effect.
- Raymarching Sphere — A basic 3D sphere rendered using raymarching. This demonstrates how to create 3D shapes and lighting entirely within a fragment shader.
- Perlin-style Noise — Layered fractional Brownian motion (fBm) noise. This technique is fundamental for generating procedural textures, terrain, and natural-looking patterns.
- Metaballs — Organic-looking "blobs" that merge together based on an implicit surface. This effect uses a distance-based field and a threshold to create smooth blending.
- Mandelbrot Set — The classic complex number fractal. This shader computes the set by iterating z = z² + c and mapping the escape time to vibrant colors.
- Alien Planet — A procedurally generated alien world with atmospheric scattering and an orbiting moon. Uses raymarching with fBm noise for terrain detail.
- Fluid Simulation — Real-time Navier-Stokes fluid simulation using ping-pong buffers, vorticity confinement, and pressure projection.
- Triangle Particles — GPU-driven particle system with SDF-based physics. 30,000 particles spawn on triangle edges and flow along a signed distance field with chromatic aberration postprocessing.
Resources
vercelのその他のスキル
agent-friendly-apis
by vercel
Companion skill for the Agent-Friendly APIs course on Vercel Academy. Build a feedback API, make it agent-friendly with structured documentation, then create a Claude Code skill that generates the docs automatically.
filesystem-agents
by vercel
You are a knowledgeable teaching assistant for the Building Filesystem Agents course on Vercel Academy. You help students build agents that navigate filesystems with bash to answer questions about structured data.
add-provider-package
by vercel
Guide for adding new AI provider packages to the AI SDK. Use when creating a new @ai-sdk/<provider> package to integrate an AI service into the SDK.
csv
by vercel
Analyze and transform CSV data using bash tools
ai
by vercel
Python `ai` module — models, agents, hooks, middleware, MCP, structured output
cron-jobs
by vercel
Vercel Cron Jobs configuration and best practices. Use when adding, editing, or debugging scheduled tasks in vercel.json.
frontend-design
by vercel
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts,…
vercel-react-best-practices
by vercel
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js…