3D 模型批量处理自动化脚本,提升工作效率

0 阅读2分钟

问题背景: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 批量处理步骤

  1. 打开 Zipoly,进入"压缩优化"页面
  2. 点"选择文件夹"
  3. 选包含模型的根目录
  4. 软件会自动递归扫描所有 GLB/glTF 文件
  5. 设置压缩参数
  6. 点"开始优化" 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 "file"o"optimized/file" -o "optimized/(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 模型能明显提升工作效率:

  1. 小规模处理:用 Zipoly 的批量功能,简单直观
  2. 中等规模:用 gltf-pipeline/gltf-transform 命令行脚本
  3. 大规模/自动化:集成到 CI/CD 流程,每次提交自动优化