@dgreenheck/three-pinata

中文文档
2.0.1发布于 2025/11/11MITTypeScriptESM + CJS零依赖近 30 天下载 2万

三.js 实时切碎和切片的图书馆.

中文使用文档
文档目录27 节
  1. 特征
  2. 现场直播
  3. 安装
  4. 快速启动
  5. API 参考
  6. 类
  7. 选项
  8. 用法实例
  9. 基本构造
  10. 与撞击点相断
  11. 折叠
  12. 简单分解
  13. 切开
  14. 使用回调
  15. 双重材料
  16. 重要要求
  17. Manifold/ 紧水网
  18. 物理整合
  19. 基础物理模式
  20. 性能提示
  21. 限制
  22. 大楼
  23. 运行演示
  24. 许可证
  25. 承认
  26. 支助
  27. 捐款

三边形

NPM Version NPM Downloads GitHub Repo stars X (formerly Twitter) Follow YouTube Channel Subscribers

实时网状断裂和切切为 三.js

三平纳塔是一个库,可以让你在浏览器中直接实时地断裂并切出3D meshes. 无论是建造一个破坏物理游戏,一个交互式的艺术作品,还是科学的可视化,三平纳塔都提供了你所需要的工具,以美地打破事物.

特征

  • 瓦罗诺伊断裂 - 有3D和2.5D模式的自然外观断裂模式
  • 基于影响的分裂 - 将碎片集中在撞击点周围,以进行现实的销毁
  • 折叠 - 碎裂可能再次被碎裂以逐步销毁(外部处理的生成跟踪)
  • 飞机切片 - 在当地或世界空间任意用飞机相撞
  • 双重材料 - 外部表面和内部断裂面分离材料
  • 自定义种子点 - 全面控制有定制的沃罗诺伊种子的断裂图案
  • 紫外线绘图 - 内部面相自动紫外线生成,可配置比例并抵消

现场直播

检查互动演示 : https://3-pinata-demo.vercel.app/ 维基百科中的相关条目: 维基文库中相关的原始文献: 维基文库中相关的原始文献: 维基文库中相关的原始文献: 维基文库中相关的原始文献: 维基文库中相关的原始文献: 维基文库中相关的原始文献: 维基文库中相关的原始文献: 维基语录

安装

npm install @dgreenheck/three-pinata

需要三.js 0.158.0作为同伴依赖.

快速启动

import * as THREE from "three";
import { DestructibleMesh, FractureOptions } from "@dgreenheck/three-pinata";

// Setup scene
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000,
);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Create materials
const outerMaterial = new THREE.MeshStandardMaterial({ color: 0x4a90e2 });
const innerMaterial = new THREE.MeshStandardMaterial({ color: 0xff6b6b });

// Create destructible mesh with both materials
const geometry = new THREE.SphereGeometry(1, 32, 32);
const mesh = new DestructibleMesh(geometry, outerMaterial, innerMaterial);
scene.add(mesh);

// Fracture the mesh
const options = new FractureOptions({
  fractureMethod: "voronoi",
  fragmentCount: 50,
  voronoiOptions: {
    mode: "3D",
  },
});
const fragments = mesh.fracture(options, (fragment) => {
  // Setup each fragment (material already set automatically)
  scene.add(fragment);
});

// Hide original mesh
mesh.visible = false;

// Render
renderer.render(scene, camera);

API 参考

类

DestructibleMesh

扩展 THREE.Mesh 具有内置断裂和切分能力.

构造器 :

new DestructibleMesh(
  geometry?: THREE.BufferGeometry,
  outerMaterial?: THREE.Material,
  innerMaterial?: THREE.Material
)

参数:

  • geometry - 网状的几何
  • outerMaterial - 原始外表面材料
  • innerMaterial - 用于新形成的内部断裂/切片面的材料(可选的,默认为外层材料)

方法:

fracture(options, onFragment?, onComplete?)

将网状断裂成碎片.

  • 参数:
    • options: FractureOptions - 断裂配置
    • onFragment?: (fragment: DestructibleMesh, index: number) => void - 每片可选回调
    • onComplete?: () => void - 断裂完成时可选回调
  • 回返情况: DestructibleMesh[] - 一堆碎块
slice(sliceNormal, sliceOrigin, options?, onSlice?, onComplete?)

沿着平面(局部空间)切片网.

  • 参数:
    • sliceNormal: THREE.Vector3 - 切片平面正常(局部空间)
    • sliceOrigin: THREE.Vector3 - 点在平面上(局部空间)
    • options?: SliceOptions - 切片配置
    • onSlice?: (piece: DestructibleMesh, index: number) => void 有选择的回叫每个作品
    • onComplete?: () => void - 切片完成后可选回调
  • 回返情况: DestructibleMesh[] - 一堆碎块
