关于 blender-web-pipeline
blender-web-pipeline 是将 Blender 模型和动画导出为适合网页使用格式的技能指南,主要围绕 glTF 2.0。它面向资产制作与 Web 3D 流程,涵盖 Python 自动化、批量处理和模型优化。
主要功能
- 01导出并优化 glTF 2.0
- 02使用 Python(bpy)自动化
- 03批量处理 Blender 文件
- 04纹理烘焙与压缩
- 05生成 LOD 模型
- 06优化几何体和材质
适用场景
- 01将 Blender 资产导出为 GLB
- 02批量转换 3D 模型
- 03为网页交付优化模型与纹理
- 04搭建 Web 3D 资产生产流程
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ freshtechbro/ claudedesignskills --skill blender-web-pipeline安装后在 Claude Code 中输入/blender-web-pipeline确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/README.mdreferences/bpy_api_reference.mdgltf_export_guide.mdoptimization_strategies.mdscripts/batch_export.pygenerate_lods.pyoptimize_model.py详细介绍
Blender Web Pipeline
概述
Blender Web Pipeline 技能提供了将 3D 模型和动画从 Blender 导出为适合 Web 的格式(主要是 glTF 2.0)的工作流。内容涵盖用于批量处理的 Python 脚本、提升 Web 性能的优化技术,以及与 Three.js 和 Babylon.js 等 Web 3D 库的集成。
适用场景:
- 为 Web 应用导出 Blender 模型
- 批量处理多个 3D 资源
- 优化文件大小以便通过 Web 交付
- 自动执行重复的 Blender 任务
- 为 3D Web 内容创建生产流水线
- 将旧格式转换为 glTF
主要功能:
- 支持优化的 glTF 2.0 导出
- Python(bpy)自动化脚本
- 纹理烘焙与压缩
- LOD(细节层次)生成
- 批量处理工作流
- 面向 Web 的材质与光照优化
核心概念
glTF 2.0 格式
为什么选择 glTF 用于 Web:
- Web 领域的行业标准 3D 格式
- 高效的二进制编码(.glb)
- 支持 PBR 材质
- 支持动画和蒙皮
- 可通过自定义数据扩展
- 库支持广泛(Three.js、Babylon.js 等)
glTF 与 GLB 的区别:
.gltf = JSON + external .bin + external textures
.glb = Single binary file (recommended for web)
Blender Python API(bpy)
通过 Python 访问 Blender 数据和操作:
import bpy
# Access scene data
scene = bpy.context.scene
objects = bpy.data.objects
# Modify objects
obj = bpy.data.objects['Cube']
obj.location = (0, 0, 1)
obj.scale = (2, 2, 2)
# Export glTF
bpy.ops.export_scene.gltf(
filepath='/path/to/model.glb',
export_format='GLB'
)
Web 优化目标
目标指标:
- 文件大小:每个模型 <5 MB(理想值 <1 MB)
- 多边形数量:实时使用时 <50k 个三角形
- 纹理分辨率:最高 2048x2048(优先使用 1024x1024)
- 绘制调用:通过纹理图集尽量减少
- 加载时间:在平均网络连接下 <2 秒
常见模式
1. 基本 glTF 导出(手动)
# Blender Python Console or script
import bpy
# Select objects to export (optional - exports all if none selected)
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects['MyModel'].select_set(True)
# Export as GLB
bpy.ops.export_scene.gltf(
filepath='/path/to/output.glb',
export_format='GLB', # Binary format
use_selection=True, # Export selected only
export_apply=True, # Apply modifiers
export_texcoords=True, # UV coordinates
export_normals=True, # Normals
export_materials='EXPORT', # Export materials
export_colors=True, # Vertex colors
export_cameras=False, # Skip cameras
export_lights=False, # Skip lights
export_animations=True, # Include animations
export_draco_mesh_compression_enable=True, # Compress geometry
export_draco_mesh_compression_level=6, # 0-10 (6 recommended)
export_draco_position_quantization=14, # 8-14 bits
export_draco_normal_quantization=10, # 8-10 bits
export_draco_texcoord_quantization=12 # 8-12 bits
)
2. 用于批量导出的 Python 脚本
#!/usr/bin/env blender --background --python
"""
Batch export all .blend files in a directory to glTF
Usage: blender --background --python batch_export.py -- /path/to/blend/files
"""
import bpy
import os
import sys
# Get command line arguments after --
argv = sys.argv
argv = argv[argv.index("--") + 1:] if "--" in argv else []
input_dir = argv[0] if argv else "/path/to/models"
output_dir = argv[1] if len(argv) > 1 else input_dir + "_gltf"
# Create output directory
os.makedirs(output_dir, exist_ok=True)
# Find all .blend files
blend_files = [f for f in os.listdir(input_dir) if f.endswith('.blend')]
print(f"Found {len(blend_files)} .blend files")
for blend_file in blend_files:
input_path = os.path.join(input_dir, blend_file)
output_name = blend_file.replace('.blend', '.glb')
output_path = os.path.join(output_dir, output_name)
print(f"Processing: {blend_file}")
# Open blend file
bpy.ops.wm.open_mainfile(filepath=input_path)
# Export as GLB with optimizations
bpy.ops.export_scene.gltf(
filepath=output_path,
export_format='GLB',
export_apply=True,
export_draco_mesh_compression_enable=True,
export_draco_mesh_compression_level=6
)
print(f" Exported: {output_name}")
print("Batch export complete!")
运行批处理脚本:
blender --background --python batch_export.py -- /models/source /models/output
3. 优化面向 Web 的模型(简化)
import bpy
def optimize_mesh(obj, target_ratio=0.5):
"""Reduce polygon count using decimation modifier."""
if obj.type != 'MESH':
return
# Add Decimate modifier
decimate = obj.modifiers.new(name='Decimate', type='DECIMATE')
decimate.ratio = target_ratio # 0.5 = 50% of original polygons
decimate.use_collapse_triangulate = True
# Apply modifier
bpy.context.view_layer.objects.active = obj
bpy.ops.object.modifier_apply(modifier='Decimate')
print(f"Optimized {obj.name}: {len(obj.data.polygons)} polygons")
# Optimize all selected meshes
for obj in bpy.context.selected_objects:
optimize_mesh(obj, target_ratio=0.3)
4. 面向 Web 的纹理烘焙
import bpy
def bake_textures(obj, resolution=1024):
"""Bake all materials to single texture."""
# Setup bake settings
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.bake_type = 'COMBINED'
# Create bake image
bake_image = bpy.data.images.new(
name=f"{obj.name}_bake",
width=resolution,
height=resolution
)
# Create bake material
mat = bpy.data.materials.new(name=f"{obj.name}_baked")
mat.use_nodes = True
nodes = mat.node_tree.nodes
# Add Image Texture node
tex_node = nodes.new(type='ShaderNodeTexImage')
tex_node.image = bake_image
tex_node.select = True
nodes.active = tex_node
# Assign material
if obj.data.materials:
obj.data.materials[0] = mat
else:
obj.data.materials.append(mat)
# Select object
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
# Bake
bpy.ops.object.bake(type='COMBINED')
# Save baked texture
bake_image.filepath_raw = f"/tmp/{obj.name}_bake.png"
bake_image.file_format = 'PNG'
bake_image.save()
print(f"Baked {obj.name} to {bake_image.filepath_raw}")
# Bake selected objects
for obj in bpy.context.selected_objects:
if obj.type == 'MESH':
bake_textures(obj, resolution=2048)
5. 生成 LOD(细节层次)
import bpy
def generate_lods(obj, lod_levels=[0.75, 0.5, 0.25]):
"""Generate LOD copies with decreasing polygon counts."""
lod_objects = []
for i, ratio in enumerate(lod_levels):
# Duplicate object
lod_obj = obj.copy()
lod_obj.data = obj.data.copy()
lod_obj.name = f"{obj.name}_LOD{i}"
# Link to scene
bpy.context.collection.objects.link(lod_obj)
# Add Decimate modifier
decimate = lod_obj.modifiers.new(name='Decimate', type='DECIMATE')
decimate.ratio = ratio
# Apply modifier
bpy.context.view_layer.objects.active = lod_obj
bpy.ops.object.modifier_apply(modifier='Decimate')
lod_objects.append(lod_obj)
print(f"Created {lod_obj.name}: {len(lod_obj.data.polygons)} polygons")
return lod_objects
# Generate LODs for selected object
if bpy.context.active_object:
generate_lods(bpy.context.active_object)
6. 使用纹理压缩导出
import bpy
import os
def export_optimized_gltf(filepath, texture_max_size=1024):
"""Export glTF with downscaled textures."""
# Downscale all textures
for img in bpy.data.images:
if img.size[0] > texture_max_size or img.size[1] > texture_max_size:
img.scale(texture_max_size, texture_max_size)
print(f"Downscaled {img.name} to {texture_max_size}x{texture_max_size}")
# Export with Draco compression
bpy.ops.export_scene.gltf(
filepath=filepath,
export_format='GLB',
export_apply=True,
export_image_format='JPEG', # JPEG for smaller size (or PNG for quality)
export_jpeg_quality=85, # 0-100
export_draco_mesh_compression_enable=True,
export_draco_mesh_compression_level=8, # Max compression
export_draco_position_quantization=12,
export_draco_normal_quantization=8,
export_draco_texcoord_quantization=10
)
# Export optimized
export_optimized_gltf('/path/to/optimized.glb', texture_max_size=512)
7. 命令行自动化
#!/bin/bash
# Batch export Blender files to glTF without opening GUI
SCRIPT_DIR="$(dirname "$0")"
# Export all .blend files in current directory
for blend_file in *.blend; do
echo "Exporting $blend_file..."
blender --background "$blend_file" --python - <<EOF
import bpy
import os
# Get output filename
filename = os.path.splitext(bpy.data.filepath)[0]
output = filename + '.glb'
# Export
bpy.ops.export_scene.gltf(
filepath=output,
export_format='GLB',
export_apply=True,
export_draco_mesh_compression_enable=True,
export_draco_mesh_compression_level=6
)
print(f'Exported to {output}')
EOF
done
echo "All files exported!"
集成模式
与 Three.js 集成
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
const loader = new GLTFLoader();
// Setup Draco decoder for compressed models
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
loader.setDRACOLoader(dracoLoader);
// Load Blender export
loader.load('/models/exported.glb', (gltf) => {
scene.add(gltf.scene);
// Play animations
if (gltf.animations.length > 0) {
const mixer = new THREE.AnimationMixer(gltf.scene);
const action = mixer.clipAction(gltf.animations[0]);
action.play();
}
});
与 React Three Fiber 集成
import { useGLTF } from '@react-three/drei';
function Model() {
const { scene } = useGLTF('/models/exported.glb');
return <primitive object={scene} />;
}
// Preload for better performance
useGLTF.preload('/models/exported.glb');
与 Babylon.js 集成
import * as BABYLON from '@babylonjs/core';
import '@babylonjs/loaders/glTF';
BABYLON.SceneLoader.ImportMesh(
'',
'/models/',
'exported.glb',
scene,
(meshes) => {
console.log('Loaded meshes:', meshes);
}
);
优化技术
1. 几何体优化
简化修改器:
# Reduce polygon count by 70%
obj.modifiers.new(name='Decimate', type='DECIMATE')
obj.modifiers['Decimate'].ratio = 0.3
按距离合并:
# Remove duplicate vertices
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles(threshold=0.0001)
bpy.ops.object.mode_set(mode='OBJECT')
三角化面:
# Ensure all faces are triangles (required for some engines)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.quads_convert_to_tris()
bpy.ops.object.mode_set(mode='OBJECT')
2. 纹理优化
图像压缩:
# Save textures as JPEG (lossy but smaller)
for img in bpy.data.images:
img.file_format = 'JPEG'
img.filepath_raw = f"/output/{img.name}.jpg"
img.save()
纹理图集:
# Combine multiple textures into one atlas
# Use Smart UV Project for automatic atlasing
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.uv.smart_project(angle_limit=66, island_margin=0.02)
bpy.ops.object.mode_set(mode='OBJECT')
3. 材质简化
转换为 PBR:
# Ensure materials use Principled BSDF (glTF standard)
for mat in bpy.data.materials:
if not mat.use_nodes:
mat.use_nodes = True
nodes = mat.node_tree.nodes
principled = nodes.get('Principled BSDF')
if not principled:
principled = nodes.new(type='ShaderNodeBsdfPrincipled')
output = nodes.get('Material Output')
mat.node_tree.links.new(principled.outputs[0], output.inputs[0])
常见问题
1. 文件过大
问题: 导出的 .glb 文件超过 20 MB
解决方案:
- 启用 Draco 压缩(可减少 60-90%)
- 降低纹理分辨率(2048 → 1024 或 512)
- 纹理使用 JPEG 而不是 PNG
- 简化几何体(目标为 <50k 个三角形)
- 移除未使用的材质/纹理
2. 导出时缺少纹理
问题: 纹理未在 Web 查看器中显示
解决方案:
- 确保所有图像都已保存(而非打包)
- 纹理使用相对路径
- 导出时启用“Export Images”
- 检查图像格式是否兼容(PNG/JPEG)
3. 动画无法播放
问题: 动画未导出或播放异常
解决方案:
- 确保动画位于时间轴上(而非 NLA 条带中)
- 导出时启用“Export Animations”
- 检查动画动作是否已分配给对象
- 对复杂骨架使用“Bake Actions”
4. 材质外观不同
问题: 材质在 Web 中的渲染效果与 Blender 中不同
解决方案:
- 使用 Principled BSDF(可映射到 glTF PBR)
- 避免使用自定义着色器节点(无法导出)
- 使用支持的纹理类型(Base Color、Metallic、Roughness、Normal、Emission)
- 部署前在 glTF 查看器中测试
5. 导出耗时过长
问题: 导出耗时超过 10 分钟
解决方案:
- 导出前应用修改器(不要以非破坏性方式导出)
- 降低几何体复杂度
- 移除未使用的数据(清理孤立数据)
- 使用命令行导出(比图形界面更快)
6. 浏览器中的性能问题
问题: 模型在浏览器中运行卡顿
解决方案:
- 生成 LOD(细节层次)
- 对重复对象使用实例化
- 限制绘制调用次数(合并对象、使用纹理图集)
- 减少多边形数量(少于 50k 个三角形)
- 优化着色器(避免透明效果和折射)
最佳实践
导出前检查清单
☐ Apply all modifiers
☐ Merge vertices (remove doubles)
☐ Triangulate faces (if required)
☐ Optimize polygon count (<50k triangles)
☐ UV unwrap all meshes
☐ Bake materials (if complex)
☐ Resize textures (max 2048x2048)
☐ Use Principled BSDF materials
☐ Remove unused data (orphan cleanup)
☐ Name objects descriptively
☐ Set origin points correctly
☐ Apply transformations (Ctrl+A)
导出设置
# Recommended glTF export settings
bpy.ops.export_scene.gltf(
filepath='/output.glb',
export_format='GLB', # Binary format
export_apply=True, # Apply modifiers
export_image_format='JPEG', # Smaller file size
export_jpeg_quality=85, # Quality vs size
export_draco_mesh_compression_enable=True, # Enable compression
export_draco_mesh_compression_level=6, # Balance speed/size
export_animations=True, # Include animations
export_lights=False, # Skip lights (recreate in code)
export_cameras=False # Skip cameras
)
资源
此技能包含:
scripts/
batch_export.py- 将 .blend 文件批量导出为 glTFoptimize_model.py- 针对 Web 优化几何体和纹理generate_lods.py- 自动生成 LOD 副本
references/
gltf_export_guide.md- 完整的 glTF 导出参考bpy_api_reference.md- Blender Python API 快速参考optimization_strategies.md- 详细的优化技巧
assets/
export_template.blend- 预配置的导出模板shader_library/- 针对 Web 优化的 PBR 着色器
相关技能
- threejs-webgl - 在 Three.js 中加载并渲染导出的 glTF 模型
- react-three-fiber - 在 React 应用中使用 glTF 模型
- babylonjs-engine - 可用于 Web 的替代 3D 引擎
- playcanvas-engine - 支持导入 glTF 的游戏引擎
评论
支持 Markdown