3D 布料物理模拟器
一个基于 Next.js 16 + Canvas 的实时 3D 布料物理模拟器,支持多种材质、场景模式和物理交互。
源代码:https://gitee.com/yanjianzhong007/clothSimulation
在线演示:https://z2p9jz49tp.coze.site/

功能特性
🎨 多种材质
- 丝绸 - 柔软飘逸,适合轻薄织物
- 棉布 - 中等硬度,日常织物
- 麻布 - 硬挺有型,适合厚织物
- 橡胶 - 高弹性,可拉伸回弹
🎬 四种场景模式
- 悬挂模式 - 顶部固定,自然下垂
- 旗帜模式 - 左侧固定,随风飘扬
- 降落伞模式 - 底部固定,向上飘动
- 自由模式 - 无固定点,自由漂浮
⚙️ 物理参数调节
- 重力强度
- 风力强度
- 风速度
- 阻尼系数
- 约束迭代次数
🎮 交互功能
- 鼠标拖拽 - 左键拖动布料任意位置
- 剪断布料 - 右键滑动剪断布料连接
- 触摸支持 - 移动端触摸操作
- 碰撞体交互 - 添加球体/立方体碰撞体,布料会自然包裹
🛠️ 实用工具
- 撤销/重做操作
- 截图保存
- 实时 FPS 监控
- 多种基础颜色选择
📊 网格密度
- 小(40×26)- 高性能
- 中(70×45)- 平衡模式
- 大(100×64)- 高精度
使用指南
基本操作
| 操作 | 说明 |
|---|---|
| 左键拖拽 | 抓取并移动布料 |
| 右键滑动 | 剪断布料连接线 |
| 滚轮 | 缩放视角 |
| 触摸拖拽 | 移动端抓取布料 |
| 双指缩放 | 移动端缩放 |
控制面板
控制面板位于屏幕右下角,包含三个标签页:
物理参数
- 场景模式 - 选择不同的布料悬挂方式
- 重力 - 调整布料下落速度
- 风力强度 - 调整风力大小
- 风速度 - 调整风速变化频率
- 阻尼 - 控制能量损失
- 约束迭代次数 - 物理模拟精度
视觉设置
- 材质 - 选择布料材质(丝绸、棉布、麻布、橡胶)
- 网格大小 - 调整布料密度
- 基础颜色 - 选择布料颜色
碰撞体
- 添加碰撞体 - 点击添加球体或立方体
- 碰撞体大小 - 调节碰撞体尺寸
- 清除所有碰撞体 - 移除所有碰撞体
底部操作按钮
- 重置 - 重置布料到初始状态
- 截图 - 保存当前画面
- 撤销 - 撤销上一步操作
- 重做 - 重做撤销的操作
技术架构
核心技术
- Next.js 16 - App Router,React Server Components
- React 19 - 最新特性
- TypeScript 5 - 严格类型检查
- Tailwind CSS 4 - 样式系统
- shadcn/ui - UI 组件库
- Canvas 2D API - 图形渲染
物理引擎
采用 Verlet 积分 实现布料物理模拟:
位置更新: x_new = 2*x - x_prev + a*dt²
约束求解: 满足距离约束的迭代算法
主要模块:
ClothPhysicsEngine- 物理计算引擎ClothRenderer- Canvas 渲染器FPSMonitor- 性能监控StateHistory- 状态历史(撤销/重做)
碰撞检测
- 球体碰撞 - 点与球体距离检测
- 立方体碰撞 - 点与立方体边界检测
- 包裹效果 - 布料自然包裹碰撞体表面
项目结构
src/
├── app/
│ ├── layout.tsx # 根布局
│ ├── page.tsx # 主页面(模拟器入口)
│ └── globals.css # 全局样式
├── components/
│ ├── ClothControlPanel.tsx # 控制面板组件
│ └── ui/ # shadcn/ui 组件
│ ├── badge.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── separator.tsx
│ └── slider.tsx
├── contexts/
│ └── SimulationContext.tsx # 全局状态管理
└── lib/
├── fps-monitor.tsx # FPS 监控
├── physics-engine.ts # 物理引擎
├── renderer.ts # 渲染器
├── simulation-config.ts # 配置定义
└── state-history.ts # 撤销/重做
开发规范
1. 组件开发
优先使用 shadcn/ui 基础组件
tsx
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Slider } from '@/components/ui/slider';
export function MyControl() {
return (
<Card>
<Slider value={[50]} onValueChange={([v]) => console.log(v)} />
<Button>操作</Button>
</Card>
);
}
2. 状态管理
使用 Context API 管理全局状态:
tsx
import { useSimulation } from '@/contexts/SimulationContext';
function MyComponent() {
const { config, updateConfig } = useSimulation();
return <div>{config.gravity}</div>;
}
3. 依赖管理
必须使用 pnpm
bash
npm install
npm run build
npm start
4. 样式开发
使用 Tailwind CSS:
tsx
<div className="flex items-center gap-4 p-4 rounded-lg bg-blue-950/80">
<span>内容</span>
</div>
性能优化
网格密度选择
- 小网格 - 40×26,适合低端设备
- 中网格 - 70×45,推荐使用
- 大网格 - 100×64,高精度,需要较好性能
物理参数调优
- 降低约束迭代次数可提高性能
- 增加阻尼可减少震荡,提高稳定性
- 降低网格密度可显著提升 FPS
浏览器兼容性
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- 支持触摸设备
License
MIT