sliceWorld(worldNormal, worldOrigin, options?, onSlice?, onComplete?)

沿着平面(世界空间)剪接网.

  • 参数:
    • worldNormal: THREE.Vector3 - 切片平面正常(世界空间)
    • worldOrigin: THREE.Vector3 - 点在平面上(世界空间)
    • options?: SliceOptions - 切片配置
    • onSlice?: (piece: DestructibleMesh, index: number) => void 有选择的回叫每个作品
    • onComplete?: () => void - 切片完成后可选回调
  • 回返情况: DestructibleMesh[] - 一堆碎块
dispose()

处置网状几何和材料以释放记忆.

  • 参数: 无
  • 回返情况: void

选项

FractureOptions

分解操作的配置 。 既支持沃罗诺伊也支持简单的平面分解.

构造器 :

new FractureOptions({
  fractureMethod?: "voronoi" | "simple";
  fragmentCount?: number;
  voronoiOptions?: VoronoiOptions;
  fracturePlanes?: { x: boolean; y: boolean; z: boolean };
  textureScale?: THREE.Vector2;
  textureOffset?: THREE.Vector2;
  seed?: number;
})

属性 :

  • fractureMethod: "voronoi" | "simple" - 使用断裂法(默认:"voronoi")
    • "voronoi": 自然外观断裂,采用Voronii断裂法(需要voronoi options)
    • "simple": 简单平面分解(快速,质量较低)
  • fragmentCount: number - 要创建的碎片数( 默认: 50) 。 请注意,在分解出非凸起膜时,实际碎片计数可能更高.
  • voronoiOptions?: VoronoiOptions - Voronii特定选项(当断裂方法是"voronoi"时需要)
  • fracturePlanes: { x: boolean; y: boolean; z: boolean } - 简单的断裂:沿途由哪轴断裂(默认:全部为真)
  • textureScale: THREE.Vector2 - 内部面相的紫外尺度(默认:1,1)
  • textureOffset: THREE.Vector2 - 内部面相的紫外线抵消(默认:0,0)
  • seed?: number - 可复制的随机种子

VoronoiOptions

Voronoi特定断裂配置(在断裂选项中使用).

接口 :

{
  mode: "3D" | "2.5D";
  seedPoints?: THREE.Vector3[];
  impactPoint?: THREE.Vector3;
  impactRadius?: number;
  projectionAxis?: "x" | "y" | "z" | "auto";
  projectionNormal?: THREE.Vector3;
  useApproximation?: boolean;
  approximationNeighborCount?: number;
}

属性 :

  • mode: "3D" | "2.5D" - 沃罗诺伊断裂模式(需要)
    • "3D": 完整 3D Voranoi 切换 - 最现实, 慢
    • "2.5D": 2D Voronoi 通过网状投影 - 更快,对平面物体有利
  • seedPoints?: THREE.Vector3[] - 为当地空间的Voranoi细胞自定义种子点(如果不提供,则自动生成)
  • impactPoint?: THREE.Vector3 - 局部空间的撞击位置,以集中碎片
  • impactRadius?: number - 撞击点周围的半径为碎片密度
  • projectionAxis?: "x" | "y" | "z" | "auto" - 对于2.5D模式:投影轴(默认为"自动")
  • projectionNormal?: THREE.Vector3 - 2.5D模式:可选投影平面正常
  • useApproximation?: boolean - 使用 K 近邻 近似值进行性能( 默认: 假)
    • 警告: 启用时可能导致碎片重叠
  • approximationNeighborCount?: number - 使用近似值时应考虑的邻居(默认:12)

SliceOptions

切换操作配置 .

构造器 :

new SliceOptions();

属性 :

  • textureScale: THREE.Vector2 - 内部面相的紫外尺度(默认:1,1)
  • textureOffset: THREE.Vector2 - 内部面相的紫外线抵消(默认:0,0)

用法实例

基本构造

import { DestructibleMesh, FractureOptions } from "@dgreenheck/three-pinata";

const outerMaterial = new THREE.MeshStandardMaterial({ color: 0x4a90e2 });
const innerMaterial = new THREE.MeshStandardMaterial({ color: 0xff6b6b });

const mesh = new DestructibleMesh(geometry, outerMaterial, innerMaterial);
scene.add(mesh);

const options = new FractureOptions({
  fractureMethod: "voronoi",
  fragmentCount: 16,
  voronoiOptions: {
    mode: "3D",
  },
});
const fragments = mesh.fracture(options);

fragments.forEach((fragment) => scene.add(fragment));
mesh.visible = false;

