@pmx-three/three
v0.1.0
Published
Three.js adapter for @pmx-three/core
Maintainers
Readme
@pmx-three/three
@pmx-three/core 的 Three.js 适配层。。
安装
npm install @pmx-three/core @pmx-three/three three从 URL 加载
import * as THREE from 'three';
import { PmxLoader } from '@pmx-three/three';
const scene = new THREE.Scene();
const loader = new PmxLoader();
const controller = new AbortController();
const result = await loader.load('/models/miku/model.pmx', {
signal: controller.signal,
onProgress({ loaded, total, ratio }) {
console.log({ loaded, total, percent: Math.round(ratio * 100) });
},
});
scene.add(result.mesh);
console.log(result.pmx.metadata.name);
console.warn(result.warnings);加载器只创建模型对象。应用需自行配置 renderer、camera、灯光和渲染循环。
解析内存数据
const response = await fetch('/models/miku/model.pmx');
const buffer = await response.arrayBuffer();
const result = loader.parse(
buffer,
new URL('/models/miku/model.pmx', window.location.href),
);
scene.add(result.mesh);加载本地文件
import {
PmxLoader,
normalizePmxResourcePath,
} from '@pmx-three/three';
async function loadLocalModel(modelFile: File, files: File[]) {
const modelPath = normalizePmxResourcePath(
modelFile.webkitRelativePath || modelFile.name,
);
const modelDirectory = modelPath.slice(0, modelPath.lastIndexOf('/') + 1);
const resources = new Map(
files.map((file) => {
const path = normalizePmxResourcePath(
file.webkitRelativePath || file.name,
);
const relativePath = path.startsWith(modelDirectory)
? path.slice(modelDirectory.length)
: path;
return [relativePath, file] as const;
}),
);
return new PmxLoader().parse(
await modelFile.arrayBuffer(),
'https://local.invalid/model.pmx',
{ resourceFiles: resources },
);
}支持BMP、PNG、JPEG、TGA 与 WebP纹理格式。
返回结果与资源释放
load 和 parse 返回 PmxLoadResult:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| mesh | PmxMesh | 已绑定骨架的 THREE.SkinnedMesh |
| pmx | PmxModel | core 解析出的原始模型数据 |
| bones | THREE.Bone[] | 与 PMX 骨骼索引顺序一致的骨骼数组 |
| materials | THREE.MeshToonMaterial[] | 与 PMX 材质顺序一致的材质数组 |
| warnings | string[] | 纹理缺失或格式不支持等非致命问题 |
| objectUrls | string[] | 为本地 Blob 纹理创建的临时 URL |
模型不再使用时调用加载器释放相关 GPU 资源与 Object URL:
scene.remove(result.mesh);
loader.dispose(result);不要在仍有其他对象共享这些几何体、材质或纹理时调用 dispose。
API
| 导出 | 说明 |
| --- | --- |
| createPmxGeometry(pmx) | 创建坐标系已转换、包含材质组和蒙皮属性的 BufferGeometry |
| createPmxSkeleton(pmx) | 创建 bones、根骨骼数组与 THREE.Skeleton |
| createPmxMaterials(pmx, options) | 创建 MeshToonMaterial[] 并开始加载纹理 |
| getPmxMaterialUniforms(material) | 取得适配层注入的 PMX 材质 uniforms |
| createTextureLoader(...) | 创建支持 PMX 路径与本地资源映射的纹理加载函数 |
| createSharedToonTexture(index) | 生成内置共享 toon 渐变纹理 |
| normalizePmxResourcePath(path) | 规范化本地资源映射键名 |
createPmxMaterials 与 createTextureLoader 属于偏底层接口,其 options 需要由调用方维护 LoadingManager、warnings、resource files 和 object URLs。一般使用 PmxLoader 即可。
坐标与材质处理
- 几何体和骨骼的 Z 轴会取反,同时反转三角形绕序,以适配 Three.js 坐标系
- PMX 材质区间转换为
BufferGeometrygroups - 生成
skinIndex、skinWeight,并在存在附加 UV 时生成第一层pmxUv1 - 普通纹理、toon 纹理使用 sRGB;sphere map 支持乘算、加算和附加 UV 模式
- 原始 PMX 对象分别保存在
mesh.userData.pmx、bone.userData.pmx和material.userData.pmx
