问题背景:3D 模型怎么批量处理 Web3D 项目里经常要处理大量 3D 模型文件:格式转换、Draco / Meshopt 压缩、纹理调整。手动一个个改效率太低,100 个 GLB 文件手动处理要 4 小时。
本文解决 3D 模型批量处理问题,介绍三种方案:Zipoly GUI 批量功能(小白可用)、gltf-pipeline / gltf-transform 命令行脚本(Node.js)、Python pygltflib 自动化工作流,并附 GitHub Actions / GitLab CI 集成示例。
一、批量处理的需求场景 1.1 电商产品展示 • 数百个产品模型要统一压缩 • 不同产品用不同压缩级别 • 批量生成缩略图和预览 1.2 建筑可视化 • 整个园区的模型要拆分和优化 • 不同区域用不同 LOD 级别 • 批量转换格式 1.3 游戏资产 • 大量角色模型要统一规格 • 批量压缩纹理 • 生成多平台版本 二、Zipoly 批量处理功能 2.1 软件介绍 Zipoly(zipoly.netlify.app)是一款 Windows 桌面应用,支持格式转换、Draco/Meshopt 压缩和批量处理。
2.2 批量处理步骤
- 打开 Zipoly,进入"压缩优化"页面
- 点"选择文件夹"
- 选包含模型的根目录
- 软件会自动递归扫描所有 GLB/glTF 文件
- 设置压缩参数
- 点"开始优化" 2.3 参数设置 参数 说明 压缩引擎 Draco / Meshopt 压缩级别 1-10 纹理压缩 JPEG / WebP / KTX2 输出目录 原目录 / 自定义目录 三、命令行批量处理 3.1 gltf-pipeline Node.js 工具,适合集成到 CI/CD 流程:
安装
npm install -g gltf-pipeline
单个文件压缩
gltf-pipeline -i model.glb -o model_draco.glb --draco.compressionLevel 7
批量处理脚本(Node.js)
const { execSync } = require('child_process') const fs = require('fs') const path = require('path')
function processDirectory(dir) {
const files = fs.readdirSync(dir)
files.forEach(file => {
const fullPath = path.join(dir, file)
if (fs.statSync(fullPath).isDirectory()) {
processDirectory(fullPath)
} else if (file.endsWith('.glb')) {
const output = fullPath.replace('.glb', '_compressed.glb')
execSync(gltf-pipeline -i "${fullPath}" -o "${output}" --draco.compressionLevel 7)
console.log(Processed: ${file})
}
})
}
processDirectory('./models') 3.2 gltf-transform 更强大的命令行工具:
安装
npm install -g @gltf-transform/cli
优化单个文件
gltf-transform optimize input.glb output.glb --compress meshopt
批量处理(bash 脚本)
for file in *.glb; do gltf-transform optimize "file" "optimized_file" --compress meshopt done 四、Python 批量处理 4.1 pygltflib Python 库,适合数据处理和分析:
import pygltflib import os from pathlib import Path
def analyze_glb(file_path): gltf = pygltflib.GLTF2().load(file_path)
# 统计信息
vertices = 0
for mesh in gltf.meshes:
for primitive in mesh.primitives:
accessor_idx = primitive.attributes.POSITION
accessor = gltf.accessors[accessor_idx]
vertices += accessor.count
return {
'file': file_path,
'vertices': vertices,
'meshes': len(gltf.meshes),
'materials': len(gltf.materials)
}
批量分析
models_dir = Path('./models') for glb_file in models_dir.rglob('*.glb'): info = analyze_glb(str(glb_file)) print(f"{info['file']}: {info['vertices']} vertices, {info['meshes']} meshes") 4.2 自动化工作流 import subprocess import json from pathlib import Path
class ModelProcessor: def init(self, input_dir, output_dir): self.input_dir = Path(input_dir) self.output_dir = Path(output_dir) self.output_dir.mkdir(exist_ok=True)
def compress_model(self, input_file, compression='draco', level=7):
output_file = self.output_dir / input_file.name
cmd = [
'gltf-pipeline',
'-i', str(input_file),
'-o', str(output_file),
f'--{compression}.compressionLevel', str(level)
]
subprocess.run(cmd, check=True)
return output_file
def process_all(self):
results = []
for glb_file in self.input_dir.rglob('*.glb'):
try:
output = self.compress_model(glb_file)
results.append({
'input': str(glb_file),
'output': str(output),
'status': 'success'
})
except Exception as e:
results.append({
'input': str(glb_file),
'error': str(e),
'status': 'failed'
})
return results
使用示例
processor = ModelProcessor('./raw_models', './optimized_models') results = processor.process_all()
生成报告
with open('processing_report.json', 'w') as f: json.dump(results, f, indent=2) 五、CI/CD 集成 5.1 GitHub Actions name: Optimize 3D Models
on: push: paths: - 'models/**'
jobs: optimize: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install -g gltf-pipeline
- name: Optimize models
run: |
for file in models/*.glb; do
gltf-pipeline -i "$file" -o "optimized/${file##*/}" --draco.compressionLevel 7
done
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: optimized-models
path: optimized/
5.2 GitLab CI optimize-models: stage: build image: node:18 script: - npm install -g gltf-pipeline - for file in models/*.glb; do gltf-pipeline -i "(basename $file)" --draco.compressionLevel 7; done artifacts: paths: - optimized/ 六、性能对比 测试数据:100 个 GLB 文件,总计 2.3GB
处理方式 耗时 压缩后大小 手动处理 约 4 小时 - Zipoly 批量 15 分钟 420MB gltf-pipeline 脚本 25 分钟 450MB gltf-transform 脚本 20 分钟 430MB 方案对比速查表 批量处理 3D 模型能明显提升工作效率:
- 小规模处理:用 Zipoly 的批量功能,简单直观
- 中等规模:用 gltf-pipeline/gltf-transform 命令行脚本
- 大规模/自动化:集成到 CI/CD 流程,每次提交自动优化