substance-3d-texturing について
substance-3d-texturingは、リアルタイムレンダリングやWeb 3Dの制作者向けに、Substance 3D PainterのPBR制作・書き出し・最適化を扱うスキルです。Pythonによる一括処理と、glTF、Three.js、Babylon.js向けのテクスチャ準備も解説します。
主な機能
- 01メタリック/ラフネスPBR制作
- 02Web・リアルタイムエンジン向けテクスチャ書き出し
- 03Python APIによる一括書き出し
- 04テクスチャ圧縮と解像度調整
- 05チャンネルパッキングとカスタム書き出しプリセット
活用シーン
- 01glTFアセット用PBRテクスチャの書き出し
- 02複数のテクスチャセットの一括処理
- 03モバイルWebGL向けテクスチャ圧縮
- 04Three.jsまたはBabylon.jsでのテクスチャ利用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ freshtechbro/ claudedesignskills --skill substance-3d-texturingインストール後、Claude Code で/substance-3d-texturingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/README.mdassets/export_templates/babylonjs_pbr.jsongltf_standard.jsonmobile_webgl.jsonthreejs_optimized.jsonweb_orm_packed.jsonreferences/export_presets.mdpbr_channel_guide.mdpython_api_reference.mdscripts/batch_export.pygenerate_export_preset.pyweb_optimizer.py詳細
Substance 3D Texturing
概要
Web およびリアルタイムエンジン向けの PBR(物理ベースレンダリング)テクスチャ作成とエクスポートのワークフローを習得します。このスキルでは、マテリアルの作成から Web 向けに最適化されたテクスチャのエクスポートまで、Substance 3D Painter のワークフローを扱います。また、バッチ処理や WebGL/WebGPU エンジンとの統合に Python による自動化を活用します。
主な機能:
- PBR マテリアルの作成(メタリック/ラフネスのワークフロー)
- Web 向けに最適化されたテクスチャのエクスポート(glTF、Three.js、Babylon.js)
- バッチエクスポートのための Python API による自動化
- リアルタイムレンダリング向けのテクスチャ圧縮と最適化
基本概念
PBR ワークフロー
Substance 3D Painter では、次の基本チャンネルを使用するメタリック/ラフネスの PBR ワークフローを採用しています。
基本テクスチャマップ:
baseColor(アルベド) - RGB のディフューズカラー。ライティング情報は含みませんnormal- RGB の法線マップ(タンジェント空間)metallic- グレースケールの金属度(0 = 非金属、1 = 金属)roughness- グレースケールの表面粗さ(0 = 滑らか/光沢あり、1 = 粗い/マット)
追加マップ:
ambientOcclusion(AO) - グレースケールのキャビティ/オクルージョンheight- グレースケールのディスプレイスメント/高さemissive- RGB の自己照明opacity- グレースケールの透明度
エクスポートプリセット
Substance 3D Painter には、一般的なエンジン向けのエクスポートプリセットが組み込まれています。
- PBR Metallic Roughness - 標準的な glTF/WebGL 形式
- Unity HDRP/URP - Unity のパイプライン
- Unreal Engine - UE4/UE5 形式
- Arnold (AiStandard) - レンダラー固有
Web エンジンでは、PBR Metallic Roughness が汎用標準です。
テクスチャ解像度
Web で一般的な解像度(2 の累乗):
- 512×512 - ディテールの少ない小物、モバイル
- 1024×1024 - 標準的な小物、キャラクター
- 2048×2048 - 主役となるアセット、クローズアップ
- 4096×4096 - 展示品質(必要な場合にのみ使用)
Web 最適化のルール: 1024×1024 から始め、テクスチャのディテールが見える場合にのみ解像度を上げます。
よくあるパターン
1. 基本的な Web エクスポート(Three.js/Babylon.js)
単一のテクスチャセットを手動でエクスポートするワークフロー:
手順:
- File → Export Textures
- プリセットを選択: 「PBR Metallic Roughness」
- エクスポートを設定:
- 出力ディレクトリ:保存先のフォルダーを選択
- ファイル形式:Web 用の PNG(8 ビット)
- パディング:「Infinite」(継ぎ目を防止)
- 解像度:1024×1024(アセットに応じて調整)
- エクスポート
出力ファイル:
MyAsset_baseColor.png
MyAsset_normal.png
MyAsset_metallicRoughness.png // Packed: R=nothing, G=roughness, B=metallic
MyAsset_emissive.png // Optional
Three.js での使用方法:
import * as THREE from 'three';
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshStandardMaterial({
map: textureLoader.load('MyAsset_baseColor.png'),
normalMap: textureLoader.load('MyAsset_normal.png'),
metalnessMap: textureLoader.load('MyAsset_metallicRoughness.png'),
roughnessMap: textureLoader.load('MyAsset_metallicRoughness.png'),
aoMap: textureLoader.load('MyAsset_ambientOcclusion.png'),
});
2. Python API によるバッチエクスポート
複数のテクスチャセットのエクスポートを自動化します。
import substance_painter.export
import substance_painter.resource
import substance_painter.textureset
# Define export preset
export_preset = substance_painter.resource.ResourceID(
context="starter_assets",
name="PBR Metallic Roughness"
)
# Configure export for all texture sets
config = {
"exportShaderParams": False,
"exportPath": "C:/export/web_textures",
"defaultExportPreset": export_preset.url(),
"exportList": [],
"exportParameters": [{
"parameters": {
"fileFormat": "png",
"bitDepth": "8",
"dithering": True,
"paddingAlgorithm": "infinite",
"sizeLog2": 10 // 1024×1024
}
}]
}
# Add all texture sets to export list
for texture_set in substance_painter.textureset.all_texture_sets():
config["exportList"].append({
"rootPath": texture_set.name()
})
# Execute export
result = substance_painter.export.export_project_textures(config)
if result.status == substance_painter.export.ExportStatus.Success:
for stack, files in result.textures.items():
print(f"Exported {stack}: {len(files)} textures")
else:
print(f"Export failed: {result.message}")
3. アセットごとの解像度の上書き
アセットごとに異なる解像度でエクスポートします(例:主役と背景)。
config = {
"exportPath": "C:/export",
"defaultExportPreset": export_preset.url(),
"exportList": [
{"rootPath": "HeroCharacter"}, # Will use 2048 (override below)
{"rootPath": "BackgroundProp"} # Will use 512 (override below)
],
"exportParameters": [
{
"filter": {"dataPaths": ["HeroCharacter"]},
"parameters": {"sizeLog2": 11} # 2048×2048
},
{
"filter": {"dataPaths": ["BackgroundProp"]},
"parameters": {"sizeLog2": 9} # 512×512
}
]
}
4. カスタムエクスポートプリセット(チャンネルを分離)
メタリックとラフネスを別々のファイルとしてエクスポートするカスタムプリセットを作成します。
custom_preset = {
"exportPresets": [{
"name": "WebGL_Separated",
"maps": [
{
"fileName": "$textureSet_baseColor",
"channels": [
{"destChannel": "R", "srcChannel": "R", "srcMapType": "documentMap", "srcMapName": "baseColor"},
{"destChannel": "G", "srcChannel": "G", "srcMapType": "documentMap", "srcMapName": "baseColor"},
{"destChannel": "B", "srcChannel": "B", "srcMapType": "documentMap", "srcMapName": "baseColor"}
]
},
{
"fileName": "$textureSet_normal",
"channels": [
{"destChannel": "R", "srcChannel": "R", "srcMapType": "documentMap", "srcMapName": "normal"},
{"destChannel": "G", "srcChannel": "G", "srcMapType": "documentMap", "srcMapName": "normal"},
{"destChannel": "B", "srcChannel": "B", "srcMapType": "documentMap", "srcMapName": "normal"}
]
},
{
"fileName": "$textureSet_metallic",
"channels": [
{"destChannel": "R", "srcChannel": "R", "srcMapType": "documentMap", "srcMapName": "metallic"}
],
"parameters": {"fileFormat": "png", "bitDepth": "8"}
},
{
"fileName": "$textureSet_roughness",
"channels": [
{"destChannel": "R", "srcChannel": "R", "srcMapType": "documentMap", "srcMapName": "roughness"}
],
"parameters": {"fileFormat": "png", "bitDepth": "8"}
}
]
}]
}
config = {
"exportPath": "C:/export",
"exportPresets": custom_preset["exportPresets"],
"exportList": [{"rootPath": "MyAsset", "exportPreset": "WebGL_Separated"}]
}
5. モバイル向けに最適化されたエクスポート
モバイル WebGL 向けに強力に圧縮します。
mobile_config = {
"exportPath": "C:/export/mobile",
"defaultExportPreset": export_preset.url(),
"exportList": [{"rootPath": texture_set.name()}],
"exportParameters": [{
"parameters": {
"fileFormat": "jpeg", # JPEG for baseColor (lossy but smaller)
"bitDepth": "8",
"sizeLog2": 9, # 512×512 maximum
"paddingAlgorithm": "infinite"
}
}, {
"filter": {"outputMaps": ["$textureSet_normal", "$textureSet_metallicRoughness"]},
"parameters": {
"fileFormat": "png" # PNG for data maps (need lossless)
}
}]
}
エクスポート後: pngquant や tinypng などのツールを使って、さらに圧縮します。
6. glTF/GLB との統合
glTF 2.0 形式向けにテクスチャをエクスポートします。
gltf_config = {
"exportPath": "C:/export/gltf",
"defaultExportPreset": substance_painter.resource.ResourceID(
context="starter_assets",
name="PBR Metallic Roughness"
).url(),
"exportList": [{"rootPath": texture_set.name()}],
"exportParameters": [{
"parameters": {
"fileFormat": "png",
"bitDepth": "8",
"sizeLog2": 10, # 1024×1024
"paddingAlgorithm": "infinite"
}
}]
}
# After export, reference in glTF:
# {
# "materials": [{
# "name": "Material",
# "pbrMetallicRoughness": {
# "baseColorTexture": {"index": 0},
# "metallicRoughnessTexture": {"index": 1}
# },
# "normalTexture": {"index": 2}
# }]
# }
7. イベント駆動型エクスポートプラグイン
Python プラグインを使って、保存時に自動でエクスポートします。
import substance_painter.event
import substance_painter.export
import substance_painter.project
def auto_export(e):
if not substance_painter.project.is_open():
return
config = {
"exportPath": substance_painter.project.file_path().replace('.spp', '_textures'),
"defaultExportPreset": substance_painter.resource.ResourceID(
context="starter_assets", name="PBR Metallic Roughness"
).url(),
"exportList": [{"rootPath": ts.name()} for ts in substance_painter.textureset.all_texture_sets()],
"exportParameters": [{
"parameters": {"fileFormat": "png", "bitDepth": "8", "sizeLog2": 10}
}]
}
substance_painter.export.export_project_textures(config)
print("Auto-export completed")
# Register event
substance_painter.event.DISPATCHER.connect(
substance_painter.event.ProjectSaved,
auto_export
)
統合パターン
Three.js + React Three Fiber
エクスポートしたテクスチャを R3F で使用します。
import { useTexture } from '@react-three/drei';
function TexturedMesh() {
const [baseColor, normal, metallicRoughness, ao] = useTexture([
'/textures/Asset_baseColor.png',
'/textures/Asset_normal.png',
'/textures/Asset_metallicRoughness.png',
'/textures/Asset_ambientOcclusion.png',
]);
return (
<mesh>
<boxGeometry />
<meshStandardMaterial
map={baseColor}
normalMap={normal}
metalnessMap={metallicRoughness}
roughnessMap={metallicRoughness}
aoMap={ao}
/>
</mesh>
);
}
高度な R3F マテリアルのワークフローについては、react-three-fiber スキルを参照してください。
Babylon.js の PBR マテリアル
import { PBRMaterial, Texture } from '@babylonjs/core';
const pbr = new PBRMaterial("pbr", scene);
pbr.albedoTexture = new Texture("/textures/Asset_baseColor.png", scene);
pbr.bumpTexture = new Texture("/textures/Asset_normal.png", scene);
pbr.metallicTexture = new Texture("/textures/Asset_metallicRoughness.png", scene);
pbr.useRoughnessFromMetallicTextureAlpha = false;
pbr.useRoughnessFromMetallicTextureGreen = true;
pbr.useMetallnessFromMetallicTextureBlue = true;
高度な PBR ワークフローについては、babylonjs-engine スキルを参照してください。
GLTF エクスポートパイプライン
- Substance からテクスチャをエクスポートします(上記の手順)。
- glTF エクスポーターを使って Blender からモデルをエクスポートします。
.gltfJSON 内で Substance のテクスチャを参照します。gltf-pipelineを使って Draco 圧縮します。
gltf-pipeline -i model.gltf -o model.glb -d
3D アセットのパイプライン全体については、blender-web-pipeline スキルを参照してください。
パフォーマンスの最適化
テクスチャサイズの予算
デスクトップ WebGL: テクスチャメモリの合計で約 100~150MB
モバイル WebGL: テクスチャメモリの合計で約 30~50MB
アセットごとの予算:
- 背景/小物:512×512(テクスチャ 1 枚あたり 1MB × 4 マップ = 4MB)
- 標準アセット:1024×1024(テクスチャ 1 枚あたり 4MB × 4 マップ = 16MB)
- 主役となるアセット:2048×2048(テクスチャ 1 枚あたり 16MB × 4 マップ = 64MB)
圧縮戦略
- baseColorにはJPEG(品質70~80%) - PNGより10倍小さくなります
- データマップにはPNG-8(ノーマル、メタリック、ラフネス) - 可逆圧縮が必要です
- Basis Universal(
.basis) - GPUテクスチャ圧縮(90%小さくなります) - テクスチャアトラス - 複数のアセットを1つのテクスチャにまとめます
チャンネルパッキング
グレースケールマップをRGBチャンネルにパックして、テクスチャ数を減らします。
パック済みORM(Occlusion-Roughness-Metallic):
- 赤:アンビエントオクルージョン
- 緑:ラフネス
- 青:メタリック
Substanceでエクスポートします:
orm_map = {
"fileName": "$textureSet_ORM",
"channels": [
{"destChannel": "R", "srcChannel": "R", "srcMapType": "documentMap", "srcMapName": "ambientOcclusion"},
{"destChannel": "G", "srcChannel": "R", "srcMapType": "documentMap", "srcMapName": "roughness"},
{"destChannel": "B", "srcChannel": "R", "srcMapType": "documentMap", "srcMapName": "metallic"}
]
}
ミップマップ
遠くから見るテクスチャには、エンジンで必ずミップマップを有効にします。
// Three.js (automatic)
texture.generateMipmaps = true;
// Babylon.js
texture.updateSamplingMode(Texture.TRILINEAR_SAMPLINGMODE);
よくある問題
1. BaseColorの色空間が誤っている
問題: 線形空間でエクスポートされたBaseColorは、色あせて見えます。
解決策: SubstanceはデフォルトでbaseColorをsRGBでエクスポートします(正しい設定です)。エンジンでもsRGBを使用するようにします。
// Three.js
baseColorTexture.colorSpace = THREE.SRGBColorSpace;
// Babylon.js (automatic for albedoTexture)
2. ノーマルマップのベイクに関する問題
問題: ノーマルマップの陰影が反転したり、正しく表示されなかったりします。
解決策:
- タンジェント空間のノーマル形式(DirectXとOpenGLのY反転)を確認します
- SubstanceはOpenGL(Y+)を使用しており、glTF標準と同じです
- DirectXエンジンを使用する場合は、エクスポート時に緑チャンネルを反転します
3. メタリック/ラフネスのチャンネル順序
問題: メタリック/ラフネステクスチャのチャンネルが入れ替わっています。
解決策: Substanceのデフォルトのエクスポート設定:
- 青チャンネル = メタリック
- 緑チャンネル = ラフネス
- glTF 2.0の仕様に準拠しています
4. UVシームでのパディングによるアーティファクト
問題: UVシームに黒または色付きの線が現れます。
解決策: エクスポート設定でパディングアルゴリズムを**「infinite」**に設定します。
"paddingAlgorithm": "infinite"
5. Web向けテクスチャのサイズが大きすぎる
問題: 4Kテクスチャは、Webでの読み込み時間が長くなり、メモリの問題を引き起こします。
解決策:
- Webでは1024×1024を標準にします
- クローズアップで表示する主要アセットに限り、2048×2048を使用します
- 複数の解像度セットを使ったLODシステムを実装します
6. エンジンでAOマップが表示されない
問題: AOマップをエクスポートしたのに、エンジンで表示されません。
解決策:
- Three.js:第2 UVチャンネル(
geometry.attributes.uv2)が必要です - Babylon.js:
material.useAmbientOcclusionFromMetallicTextureRed = trueを設定します - 代替策:SubstanceでAOをbaseColorにベイクします
リソース
ワークフロー全体については、同梱のリソースを参照してください。
- references/python_api_reference.md - Substance Painter Python APIの完全なリファレンス
- references/export_presets.md - 組み込みおよびカスタムのエクスポートプリセットカタログ
- references/pbr_channel_guide.md - PBRテクスチャチャンネルの詳細な解説
- scripts/batch_export.py - すべてのテクスチャセットを一括エクスポート
- scripts/web_optimizer.py - Web向けにテクスチャを後処理(リサイズ、圧縮)
- scripts/generate_export_preset.py - カスタムのエクスポートプリセットJSONを作成
- assets/export_templates/ - Three.js、Babylon.js、Unity向けに事前設定されたエクスポートプリセット
関連スキル
- blender-web-pipeline - 3Dモデルからテクスチャ、Webまでの完全なパイプライン
- threejs-webgl - Three.jsでのPBRテクスチャの読み込みと使用
- react-three-fiber - Substanceテクスチャを使ったR3Fマテリアルのワークフロー
- babylonjs-engine - Babylon.jsのPBRマテリアルシステムとの統合