mcpField
B
blender-web-pipeline

blender-web-pipeline

github.com/freshtechbroクリエイティブ・メディア1.2k3.5k 回インストール49 週間前に更新
リポジトリ

blender-web-pipeline について

blender-web-pipelineは、Blenderのモデルやアニメーションを主にglTF 2.0などのウェブ向け形式へ書き出すスキルです。3Dアセットやウェブコンテンツの制作向けに、Python自動化、バッチ処理、最適化を扱います。

主な機能

  1. 01glTF 2.0の書き出しと最適化
  2. 02Python(bpy)による自動化
  3. 03Blenderファイルのバッチ処理
  4. 04テクスチャのベイクと圧縮
  5. 05LODモデルの生成
  6. 06ジオメトリとマテリアルの最適化

活用シーン

  1. 01BlenderアセットのGLB書き出し
  2. 023Dモデルの一括変換
  3. 03ウェブ向けモデルとテクスチャの最適化
  4. 04ウェブ3Dアセット制作パイプラインの構築

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/freshtechbro/claudedesignskills --skill blender-web-pipeline

インストール後、Claude Code で/blender-web-pipelineを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
README.md
references/
bpy_api_reference.md
gltf_export_guide.md
optimization_strategies.md
scripts/
batch_export.py
generate_lods.py
optimize_model.py

詳細

Blender Web Pipeline

概要

Blender Web Pipeline スキルでは、Blender から Web に最適化された形式(主に glTF 2.0)で 3D モデルやアニメーションを書き出すワークフローを提供します。バッチ処理用の 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 形式

Web に glTF を使用する理由:

  • 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)
  • テクスチャには PNG ではなく JPEG を使用する
  • ジオメトリをデシメーションする(目標:<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 分以上かかる

解決策:

  • 書き出し前にモディファイアーを適用する(非破壊のまま書き出さない)
  • ジオメトリの複雑さを下げる
  • 未使用データを削除する(孤立データのクリーンアップ)
  • コマンドラインで書き出す(GUI より高速)
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 ファイルを glTF に一括エクスポートします
  • optimize_model.py - ジオメトリとテクスチャをウェブ向けに最適化します
  • 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/ - ウェブ向けに最適化された PBR シェーダー

関連スキル

  • threejs-webgl - エクスポートした glTF モデルを Three.js で読み込んでレンダリングします
  • react-three-fiber - React アプリケーションで glTF モデルを使用します
  • babylonjs-engine - ウェブ向けの代替 3D エンジン
  • playcanvas-engine - glTF のインポートに対応したゲームエンジン

コメント