blender-mcp について
blender-mcpは、Blenderシーンの確認とGLTF書き出し準備のためのワークフロースキルです。MCPの接続確認、シーンやマテリアルの分析、ヘッドレスCLIでの書き出し、最適化、検証を案内します。
主な機能
- 01MCP接続とツールのヘルスチェック
- 02シーン階層とマテリアルの確認
- 03ヘッドレスCLIによるGLTF書き出し手順
- 04テクスチャとメッシュの最適化
- 05アセットとアニメーションの書き出し検証
活用シーン
- 01Blender MCP接続の診断
- 02シーンやマテリアルの書き出し問題の発見
- 03Web向けGLBアセットの準備
- 04書き出したテクスチャ、メッシュ、アニメーションの確認
MCP 対応
get_scene_info、execute_python、screenshotなどのBlender MCPツールを使い、シーンと接続状態を確認する方法を案内します。MCPサーバーはGLTF書き出しでタイムアウトするため、書き出しにはBlenderのヘッドレスCLIを使います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vladmdgolam/ agent-skills --skill blender-mcpインストール後、Claude Code で/blender-mcpを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/asset-integrations.mderrors.mdtexture-optimization.md詳細
Blender MCP
ツールの選択
すばやく確認するには、構造化 MCP ツール(get_scene_info、screenshot)を使用します。
複雑な処理(階層の走査、マテリアルの抽出、アニメーションのベイク処理、一括操作)には、execute_python を使用します。bpy API に完全にアクセスでき、ツールのスキーマによる制約を回避できます。
GLTF のエクスポートにはヘッドレス CLIを使用してください。MCP サーバーはエクスポート処理中にタイムアウトします。
ヘルスチェック(必ず最初に実施)
get_scene_info— 接続を確認します(デフォルトポートは 9876)execute_pythonでprint("ok")を実行 — Python が動作することを確認しますscreenshot— ビューポートをキャプチャできることを確認します
MCP が応答しない場合は、Blender MCP アドオンが有効になっていることと、ソケットサーバーが実行中であることを確認してください。
エクスポートの完全なワークフロー
以下は、エンドツーエンドの手順です。順番に実行してください。手順を省略しないでください。
ステップ 1:ヘルスチェック
ほかの作業を始める前に、MCP が動作していることを確認します。
# In MCP tool call:
get_scene_info
execute_python: print("ok")
screenshot
いずれかの手順が失敗した場合は、作業を中断し、まず MCP の接続を修復してください。既知のエラーと回避策を参照してください。
ステップ 2:シーンを確認
完全な階層の抽出を実行し、対象を把握します。
import bpy, json
def extract_hierarchy(obj, depth=0):
data = {
"name": obj.name,
"type": obj.type,
"location": list(obj.location),
"rotation": list(obj.rotation_euler),
"scale": list(obj.scale),
"visible": not obj.hide_viewport,
"children": [],
}
if obj.type == 'MESH' and obj.data:
data["vertices"] = len(obj.data.vertices)
data["faces"] = len(obj.data.polygons)
data["materials"] = [slot.material.name for slot in obj.material_slots if slot.material]
if obj.type == 'LIGHT':
data["light_type"] = obj.data.type
data["energy"] = obj.data.energy
data["color"] = list(obj.data.color)
for mod in obj.modifiers:
if mod.type == 'ARRAY':
data.setdefault("modifiers", []).append({
"type": "ARRAY",
"count": mod.count,
"offset_object": mod.offset_object.name if mod.offset_object else None,
})
for child in obj.children:
data["children"].append(extract_hierarchy(child, depth + 1))
return data
scene_data = {
"name": bpy.context.scene.name,
"fps": bpy.context.scene.render.fps,
"frame_start": bpy.context.scene.frame_start,
"frame_end": bpy.context.scene.frame_end,
"objects": [],
}
for obj in bpy.context.scene.objects:
if obj.parent is None:
scene_data["objects"].append(extract_hierarchy(obj))
print(json.dumps(scene_data, indent=2))
次の点を確認してください。
- Array モディファイア(ベイクするとファイルサイズが急増するため、実行時に複製する必要があります)
- 頂点数の多いオブジェクト(エクスポートが遅くなったり、GLB が大きくなったりするリスクがあります)
- エクスポートするかどうかを判断する必要がある非表示オブジェクト
- マテリアルが設定されていないオブジェクト(空の
material_slots)
ステップ 3:マテリアルを確認
エクスポートで失われる可能性のある設定を事前に把握するため、マテリアルの抽出を実行します。
import bpy, json
def extract_materials():
materials = []
for mat in bpy.data.materials:
if not mat.use_nodes:
continue
info = {"name": mat.name, "nodes": [], "warnings": []}
has_principled = False
for node in mat.node_tree.nodes:
node_data = {"type": node.type, "name": node.name}
if node.type == 'BSDF_PRINCIPLED':
has_principled = True
for inp in node.inputs:
if inp.is_linked:
node_data[inp.name] = "linked"
elif hasattr(inp, 'default_value'):
val = inp.default_value
try:
node_data[inp.name] = list(val)
except TypeError:
node_data[inp.name] = float(val)
if node.type == 'TEX_IMAGE' and node.image:
node_data["image"] = node.image.filepath
node_data["size"] = [node.image.size[0], node.image.size[1]]
if node.image.size[0] > 2048:
info["warnings"].append(f"Large texture: {node.image.filepath} ({node.image.size[0]}x{node.image.size[1]})")
if node.type in ('TEX_NOISE', 'TEX_VORONOI', 'TEX_WAVE', 'TEX_MUSGRAVE'):
info["warnings"].append(f"Procedural texture node '{node.name}' ({node.type}) will be LOST on GLTF export")
if node.type == 'VALTORGB': # Color Ramp
info["warnings"].append(f"Color Ramp '{node.name}' remapping will be LOST on GLTF export")
if not has_principled:
info["warnings"].append("No Principled BSDF found — export result unpredictable")
info["nodes"].append(node_data)
materials.append(info)
return materials
result = extract_materials()
for mat in result:
if mat["warnings"]:
print(f"WARN [{mat['name']}]: {'; '.join(mat['warnings'])}")
print(json.dumps(result, indent=2))
先に進む前に、すべての警告を確認してください。プロシージャルテクスチャを今すぐベイクするか、エクスポート後に実行時にマテリアルを修正するかを判断します。
ステップ 4:ヘッドレス CLI でエクスポート
MCP サーバーは GLTF のエクスポートを処理できません(タイムアウト)。必ずヘッドレス CLI を使用してください。
# Use 'blender' if it's on PATH, otherwise use the platform-specific path:
# macOS: /Applications/Blender.app/Contents/MacOS/Blender
# Windows: "C:\Program Files\Blender Foundation\Blender 4.x\blender.exe"
# Linux: /usr/bin/blender
blender \
--background "/path/to/scene.blend" \
--python-expr "
import bpy, os
export_path = '/path/to/output.glb'
os.makedirs(os.path.dirname(os.path.abspath(export_path)), exist_ok=True)
bpy.ops.export_scene.gltf(
filepath=export_path,
export_format='GLB',
export_apply=False,
export_animations=True,
export_nla_strips=True,
export_cameras=True,
export_lights=False,
export_draco_mesh_compression_enable=False,
)
size_mb = os.path.getsize(export_path) / 1024 / 1024
print(f'Export complete: {export_path} ({size_mb:.1f} MB)')
"
重要なフラグ:
export_apply=False— モディファイアをベイクしません(Array モディファイアを適用すると、1 MB が 56 MB になります)export_draco_mesh_compression_enable=False— Draco 圧縮は後から gltf-transform で適用します- スペースを含む可能性のあるパスはすべて引用符で囲みます
ステップ 5:gltf-transform で最適化
エクスポートが成功した後に実行します。必ず個別の手順を使用し、optimize は使用しないでください。
# 1. Inspect raw export first
npx @gltf-transform/cli inspect output.glb
# 2. Resize textures (max 1K for web/mobile)
npx @gltf-transform/cli resize output.glb resized.glb --width 1024 --height 1024
# 3. WebP compression (quality 90 preserves detail)
npx @gltf-transform/cli webp resized.glb webp.glb --quality 90
# 4. Draco mesh compression (LAST — irreversible)
npx @gltf-transform/cli draco webp.glb final.glb
# 5. Inspect final result
npx @gltf-transform/cli inspect final.glb
予想されるサイズ削減量:未圧縮で約 22 MB → WebP で約 3.7 MB → Draco で約 1 MB。詳細な測定値については、references/texture-optimization.mdを参照してください。
ステップ 6:検証
納品前に、以下の「エクスポート後の検証」チェックリストをすべて実行してください。
エクスポート後の検証チェックリスト
エクスポートのたびに、GLB を統合作業に渡す前に以下を確認してください。
- ファイルサイズが適切であること — 一般的な Web シーンでは、最適化前の GLB は 30 MB 未満、最適化後の GLB は 5 MB 未満にします。これらのしきい値を超えるものがあれば報告してください。
- gltf-transform CLI で検査すること —
npx @gltf-transform/cli inspect final.glbを実行し、メッシュ数、テクスチャ数、テクスチャサイズ、アニメーション数、アクセサーのサイズを確認します。予期しない重複がないことを確認してください。 - Babylon.js Sandbox でビジュアルテストを行うこと — sandbox.babylonjs.com に GLB をドラッグ&ドロップします。メッシュが正しく描画されること、テクスチャが表示されること、アニメーションが再生されること、黒やピンクのマテリアルがないことを確認してください。
- Three.js のコンソールエラーがないこと — 最小構成の Three.js GLTFLoader テストページで読み込み、ブラウザーのコンソールを確認します。よくあるエラー:
THREE.GLTFLoader: Unknown extension、テクスチャファイルの欠落、未対応の Draco バージョン。 - マテリアルを抜き取り確認すること — 3~5 個のマテリアルを選び、ラフネス、メタルネス、ベースカラーが正しく見えることを目視で確認します。Blender のビューポートレンダーと比較してください。フラットに見えるものや、光沢が強すぎるものがあれば報告してください。
- アニメーションを抜き取り確認すること — シーンにアニメーションがある場合は、Babylon.js Sandbox または Three.js で少なくとも 1 つが正しく再生されることを確認します。フレーム数が想定どおりであることも確認してください。
- 名前のマッピングが検証済みであること — ランタイムコードがメッシュ名を参照する場合は、GLTF エクスポート時の変換後も名前が一致することを確認します(スペース → アンダースコア、ドットを削除)。重大なルール 5 を参照してください。
- テクスチャの欠落がないこと — Babylon.js Sandbox のネットワークタブを確認します。テクスチャファイルへの 404 がないこと、すべてのテクスチャが GLB 内に格納されていることを確認してください。
例
例 1:アニメーション付きのキャラクターリグをエクスポートする
シナリオ: アーマチュア、3 つの NLA アクション(idle、walk、run)、PBR テクスチャセットを持ち、ペアレント化によって武器が取り付けられた人型キャラクターがあります。Three.js シーン用の Web 対応 GLB が必要です。
手順 1:ヘルスチェックとシーンの検査
# MCP tool calls
get_scene_info
execute_python: print("ok")
手順 2:リグを検査する
import bpy, json
# Check armature and NLA strips
for obj in bpy.data.objects:
if obj.type == 'ARMATURE':
print(f"Armature: {obj.name}")
if obj.animation_data:
print(f" Active action: {obj.animation_data.action.name if obj.animation_data.action else 'None'}")
for track in obj.animation_data.nla_tracks:
print(f" NLA track: {track.name}")
for strip in track.strips:
print(f" Strip: {strip.name}, frames {strip.frame_start}-{strip.frame_end}")
手順 3:エクスポートで失われるマテリアル情報を確認する
上記のマテリアル抽出を実行します。キャラクターの場合、以下に注意してください。
- プロシージャルスキンテクスチャノード(Noise → 色の変化)— これらは失われます
- 布地のラフネスに使われている Color Ramp — これは失われ、ラフネスはフラットに見えます
- 判断:プロシージャルな変化を画像テクスチャにベイクするか、ランタイムでラフネス値を調整します
手順 4:エクスポートする
blender \
--background "/path/to/character.blend" \
--python-expr "
import bpy, os, tempfile
export_dir = tempfile.gettempdir()
bpy.ops.export_scene.gltf(
filepath=os.path.join(export_dir, 'character.glb'),
export_format='GLB',
export_apply=False,
export_animations=True,
export_nla_strips=True,
export_cameras=False,
export_lights=False,
export_draco_mesh_compression_enable=False,
export_skins=True,
export_morph=True,
)
print('done:', os.path.getsize(os.path.join(export_dir, 'character.glb')) / 1024 / 1024, 'MB')
"
手順 5:アニメーションがエクスポートされたことを確認する
npx @gltf-transform/cli inspect character.glb | grep -i anim
期待される出力:アニメーション 3 つ(Idle、Walk、Run)。0 の場合は、NLA ストリップがミュートされていないか、トラックがソロに設定されていないか確認してください。
手順 6:最適化する
npx @gltf-transform/cli resize character.glb char_resized.glb --width 1024 --height 1024
npx @gltf-transform/cli webp char_resized.glb char_webp.glb --quality 90
npx @gltf-transform/cli draco char_webp.glb character_final.glb
手順 7:ランタイムでアニメーションを設定する(Three.js)
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import * as THREE from 'three';
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
loader.load('/character_final.glb', (gltf) => {
const mixer = new THREE.AnimationMixer(gltf.scene);
const clips = gltf.animations; // [Idle, Walk, Run]
const idleAction = mixer.clipAction(clips.find(c => c.name === 'Idle'));
idleAction.play();
// Animate mixer in render loop: mixer.update(delta)
});
例 2:マテリアルのエクスポートで失われる情報をデバッグする(ラフネスがフラットに見える)
シナリオ: エクスポート後、金属パネルのマテリアルが Three.js で均一にフラットで、光沢のある見た目になります。Blender では Noise Texture → Color Ramp → ラフネス入力によるラフネスの変化がありました。
手順 1:Blender で問題を確認する
import bpy, json
mat = bpy.data.materials.get("MetalPanel")
if mat and mat.use_nodes:
for node in mat.node_tree.nodes:
print(f"Node: {node.type} - {node.name}")
for inp in node.inputs:
if inp.is_linked:
print(f" Input '{inp.name}': linked to something")
期待される出力には、以下の内容が表示されます。
Node: BSDF_PRINCIPLED - Principled BSDF
Input 'Roughness': linked to something
Node: VALTORGB - Color Ramp <-- this will NOT export
Node: TEX_NOISE - Noise Texture <-- this will NOT export
手順 2:GLTF に渡された内容を把握する
エクスポート時には Principled BSDF のラフネス入力がエクスポートされます。Color Ramp に接続されている場合、GLTF エクスポーターは入力ソケットの default_value(フォールバック値)を使用します。通常は 0.5 で、完全にフラットな値です。
手順 3A:Blender でベイクして修正する(最高品質)
import bpy
# Select the object
obj = bpy.data.objects["MetalPanelMesh"]
bpy.context.view_layer.objects.active = obj
bpy.ops.object.select_all(action='DESELECT')
obj.select_set(True)
# Create a new image to bake into
bake_img = bpy.data.images.new("MetalPanel_roughness_baked", width=1024, height=1024)
bake_img.colorspace_settings.name = 'Non-Color'
# Add image texture node to material
mat = obj.active_material
nodes = mat.node_tree.nodes
img_node = nodes.new('ShaderNodeTexImage')
img_node.image = bake_img
nodes.active = img_node
# Bake roughness (use ROUGHNESS pass or EMIT trick)
bpy.context.scene.cycles.bake_type = 'ROUGHNESS'
bpy.ops.object.bake(type='ROUGHNESS', save_mode='INTERNAL')
# Save baked image
import tempfile, os
bake_path = os.path.join(tempfile.gettempdir(), 'MetalPanel_roughness_baked.png')
bake_img.filepath_raw = bake_path
bake_img.file_format = 'PNG'
bake_img.save()
print(f"Baked roughness to {bake_path}")
その後、新しい画像テクスチャノードを Roughness 入力に接続して、再エクスポートします。
手順 3B:Three.js のランタイムで修正する(簡易パッチ)
ベイクできない場合は、読み込み後にマテリアルを上書きします。
loader.load('/metal_panel.glb', (gltf) => {
gltf.scene.traverse((child) => {
if (child.isMesh && child.material) {
const mats = Array.isArray(child.material) ? child.material : [child.material];
mats.forEach(mat => {
if (mat.name === 'MetalPanel') {
// Instead of flat 0.5, set a textured roughness or varied value
mat.roughness = 0.3; // adjust to match intended look
mat.metalness = 0.9;
mat.needsUpdate = true;
}
});
}
});
});
手順 4:修正を確認する
再エクスポートして、検証チェックリストを実行します。Babylon.js Sandbox で金属パネルのマテリアルを Blender のビューポートのスクリーンショットと比較し、ラフネスの変化が保持されていることを確認してください。
重大なルール
1. MCP サーバーはエクスポート時にタイムアウトする
Blender MCP サーバーでは GLTF エクスポートを処理できません。タイムアウトを超えるためです。必ずヘッドレス CLI を使用してください。
blender --background "scene.blend" --python-expr "
import bpy, os
export_path = 'output.glb'
os.makedirs(os.path.dirname(export_path), exist_ok=True)
bpy.ops.export_scene.gltf(
filepath=export_path,
export_format='GLB',
export_apply=False,
export_animations=True,
export_nla_strips=True,
export_cameras=True,
export_lights=False,
export_draco_mesh_compression_enable=False,
)
print(f'Size: {os.path.getsize(export_path)/1024/1024:.1f} MB')
"
2. エクスポート時にモディファイアーを適用しない
export_apply=False に設定してください。配列モディファイアー(円形パターン、線形の反復)を適用すると、ファイルサイズが膨れ上がります。代わりに、実行時に複製してください。
例:Array モディファイアーを使用したローラーインスタンス 16 個の場合、GLB は約 1 MB です。適用すると、GLB は約 56 MB になります。
3. まずは Draco なしでエクスポートする
gltf-transform で最適化する予定がある場合は、Draco 圧縮なしでエクスポートしてください。既存の Draco データを再エンコードすると、メッシュが破損します。Draco の適用は最後の手順にしてください。
4. プロシージャルテクスチャは GLTF にエクスポートされない
以下の Blender ノード設定はエクスポート時に失われます。
| ノード設定 | 失われるもの | 回避策 |
|---|---|---|
| Noise Texture → roughness | プロシージャルチェーン全体 | テクスチャにベイクするか、実行時にシェーダーパッチを適用 |
| roughness テクスチャ上の Color Ramp | 値の再マッピング範囲 | roughness 値を手動で設定するか、実行時に再マッピング |
| プロシージャルバンプ(Noise → Bump) | バンプの詳細 | Blender でノーマルマップをベイク |
| 複雑な係数を使った Mix Shader | ブレンドロジック | エクスポート前に単一の BSDF に簡略化 |
エクスポートされるもの: 平坦な roughness/metallic 値、画像テクスチャ(Color Ramp による再マッピングを除く)、ベイク済みノーマルマップ、PBR テクスチャセット(baseColor、metallicRoughness、normal)。
5. GLTF の名前マッピング
Blender の名前は GLTF では次のように変換されます。
- スペース → アンダースコア
- ピリオド → 削除
- 末尾のスペース → 末尾のアンダースコア
| Blender | GLTF |
|---|---|
RINGS ball L | RINGS_ball_L |
Sphere.003 | Sphere003 |
RINGS L.001 | RINGS_L001 |
RINGS S (末尾にスペース) | RINGS_S_ |
コード内でメッシュを参照する場合は、Blender ではなく、エクスポートした GLB 内の名前を必ず確認してください。
6. gltf-transform の optimize は絶対に使わない
optimize コマンドには、メッシュジオメトリを破壊する simplify が含まれています。代わりに、個別の手順を使用してください。
# Resize textures (max 1024x1024)
npx @gltf-transform/cli resize input.glb resized.glb --width 1024 --height 1024
# WebP texture compression
npx @gltf-transform/cli webp resized.glb webp.glb --quality 90
# Draco mesh compression (LAST step)
npx @gltf-transform/cli draco webp.glb output.glb
7. スペースを含むパスは引用符で囲む
Blender プロジェクトのパスには、スペースが含まれることがよくあります。必ず二重引用符で囲んでください。
blender --background "$HOME/Downloads/blend 3/scene.blend" ...
シーン抽出のパターン
マテリアル、トランスフォーム、モディファイアーを含む完全な階層:
import bpy, json
def extract_hierarchy(obj, depth=0):
data = {
"name": obj.name,
"type": obj.type,
"location": list(obj.location),
"rotation": list(obj.rotation_euler),
"scale": list(obj.scale),
"visible": not obj.hide_viewport,
"children": [],
}
if obj.type == 'MESH' and obj.data:
data["vertices"] = len(obj.data.vertices)
data["faces"] = len(obj.data.polygons)
data["materials"] = [slot.material.name for slot in obj.material_slots if slot.material]
if obj.type == 'LIGHT':
data["light_type"] = obj.data.type
data["energy"] = obj.data.energy
data["color"] = list(obj.data.color)
if obj.data.type == 'AREA':
data["size"] = obj.data.size
data["size_y"] = obj.data.size_y
# Array modifiers (important for runtime replication)
for mod in obj.modifiers:
if mod.type == 'ARRAY':
data.setdefault("modifiers", []).append({
"type": "ARRAY",
"count": mod.count,
"offset_object": mod.offset_object.name if mod.offset_object else None,
})
for child in obj.children:
data["children"].append(extract_hierarchy(child, depth + 1))
return data
scene_data = {
"name": bpy.context.scene.name,
"fps": bpy.context.scene.render.fps,
"frame_start": bpy.context.scene.frame_start,
"frame_end": bpy.context.scene.frame_end,
"objects": [],
}
for obj in bpy.context.scene.objects:
if obj.parent is None:
scene_data["objects"].append(extract_hierarchy(obj))
print(json.dumps(scene_data, indent=2))
マテリアル抽出のパターン
import bpy, json
def extract_materials():
materials = []
for mat in bpy.data.materials:
if not mat.use_nodes:
continue
info = {"name": mat.name, "nodes": []}
for node in mat.node_tree.nodes:
node_data = {"type": node.type, "name": node.name}
if node.type == 'BSDF_PRINCIPLED':
for inp in node.inputs:
if inp.is_linked:
node_data[inp.name] = "linked"
elif hasattr(inp, 'default_value'):
val = inp.default_value
try:
node_data[inp.name] = list(val)
except TypeError:
node_data[inp.name] = float(val)
if node.type == 'TEX_IMAGE' and node.image:
node_data["image"] = node.image.filepath
node_data["size"] = [node.image.size[0], node.image.size[1]]
info["nodes"].append(node_data)
materials.append(info)
return materials
print(json.dumps(extract_materials(), indent=2))
アニメーションのキーフレーム抽出
import bpy, json
def extract_animation(obj):
if not obj.animation_data or not obj.animation_data.action:
return None
tracks = []
for fc in obj.animation_data.action.fcurves:
keyframes = []
for kp in fc.keyframe_points:
keyframes.append({
"frame": int(kp.co[0]),
"value": float(kp.co[1]),
"interpolation": kp.interpolation,
})
tracks.append({
"data_path": fc.data_path,
"index": fc.array_index,
"keyframes": keyframes,
})
return {"object": obj.name, "tracks": tracks}
animations = []
for obj in bpy.data.objects:
anim = extract_animation(obj)
if anim:
animations.append(anim)
print(json.dumps(animations, indent=2))
GLTF エクスポート設定のリファレンス
| 設定 | 値 | 理由 |
|---|---|---|
export_format | 'GLB' | 単一のバイナリファイル |
export_apply | False | モディファイアー(Array など)をベイクしない |
export_animations | True | アニメーションデータを含める |
export_nla_strips | True | NLA ストリップをアクションにベイクする |
export_cameras | True | カメラリグを含める |
export_lights | False | ライトは実行時(Three.js/R3F)に処理する |
export_draco_mesh_compression_enable | False | 後から gltf-transform で Draco を適用する |
テクスチャ最適化パイプライン
目標:許容できる視覚品質を保ちながら、GLB を最小サイズにすること。
Blender export (no Draco) → resize (1K max) → WebP (q90) → Draco
~22 MB ~3.7 MB ~3.7 MB ~1 MB
主なポイント:
- 4K テクスチャ(4096x4096)は、テクスチャ 1 枚あたり約 89 MB の GPU メモリを使用します。1K では約 5.6 MB です。16 分の 1 に削減できます。
- PNG の metallicRoughness テクスチャは、品質 85〜90 の WebP にするとよく圧縮されます。
- モバイル GPU(Adreno、Mali)では、テクスチャのダウンスケーリングが特に効果的です。
npx @gltf-transform/cli inspect model.glbで確認できます。
具体的なコマンドと品質指標については、references/texture-optimization.md を参照してください。
アセット連携
設定済みの場合、Blender MCP から利用できます。
| 連携 | 機能 |
|---|---|
| PolyHaven | 無料の HDRI、テクスチャ、3D モデルを検索、ダウンロード、インポートし、マテリアルを自動設定 |
| Sketchfab | モデルを検索、ダウンロード(アクセストークンが必要) |
| Hyper3D Rodin | テキストの説明や参照画像から 3D モデルを生成 |
| Hunyuan3D | テキストプロンプト、画像、またはその両方から 3D アセットを作成 |
使用例とワークフローのパターンについては、references/asset-integrations.md を参照してください。
既知のエラーと回避策
エラーの一覧については、references/errors.md を参照してください。
データ出力
- 小さな結果(シーン情報、単一オブジェクト)には、
print()+json.dumps()を使用します - 大きな抽出結果(階層全体、アニメーションデータ、マテリアルレポート)には、
tempfile.gettempdir()を使用します - メタデータ(シーン名、fps、フレーム範囲、Blender のバージョン)を必ず含めます