与撞击点相断

const options = new FractureOptions({
  fractureMethod: "voronoi",
  fragmentCount: 16,
  voronoiOptions: {
    mode: "3D",
    impactPoint: new THREE.Vector3(0, 1, 0), // Local space
    impactRadius: 0.5, // Smaller = more concentrated
  },
});

const fragments = mesh.fracture(options);

折叠

裂口可再被分解为相继被破坏. 使用外部处理生成跟踪 userData数字 :

// Configuration
const maxGeneration = 3;
const fragmentCounts = {
  1: 32, // First fracture: 32 fragments
  2: 16, // Second fracture: 16 fragments
  3: 8,  // Third fracture: 8 fragments
};

// Initial fracture
const mesh = new DestructibleMesh(geometry, outerMaterial, innerMaterial);
mesh.userData.generation = 0; // Track generation externally

const options1 = new FractureOptions({
  fractureMethod: "voronoi",
  fragmentCount: fragmentCounts[1],
  voronoiOptions: {
    mode: "3D",
  },
});

const fragments = mesh.fracture(options1, (fragment) => {
  // Track generation in each fragment
  fragment.userData.generation = 1;
  scene.add(fragment);
});

// Later, refracture a fragment when clicked
function onFragmentClick(fragment: DestructibleMesh) {
  const currentGeneration = fragment.userData.generation || 0;

  // Check generation limit (external refracture control)
  if (currentGeneration >= maxGeneration) {
    return; // Max generation reached
  }

  // Determine fragment count for next generation
  const nextGeneration = currentGeneration + 1;
  const fragmentCount = fragmentCounts[nextGeneration];

  const options = new FractureOptions({
    fractureMethod: "voronoi",
    fragmentCount: fragmentCount,
    voronoiOptions: {
      mode: "3D",
    },
  });

  const newFragments = fragment.fracture(options, (newFragment) => {
    // Track generation externally
    newFragment.userData.generation = nextGeneration;
    scene.add(newFragment);
  });

  // Clean up old fragment
  scene.remove(fragment);
  fragment.geometry.dispose();
}

这种外部方法使你完全控制了折射行为,使你能够执行诸如:

  • 逐渐减弱(每代有羽毛碎片)
  • 以能为基础的再生(仅在撞击力超过阈值的情况下)
  • 基于材料的限度(玻璃折射量大于木材)
  • 基于性能的节流( FPS 下降时停止折叠)

简单分解

const options = new FractureOptions({
  fractureMethod: "simple",
  fragmentCount: 50,
  fracturePlanes: { x: true, y: true, z: true },
});

const fragments = mesh.fracture(options);

切开

// Create mesh with outer and inner materials
const mesh = new DestructibleMesh(geometry, outerMaterial, innerMaterial);

const sliceNormal = new THREE.Vector3(0, 1, 0); // Horizontal cut
const sliceOrigin = new THREE.Vector3(0, 0, 0); // At origin

const options = new SliceOptions();
const pieces = mesh.slice(sliceNormal, sliceOrigin, options);

// Materials are already set automatically
pieces.forEach((piece) => scene.add(piece));
mesh.visible = false;

使用回调

const mesh = new DestructibleMesh(geometry, outerMaterial, innerMaterial);

const fragments = mesh.fracture(
  options,
  (fragment, index) => {
    // Called for each fragment (materials already set)
    fragment.castShadow = true;

    // Add physics, apply forces, etc.
    physics.add(fragment, { type: "dynamic" });
  },
  () => {
    // Called when complete
    console.log("Fracturing complete!");
  },
);

双重材料

裂痕支撑了两种材料——一种用于原地表,一种用于内出裂面.

建议的办法: 将两种材料传递给构造器:

const outerMaterial = new THREE.MeshStandardMaterial({ color: 0xff6644 });
const innerMaterial = new THREE.MeshStandardMaterial({ color: 0xdddddd });

// Materials are automatically inherited by fragments
const mesh = new DestructibleMesh(geometry, outerMaterial, innerMaterial);

const fragments = mesh.fracture(options, (fragment) => {
  // Material array [outer, inner] is already set automatically
  scene.add(fragment);
});

备选案文: 手动设定每个碎片的材料:

const mesh = new DestructibleMesh(geometry, outerMaterial);

const fragments = mesh.fracture(options, (fragment) => {
  // Manually assign material array: [outer, inner]
  fragment.material = [outerMaterial, innerMaterial];
  scene.add(fragment);
});

碎片几何包括两个材料组:

  • 组 0 (材料Index 0):原始外表面面相
  • 第1组 (材料Index 1):新产生的内部断裂面

重要要求

