Webphysics Avbd Engine

作者 reason-machines2384a003145a无许可证83 个星标收录于 2026年10月8日更新于 2026年10月8日仓库3个月前更新

WebGPU rigid-body/soft-body physics engine based on the AVBD (Augmented Vertex Block Descent) solver

AI 生成的概览

指导将实验性 WebGPU AVBD 刚体与软体物理引擎集成到浏览器项目中。

功能
该技能介绍 webphysics WebGPU 物理引擎,它实现了用于刚体和软体模拟的 AVBD 求解器。内容涵盖安装、项目结构、引擎初始化、添加刚体、关节和弹簧、推进模拟以及读取刚体状态用于渲染。还提供求解器配置模式、箱体堆叠和摆链等常见示例,以及故障排查说明。
适用场景
适用于在浏览器 WebGPU 项目中添加 GPU 加速的刚体或软体物理效果。适合使用 AVBD 求解器设置碰撞检测、约束、关节或弹簧,并调整模拟稳定性。
运行要求
需要支持 WebGPU 的浏览器(仅限 Chrome)、Node.js 18 或更高版本、npm,以及通过 navigator.gpu 获取的 GPUDevice。引擎需从代码仓库克隆并手动集成;该技能本身不附带脚本,仅为说明文档。

webphysics-avbd-engine

Skill by ara.so — Daily 2026 Skills collection.

What It Does

webphysics is an experimental WebGPU-accelerated rigid-body and soft-body physics engine implementing the AVBD (Augmented Vertex Block Descent) solver from Giles et al. (2025). It runs entirely on the GPU using WebGPU compute shaders and supports:

  • Rigid-body simulation with contacts, friction, and joints
  • GPU broad-phase collision detection via LBVH (Linear BVH)
  • Narrow-phase manifold generation with warm-start persistence
  • Graph-coloring-based parallel body solves
  • Springs and soft-body constraints
  • Body sleeping/diagnostics

Browser support: Chrome only (requires WebGPU). This is an experimental proof-of-concept, not a production library.

Installation & Setup

sh
git clone https://github.com/jure/webphysics.gitcd webphysicsnpm installnpm run dev        # development servernpm run build      # production build

The dev server typically starts at http://localhost:5173 (Vite-based).

Project Structure

src/├── physics/│   ├── PhysicsEngine.ts          # Main orchestration: substep loop, init, step│   └── gpu/│       ├── avbdState.ts          # Primal/dual solve, coloring, velocity finalization│       ├── broadPhase.ts         # LBVH broad-phase candidate generation│       ├── contactGeneration.ts  # Narrow-phase manifolds, per-body constraint lists│       ├── contactRecord.ts      # Warm-start state persistence│       └── avbdState.ts          # Inertial targets, primal init, iteration├── lvbh/│   └── GPULBVHBuilder.ts         # GPU LBVH construction└── ...

Core API Usage

Initializing the Physics Engine

typescript
import { PhysicsEngine } from './src/physics/PhysicsEngine';
// Requires an existing GPUDeviceconst adapter = await navigator.gpu.requestAdapter();const device = await adapter.requestDevice();
const engine = new PhysicsEngine(device);await engine.init();

Adding Rigid Bodies

typescript
// Add a static ground planeengine.addBody({  type: 'box',  position: [0, -1, 0],  rotation: [0, 0, 0, 1],   // quaternion [x, y, z, w]  halfExtents: [10, 0.5, 10],  mass: 0,                   // 0 = static/infinite mass  restitution: 0.3,  friction: 0.5,});
// Add a dynamic rigid boxengine.addBody({  type: 'box',  position: [0, 5, 0],  rotation: [0, 0, 0, 1],  halfExtents: [0.5, 0.5, 0.5],  mass: 1.0,  restitution: 0.2,  friction: 0.6,});

Stepping the Simulation

