436 lines
7.4 KiB
Markdown
436 lines
7.4 KiB
Markdown
# compress-gltf-tools
|
||
|
||
这是从当前仓库里提取出来的一个 Node 20+ 模型处理子项目,用来在 Node 环境里直接处理 glTF / GLB 资源。
|
||
|
||
目前支持:
|
||
|
||
- glTF 模型压缩
|
||
- 压缩纹理转换:ASTC / PVRTC / ETC / S3TC / fallback
|
||
- 资源转 Base64
|
||
- glTF 打包成 GLB
|
||
- 一次输出多个纹理变体
|
||
|
||
## 安装
|
||
|
||
```bash
|
||
cd node-model-tools
|
||
npm install
|
||
```
|
||
|
||
## 构建
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
## 基本用法
|
||
|
||
```ts
|
||
import { processModel } from './dist';
|
||
|
||
const result = await processModel('../demo/assets/building/task_building_6.gltf', {
|
||
rootDir: '..',
|
||
outDir: './output',
|
||
compress: {
|
||
enabled: true
|
||
},
|
||
compressTextures: {
|
||
enabled: true,
|
||
quality: 'medium',
|
||
astc: { enabled: true },
|
||
pvrtc: { enabled: true },
|
||
fallback: { useRGBA4444: true, useRGB565: true }
|
||
},
|
||
glb: {
|
||
enabled: false
|
||
},
|
||
base64: {
|
||
enabled: false,
|
||
includeModel: false,
|
||
threshold: 1000
|
||
}
|
||
});
|
||
|
||
console.log(result.entries);
|
||
console.log(result.assets);
|
||
console.log(result.uploadFiles);
|
||
```
|
||
|
||
## `processModel(inputPath, options)` 参数说明
|
||
|
||
### `inputPath`
|
||
|
||
要处理的模型文件路径。
|
||
|
||
- 支持 `.gltf`
|
||
- 支持 `.glb`
|
||
|
||
示例:
|
||
|
||
```ts
|
||
'../demo/assets/building/task_building_6.gltf'
|
||
```
|
||
|
||
### `options`
|
||
|
||
处理选项对象。
|
||
|
||
#### `rootDir`
|
||
|
||
项目根目录,主要给内部处理中间目录和相对路径计算使用。
|
||
|
||
注意:
|
||
|
||
- 它现在不会再影响最终输出目录结构
|
||
- 它更像“当前项目根路径”的参考值
|
||
|
||
常见写法:
|
||
|
||
```ts
|
||
rootDir: process.cwd()
|
||
```
|
||
|
||
#### `outDir`
|
||
|
||
最终输出目录。
|
||
|
||
注意:
|
||
|
||
- 这里就是最终输出位置
|
||
- 不会再自动拼上输入模型原本的目录层级
|
||
|
||
例如输入:
|
||
|
||
```txt
|
||
../demo/assets/building/task_building_6.gltf
|
||
```
|
||
|
||
如果设置:
|
||
|
||
```ts
|
||
outDir: './output'
|
||
```
|
||
|
||
那么输出会直接写到:
|
||
|
||
```txt
|
||
./output
|
||
```
|
||
|
||
## `compress` 模型压缩配置
|
||
|
||
用于控制模型几何压缩。
|
||
|
||
```ts
|
||
compress: {
|
||
enabled: true,
|
||
excludes: [],
|
||
quantization: {}
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `enabled`:是否开启模型压缩
|
||
- `excludes`:排除规则,命中的文件不做模型压缩
|
||
- `quantization`:量化参数,传给模型压缩器
|
||
|
||
`quantization` 示例:
|
||
|
||
```ts
|
||
quantization: {
|
||
POSITION: 13,
|
||
NORMAL: 8,
|
||
TEXCOORD: 10
|
||
}
|
||
```
|
||
|
||
## `compressTextures` 纹理压缩配置
|
||
|
||
用于把纹理转换成压缩纹理格式,或者输出 fallback 版本。
|
||
|
||
```ts
|
||
compressTextures: {
|
||
enabled: true,
|
||
quality: 'medium',
|
||
excludes: [],
|
||
astc: { enabled: true },
|
||
pvrtc: { enabled: true },
|
||
etc: { enabled: false },
|
||
s3tc: { enabled: false },
|
||
fallback: {
|
||
useRGBA4444: true,
|
||
useRGB565: true
|
||
}
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `enabled`:是否开启纹理压缩链路
|
||
- `quality`:整体质量档位,可选 `high` / `medium` / `low`
|
||
- `excludes`:排除规则,命中的纹理不参与压缩
|
||
- `astc`:ASTC 配置
|
||
- `pvrtc`:PVRTC 配置
|
||
- `etc`:ETC 配置
|
||
- `s3tc`:S3TC 配置
|
||
- `fallback`:fallback 配置
|
||
|
||
### `astc / pvrtc / etc / s3tc` 子字段
|
||
|
||
这些编码器配置结构基本一致:
|
||
|
||
```ts
|
||
astc: {
|
||
enabled: true,
|
||
formatOpaque: 'ASTC_8x5',
|
||
formatTransparent: 'ASTC_6x6',
|
||
quality: 'astcmedium',
|
||
excludes: []
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `enabled`:是否启用该纹理格式输出
|
||
- `formatOpaque`:不透明纹理使用的压缩格式
|
||
- `formatTransparent`:透明纹理使用的压缩格式
|
||
- `quality`:该编码器自己的质量参数
|
||
- `excludes`:排除规则
|
||
|
||
### `fallback` 子字段
|
||
|
||
```ts
|
||
fallback: {
|
||
useRGBA4444: true,
|
||
useRGB565: true,
|
||
excludes: []
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `useRGBA4444`:透明图走 fallback 时是否标记为 `RGBA4444`
|
||
- `useRGB565`:不透明图走 fallback 时是否标记为 `RGB565`
|
||
- `excludes`:排除规则
|
||
|
||
补充说明:
|
||
|
||
- 当前 fallback 分支沿用老项目逻辑
|
||
- 它会输出 fallback 版本并写入 `Sein_textureImprove` 标记
|
||
- 但不会真正把 PNG 重新编码成低位格式图片
|
||
|
||
## `glb` 配置
|
||
|
||
用于控制是否把 glTF 打包成 GLB。
|
||
|
||
```ts
|
||
glb: {
|
||
enabled: true,
|
||
excludes: []
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `enabled`:是否输出 GLB
|
||
- `excludes`:排除规则,命中的资源保持分离
|
||
|
||
## `base64` 配置
|
||
|
||
用于把小资源直接转成 Base64 内联。
|
||
|
||
```ts
|
||
base64: {
|
||
enabled: true,
|
||
threshold: 1000,
|
||
includeModel: false,
|
||
excludes: []
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `enabled`:是否开启 Base64 内联
|
||
- `threshold`:小于这个字节数的资源才会转 Base64
|
||
- `includeModel`:是否允许把 glTF / GLB 本体也转成 Base64
|
||
- `excludes`:排除规则
|
||
|
||
## `processors` 配置
|
||
|
||
用于在写出资源前,自定义处理资源内容。
|
||
|
||
```ts
|
||
processors: [
|
||
{
|
||
test: /\\.bin$/,
|
||
async process({ data, filePath }) {
|
||
return data;
|
||
}
|
||
}
|
||
]
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `test`:匹配规则,命中的文件会进入这个处理器
|
||
- `process`:处理函数,接收 `{ data, filePath }`
|
||
|
||
其中:
|
||
|
||
- `data`:当前资源的二进制内容,类型是 `Buffer`
|
||
- `filePath`:当前资源路径
|
||
|
||
返回值必须是:
|
||
|
||
- `Promise<Buffer>`
|
||
|
||
## 排除规则 `excludes`
|
||
|
||
很多地方都支持 `excludes`。
|
||
|
||
它可以是:
|
||
|
||
- `RegExp`
|
||
- `(filePath: string) => boolean`
|
||
|
||
示例:
|
||
|
||
```ts
|
||
excludes: [
|
||
/normal/i,
|
||
filePath => filePath.endsWith('.mp3')
|
||
]
|
||
```
|
||
|
||
## 返回值说明
|
||
|
||
`processModel` 返回:
|
||
|
||
```ts
|
||
{
|
||
inputPath,
|
||
outDir,
|
||
entries,
|
||
assets,
|
||
uploadFiles
|
||
}
|
||
```
|
||
|
||
### `inputPath`
|
||
|
||
本次处理的输入模型绝对路径。
|
||
|
||
### `outDir`
|
||
|
||
本次实际使用的输出目录绝对路径。
|
||
|
||
### `entries`
|
||
|
||
模型主输出列表。每个元素代表一个模型变体。
|
||
|
||
单个元素结构:
|
||
|
||
```ts
|
||
{
|
||
name,
|
||
variant,
|
||
type,
|
||
required,
|
||
url,
|
||
outputPath
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `name`:模型名,不带扩展名
|
||
- `variant`:变体名,例如 `normal` / `astc` / `fallback`
|
||
- `type`:输出类型,`gltf` 或 `glb`
|
||
- `required`:该变体依赖的纹理扩展
|
||
- `url`:输出文件名或相对路径
|
||
- `outputPath`:实际输出文件绝对路径
|
||
|
||
### `assets`
|
||
|
||
附属资源输出列表,比如:
|
||
|
||
- `.bin`
|
||
- `.png`
|
||
- `.ktx`
|
||
- 被内联成 Base64 的资源
|
||
|
||
单个元素结构:
|
||
|
||
```ts
|
||
{
|
||
sourcePath,
|
||
distPath,
|
||
outputPath,
|
||
url,
|
||
inlined
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `sourcePath`:原始资源路径
|
||
- `distPath`:相对输出路径
|
||
- `outputPath`:实际输出文件绝对路径
|
||
- `url`:相对输出路径,或者 Base64 字符串
|
||
- `inlined`:是否被内联成 Base64
|
||
|
||
### `uploadFiles`
|
||
|
||
专门整理好的“待上传文件数组”。
|
||
|
||
特点:
|
||
|
||
- 只包含真实写到磁盘的文件
|
||
- 不包含被 Base64 内联的资源
|
||
- 适合你后续直接遍历上传 OSS
|
||
|
||
单个元素结构:
|
||
|
||
```ts
|
||
{
|
||
sourcePath,
|
||
relativePath,
|
||
outputPath,
|
||
fileName,
|
||
mimeType,
|
||
size
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `sourcePath`:原始来源文件路径
|
||
- `relativePath`:输出相对路径,可直接作为上传 key 的基础值
|
||
- `outputPath`:本地输出文件绝对路径
|
||
- `fileName`:输出文件名
|
||
- `mimeType`:文件 MIME 类型
|
||
- `size`:文件大小,单位字节
|
||
|
||
示例:
|
||
|
||
```ts
|
||
for (const file of result.uploadFiles) {
|
||
console.log(file.relativePath, file.outputPath);
|
||
}
|
||
```
|
||
|
||
## 处理后的 generator
|
||
|
||
处理后的 glTF 资产会统一写入:
|
||
|
||
```json
|
||
"generator": "XOSMO Toolkit"
|
||
```
|
||
|
||
## 额外说明
|
||
|
||
- 如果输入是 `.glb`,不会走 glTF 贴图引用改写流程
|
||
- 如果同时开启纹理压缩,会按配置输出多个变体
|
||
- 某些压缩纹理格式在磁盘上不一定比原图更小,但它们的目标主要是运行时显存和采样性能
|