Manifold/ 紧水网

图书馆要求 多重( 防水) meshes - 三维模型,形成一个完全封闭的,固态的体积,没有孔或自相交接几何.

有效网点:

  • 球形、立方体、圆柱形、圆锥形
  • 封闭字符模型
  • 适当建模无缺口的物体

无效的 meshes :

  • 平面或单面表面
  • 有洞或脸部缺失
  • 无限用气瓶或盒
  • 重叠几何

如何在 Blender 中检查/修复 :

  1. 在编辑模式中选择网格
  2. Mesh > Clean Up > Make Manifold
  3. 使用“ 3D 打印工具箱” 附加以检查问题

为什么这很重要:

  • 分解算法需要确定"内"对"外"
  • 非狂眼膜造成模糊不清 导致脸孔和视觉文物的缺失
  • 物理相撞器会与非磁性相撞的碎片发生不可预测的行为

物理整合

库只处理几何. 对于现实的破坏,与物理引擎融合如: 猛兽。 。 。 .

基础物理模式

import RAPIER from "@dimforge/rapier3d";

// Initialize physics world
await RAPIER.init();
const world = new RAPIER.World({ x: 0, y: -9.81, z: 0 });

// Add physics to fragments
const fragments = mesh.fracture(options, (fragment) => {
  // Create rigid body
  const rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic().setTranslation(
    fragment.position.x,
    fragment.position.y,
    fragment.position.z,
  );
  const rigidBody = world.createRigidBody(rigidBodyDesc);

  // Create convex hull collider
  const vertices = fragment.geometry.getAttribute("position").array;
  const colliderDesc = RAPIER.ColliderDesc.convexHull(vertices)
    .setRestitution(0.3)
    .setFriction(0.5);
  world.createCollider(colliderDesc, rigidBody);
});

// Update physics each frame
function animate() {
  world.step();
  // Sync Three.js objects with physics...
}

关于全面执行情况,见:

  • demo/src/physics/PhysicsWorld.ts - 完整的物理包装
  • demo/src/physics/PhysicsBody.ts - 物理人体包装器
  • demo/src/scenes/SmashingScene.ts - 现实世界的例子

性能提示

  • 碎片计数:10-50 碎片是最佳的. 100+ 可能导致慢设备滞后
  • 2.5D对3D: 在可能的情况下使用 2.5D 模式 - 明显更快
  • 断裂前: 提前断裂并保存碎片以立即销毁
  • 大约: 对于高分数(>50),启用 useApproximation (可能造成重叠)
  • 物理学:更多的碎片=更多的物理体. 破碎的碎片在安顿下来之后

限制

  • 管理要求: Meshes 必须是紧取水(没有孔或自相接几何)
  • 内存:每个片段都是一个新的几何. 为许多可毁物体制定相应的计划
  • 所需物理学: 库只处理几何 - 您必须添加物理集成

大楼

npm run build:lib

生成 :

  • three-pinata.es.js - ES模块
  • three-pinata.umd.js - UMD模块
  • 类型声明

运行演示

npm install
npm run dev

开放http://localhost:5173/ (中文(简体) )

许可证

本项目根据以下规定获得许可证: MIT 许可证。 。 。 .

承认

支助

对于错误或特性请求,请在 问题跟踪器。 。 。 .

捐款

欢迎捐款! 请提交一份拉出请求.

版本与发布记录

@dgreenheck/three-pinata 共发布 25 个版本,首次发布于 2025/03/04;过去 12 个月发布了 0 个版本。

版本发布日期距今
2.0.1latest2025/11/111 年前
2.0.02025/11/111 年前
1.0.52025/11/051 年前
1.0.42025/11/051 年前
1.0.32025/11/051 年前
1.0.22025/11/051 年前

关于 @dgreenheck/three-pinata 的常见问题

@dgreenheck/three-pinata 是什么?

三.js 实时切碎和切片的图书馆.

如何安装 @dgreenheck/three-pinata?

在项目目录运行 npm install @dgreenheck/three-pinata,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:three(>=0.158.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@dgreenheck/three-pinata 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dgreenheck/three-pinata 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@dgreenheck/three-pinata 可以商用吗?

@dgreenheck/three-pinata 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@dgreenheck/three-pinata 的下载量有多少?

根据 npm 官方下载统计,@dgreenheck/three-pinata 在 2026/10/12 – 2026/11/10 这 30 天内被下载 19,684 次,日均约 656 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dgreenheck/three-pinata 还在维护吗?

最新版本 2.0.1 发布于 2025/11/11(1 年前);至今共发布 25 个版本,其中过去 12 个月发布了 0 个;首次发布于 2025/03/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。