typescript
const TIMESTEP = 1 / 60;const SUBSTEPS = 10;
function gameLoop(dt: number) {  engine.step(dt, SUBSTEPS);  // Read back positions for rendering  const bodyStates = engine.getBodyStates();  renderBodies(bodyStates);  requestAnimationFrame(gameLoop);}requestAnimationFrame(gameLoop);

Reading Body State for Rendering

typescript
// After engine.step(), retrieve updated transformsconst states = engine.getBodyStates();for (const state of states) {  const { position, rotation, bodyIndex } = state;  // position: [x, y, z]  // rotation: quaternion [x, y, z, w]  updateMeshTransform(bodyIndex, position, rotation);}

Adding Joints / Constraints

typescript
// Distance joint between two bodiesengine.addJoint({  type: 'distance',  bodyA: 0,  bodyB: 1,  anchorA: [0, 0.5, 0],   // local-space anchor on body A  anchorB: [0, -0.5, 0],  // local-space anchor on body B  restLength: 1.0,  stiffness: 1e4,});

Adding Springs (Soft Bodies)

typescript
engine.addSpring({  bodyA: 2,  bodyB: 3,  anchorA: [0, 0, 0],  anchorB: [0, 0, 0],  restLength: 0.8,  stiffness: 500,  damping: 10,});

AVBD Pipeline Reference

The solver follows Algorithm 1 from the AVBD paper:

1. collision detection (x^t)      ↓2. broad phase (LBVH)         → src/lvbh/GPULBVHBuilder.ts      ↓3. narrow phase + warm start  → src/physics/gpu/contactGeneration.ts      ↓4. per-body constraint lists  → src/physics/gpu/avbdState.ts      ↓5. graph coloring             → src/physics/gpu/avbdState.ts      ↓6. inertial target y, primal init, warm-start α/γ      ↓7. [loop] colored primal body solve (approx Hessian)      ↓8. [loop] dual + stiffness update      ↓9. finalize velocities

Key files per stage:

StageFile
Orchestrationsrc/physics/PhysicsEngine.ts
Broad phasesrc/physics/gpu/broadPhase.ts
Narrow phasesrc/physics/gpu/contactGeneration.ts
Contact recordssrc/physics/gpu/contactRecord.ts
AVBD solvesrc/physics/gpu/avbdState.ts
LBVH buildersrc/lvbh/GPULBVHBuilder.ts

Configuration Patterns

Solver Parameters

typescript
// Passed during engine construction or stepengine.step(dt, substeps, {  gravity: [0, -9.81, 0],  iterations: 10,          // AVBD inner iterations per substep  restitutionThreshold: 1.0,});

Tuning Stability

  • Increase substeps (e.g., 20) for stiff stacks or fast-moving bodies
  • Increase iterations for better constraint convergence
  • Use mass: 0 for static bodies (never moves, acts as infinite mass)
  • Lower stiffness values for softer, more stable joints
  • Set restitution: 0 + high friction for non-bouncy stacking

Common Patterns

Stack of Boxes

typescript
const groundIndex = engine.addBody({  type: 'box',  position: [0, 0, 0],  halfExtents: [5, 0.25, 5],  mass: 0,  friction: 0.7,  restitution: 0.1,});
for (let i = 0; i < 8; i++) {  engine.addBody({    type: 'box',    position: [0, 0.5 + i * 1.05, 0],    halfExtents: [0.5, 0.5, 0.5],    mass: 1.0,    friction: 0.5,    restitution: 0.1,  });}

Pendulum Chain with Distance Joints

typescript
let prevIndex = engine.addBody({  type: 'box', position: [0, 5, 0],  halfExtents: [0.1, 0.1, 0.1], mass: 0,  friction: 0, restitution: 0,});
for (let i = 1; i <= 5; i++) {  const curr = engine.addBody({    type: 'box', position: [0, 5 - i, 0],    halfExtents: [0.15, 0.15, 0.15], mass: 1.0,    friction: 0.1, restitution: 0,  });  engine.addJoint({    type: 'distance',    bodyA: prevIndex, bodyB: curr,    anchorA: [0, -0.15, 0], anchorB: [0, 0.15, 0],    restLength: 0.7,    stiffness: 1e5,  });  prevIndex = curr;}

Integrate with Three.js Rendering

typescript
import * as THREE from 'three';
const meshes: THREE.Mesh[] = [];
function syncPhysicsToRender() {  const states = engine.getBodyStates();  states.forEach((state, i) => {    if (!meshes[i]) return;    meshes[i].position.set(...state.position);    meshes[i].quaternion.set(      state.rotation[0], state.rotation[1],      state.rotation[2], state.rotation[3]    );  });}
function animate() {  engine.step(1 / 60, 10);  syncPhysicsToRender();  renderer.render(scene, camera);  requestAnimationFrame(animate);}

Troubleshooting

WebGPU Not Available

Error: navigator.gpu is undefined
  • Only Chrome 113+ supports WebGPU by default
  • Enable via chrome://flags/#enable-unsafe-webgpu on older versions
  • Firefox/Safari do not currently support WebGPU

Simulation Explodes / Bodies Flying Off

  • Reduce timestep or increase substeps
  • Lower joint stiffness values
  • Ensure static bodies have mass: 0
  • Check that halfExtents are positive and non-zero

Bodies Sinking Through Ground

  • Increase iterations (try 15–20)
  • Increase substeps
  • Check collision shape sizing matches visual mesh

Performance Issues

  • This is a Chrome-only WebGPU project; GPU driver issues can cause slowdowns
  • Reduce body count or iteration count
  • Check chrome://gpu to ensure hardware acceleration is active

Build Errors

sh
# Ensure Node.js >= 18node --version# Clear cacherm -rf node_modules distnpm installnpm run build

Limitations & Roadmap Notes

  • Chrome only — no Firefox/Safari support yet
  • Not a drop-in npm package; must clone and integrate manually
  • Double-buffered position updates (for same-color conflict safety) not yet implemented — current path uses in-place colored body solve in avbdState.ts
  • Experimental API — breaking changes expected
  • No TypeScript type declarations exported for external use yet

References

来源与署名

来源:reason-machines/trending-skills位于skills/webphysics-avbd-engine提交2384a00

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架