# 機能設計書 52-MeshStandardMaterial

## 概要

本ドキュメントは、Three.jsにおけるMeshStandardMaterialクラスの機能設計を定義する。MeshStandardMaterialは、物理ベースレンダリング（PBR）を使用したMetallic-Roughnessワークフローに基づく標準マテリアルクラスである。

### 本機能の処理概要

MeshStandardMaterialは、物理的に正確なライティング計算を行うPBR（Physically Based Rendering）マテリアルである。Unity、Unreal Engine、3D Studio Maxなど主要な3Dアプリケーションで採用されている標準的なアプローチを採用しており、特定の照明条件に合わせてマテリアルを調整するのではなく、すべての照明シナリオで「正しく」反応するマテリアルを作成できる。

**業務上の目的・背景**：現代の3Dグラフィックスでは、写実的なレンダリングが求められる場面が増えている。PBRマテリアルは、物理法則に基づいた光の相互作用をシミュレートすることで、MeshLambertMaterialやMeshPhongMaterialよりも正確でリアルな見た目を実現する。ゲーム、建築ビジュアライゼーション、プロダクトデザインなど幅広い分野で活用される。

**機能の利用シーン**：リアルな金属・非金属表面のレンダリング、環境マップを使用した反射表現、粗さ（roughness）と金属度（metalness）を調整したマテリアル設定、エディタでのPBRマテリアル編集時に利用される。

**主要な処理内容**：
1. マテリアルの初期化とパラメータ設定
2. 拡散反射色（diffuse color）の管理
3. 粗さ（roughness）と金属度（metalness）パラメータの制御
4. 各種テクスチャマップ（カラーマップ、roughnessMap、metalnessMap、法線マップ等）の適用
5. 環境マップによるPBR準拠の反射シミュレーション（PMREMGeneratorで前処理）
6. ライトマップとアンビエントオクルージョンの適用
7. 発光色（emissive）の設定
8. ワイヤーフレームモードとフラットシェーディングのサポート

**関連システム・外部連携**：WebGLRenderer、WebGPURendererと連携してレンダリングを行う。環境マップはPMREMGeneratorで事前処理され、正確なPBRレンダリングが実現される。HDRIテクスチャとの連携により、より写実的な反射表現が可能。

**権限による制御**：特になし。マテリアルの設定はすべてのユーザーが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | Sidebar - Material | 補助機能 | PBRマテリアルの設定 |
| 36 | Material Browser | 主機能 | PBRマテリアルのプレビュー |

## 機能種別

マテリアル設定 / PBRシェーディング処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| color | Color | No | 拡散反射色（デフォルト: 0xffffff） | Color型として有効な値 |
| roughness | number | No | 表面の粗さ（デフォルト: 1.0）。0.0=鏡面反射、1.0=完全拡散 | 0-1の数値 |
| metalness | number | No | 金属度（デフォルト: 0.0）。0.0=非金属、1.0=金属 | 0-1の数値 |
| map | Texture | No | カラーマップ | Texture型またはnull |
| lightMap | Texture | No | ライトマップ | Texture型またはnull |
| lightMapIntensity | number | No | ライトマップ強度（デフォルト: 1） | 0以上の数値 |
| aoMap | Texture | No | アンビエントオクルージョンマップ | Texture型またはnull |
| aoMapIntensity | number | No | AO強度（デフォルト: 1） | 0-1の数値 |
| emissive | Color | No | 発光色（デフォルト: 0x000000） | Color型として有効な値 |
| emissiveIntensity | number | No | 発光強度（デフォルト: 1） | 0以上の数値 |
| emissiveMap | Texture | No | 発光マップ | Texture型またはnull |
| bumpMap | Texture | No | バンプマップ | Texture型またはnull |
| bumpScale | number | No | バンプスケール（デフォルト: 1） | 数値 |
| normalMap | Texture | No | 法線マップ | Texture型またはnull |
| normalMapType | constant | No | 法線マップタイプ（デフォルト: TangentSpaceNormalMap） | TangentSpaceNormalMapまたはObjectSpaceNormalMap |
| normalScale | Vector2 | No | 法線マップスケール（デフォルト: (1,1)） | Vector2型 |
| displacementMap | Texture | No | ディスプレイスメントマップ | Texture型またはnull |
| displacementScale | number | No | ディスプレイスメントスケール（デフォルト: 1） | 数値 |
| displacementBias | number | No | ディスプレイスメントバイアス（デフォルト: 0） | 数値 |
| roughnessMap | Texture | No | 粗さマップ（緑チャンネル使用） | Texture型またはnull |
| metalnessMap | Texture | No | 金属度マップ（青チャンネル使用） | Texture型またはnull |
| alphaMap | Texture | No | アルファマップ | Texture型またはnull |
| envMap | Texture | No | 環境マップ（PMREMGeneratorで前処理推奨） | Texture型またはnull |
| envMapRotation | Euler | No | 環境マップ回転（デフォルト: (0,0,0)） | Euler型 |
| envMapIntensity | number | No | 環境マップ強度（デフォルト: 1） | 0以上の数値 |
| wireframe | boolean | No | ワイヤーフレーム描画（デフォルト: false） | true/false |
| wireframeLinewidth | number | No | ワイヤーフレーム線幅（デフォルト: 1） | 1以上の数値 |
| wireframeLinecap | string | No | ワイヤーフレーム線端（デフォルト: 'round'） | 'round', 'bevel', 'miter' |
| wireframeLinejoin | string | No | ワイヤーフレーム線結合（デフォルト: 'round'） | 'round', 'bevel', 'miter' |
| flatShading | boolean | No | フラットシェーディング（デフォルト: false） | true/false |
| fog | boolean | No | フォグ影響（デフォルト: true） | true/false |

### 入力データソース

コンストラクタへのパラメータオブジェクト、またはプロパティへの直接代入

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isMeshStandardMaterial | boolean | 型判定フラグ（常にtrue） |
| type | string | マテリアルタイプ（'MeshStandardMaterial'） |
| defines | Object | シェーダー定義（{ 'STANDARD': '' }） |
| マテリアルプロパティ | 各種 | 設定されたマテリアル属性 |

### 出力先

WebGLRenderer/WebGPURendererによるシェーダープログラムへの入力

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ 親クラスMaterialのコンストラクタを呼び出し
2. 型フラグの設定
   └─ isMeshStandardMaterial = true
3. マテリアルタイプの設定
   └─ type = 'MeshStandardMaterial'
4. シェーダー定義の設定
   └─ defines = { 'STANDARD': '' }
5. PBRプロパティの初期化
   └─ roughness = 1.0, metalness = 0.0
6. デフォルトプロパティの初期化
   └─ color, emissive等の初期値設定
7. テクスチャマップの初期化
   └─ map, normalMap, roughnessMap, metalnessMap等をnullで初期化
8. パラメータの適用
   └─ setValues(parameters)でパラメータを適用
```

### フローチャート

```mermaid
flowchart TD
    A[開始: new MeshStandardMaterial] --> B[super() 呼び出し]
    B --> C[isMeshStandardMaterial = true]
    C --> D[type = 'MeshStandardMaterial']
    D --> E[defines = STANDARD]
    E --> F[roughness/metalness 初期化]
    F --> G[カラープロパティ初期化]
    G --> H[テクスチャマップ初期化]
    H --> I[ワイヤーフレーム設定初期化]
    I --> J[setValues parameters]
    J --> K[終了: マテリアルインスタンス]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 法線マップ優先 | normalMapが設定されている場合、bumpMapは無視される | normalMapがnull以外の場合 |
| BR-02 | 第2UV必須 | lightMapとaoMapは第2セットのUV座標が必要 | lightMapまたはaoMapを使用する場合 |
| BR-03 | roughnessMap乗算 | roughnessMapの緑チャンネル値とroughnessプロパティが乗算される | roughnessMapが設定されている場合 |
| BR-04 | metalnessMap乗算 | metalnessMapの青チャンネル値とmetalnessプロパティが乗算される | metalnessMapが設定されている場合 |
| BR-05 | 環境マップ推奨 | 最良の結果を得るには環境マップを常に指定することが推奨される | PBRマテリアル使用時 |
| BR-06 | PMREM前処理 | 環境マップはPMREMGeneratorで内部的に前処理される | envMapが設定されている場合 |

### 計算ロジック

Metallic-Roughnessワークフロー（Disney BRDF準拠）:
- 基本反射率: F0 = mix(0.04, color, metalness)
- 拡散反射: diffuse = color * (1 - metalness) * NdotL
- スペキュラ反射: GGXマイクロファセットBRDFに基づく
- 最終色 = ambient + diffuse + specular + emissive + envMap

## データベース操作仕様

該当なし（本機能はデータベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | Warning | 未定義のプロパティを設定しようとした場合 | コンソールに警告を出力 |
| N/A | Warning | undefinedの値を設定しようとした場合 | コンソールに警告を出力し、設定をスキップ |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- MeshLambertMaterialやMeshPhongMaterialより計算コストが高い
- per-fragmentシェーディングを使用
- 環境マップ使用時は追加のテクスチャサンプリングが発生

## セキュリティ考慮事項

特になし

## 備考

- SVGRendererを使用する場合のみwireframeLinewidthが有効
- WebGL/WebGPUでは線幅は常に1ピクセル
- PBR理論の詳細はDisneyのBRDFペーパーを参照

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、マテリアルの基本構造とPBR固有のプロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Material.js | `src/materials/Material.js` | マテリアルの基底クラス。共通プロパティを定義 |
| 1-2 | MeshStandardMaterial.js | `src/materials/MeshStandardMaterial.js` | PBR固有のプロパティ（roughness, metalness等）を定義 |

**読解のコツ**: MeshStandardMaterialはMaterialを直接継承し、definesプロパティに'STANDARD'を設定することでシェーダーにPBRモードを指示している。roughnessとmetalnessがPBRの核心的なパラメータである。

#### Step 2: エントリーポイントを理解する

マテリアルのインスタンス化と初期化プロセスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MeshStandardMaterial.js | `src/materials/MeshStandardMaterial.js` | constructorメソッドがエントリーポイント |

**主要処理フロー**:
1. **52-54行目**: コンストラクタでsuper()を呼び出し、Materialの初期化を実行
2. **63行目**: isMeshStandardMaterialフラグをtrueに設定
3. **65行目**: typeを'MeshStandardMaterial'に設定
4. **67行目**: definesに{ 'STANDARD': '' }を設定
5. **75行目**: colorを白(0xffffff)で初期化
6. **85行目**: roughnessを1.0で初期化（完全拡散）
7. **96行目**: metalnessを0.0で初期化（非金属）
8. **106-307行目**: 各種テクスチャマップとプロパティの初期化
9. **363行目**: setValues(parameters)でユーザー指定パラメータを適用

#### Step 3: copyメソッドを理解する

マテリアルのクローン作成時の動作を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MeshStandardMaterial.js | `src/materials/MeshStandardMaterial.js` | copyメソッド（367-421行目） |

**主要処理フロー**:
- **369行目**: 親クラスのcopyを呼び出し
- **371行目**: definesを再設定（参照コピーを避ける）
- **373-417行目**: Standard固有のプロパティをコピー

### プログラム呼び出し階層図

```
MeshStandardMaterial (constructor)
    │
    ├─ Material (super())
    │      └─ EventDispatcher (super())
    │
    ├─ Color (new Color())
    │      └─ color, emissive の初期化
    │
    ├─ Vector2 (new Vector2())
    │      └─ normalScale の初期化
    │
    ├─ Euler (new Euler())
    │      └─ envMapRotation の初期化
    │
    └─ setValues (parameters)
           └─ Material.setValues (inherited)
```

### データフロー図

```
[入力]                      [処理]                           [出力]

parameters ────────▶ constructor() ────────▶ MeshStandardMaterial
  (color, roughness,   - super()呼び出し        インスタンス
   metalness, map,     - defines設定            (PBRシェーダーで
   roughnessMap,       - プロパティ初期化        使用される
   metalnessMap,       - setValues()適用         マテリアル設定)
   envMap, etc.)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Material.js | `src/materials/Material.js` | ソース | マテリアル基底クラス |
| MeshStandardMaterial.js | `src/materials/MeshStandardMaterial.js` | ソース | PBR標準マテリアル実装 |
| Color.js | `src/math/Color.js` | ソース | 色データ管理 |
| Vector2.js | `src/math/Vector2.js` | ソース | 2次元ベクトル（normalScale用） |
| Euler.js | `src/math/Euler.js` | ソース | オイラー角（envMapRotation用） |
| constants.js | `src/constants.js` | ソース | 定数定義（TangentSpaceNormalMap等） |
| PMREMGenerator.js | `src/extras/PMREMGenerator.js` | ソース | 環境マップの前処理 |
| EventDispatcher.js | `src/core/EventDispatcher.js` | ソース | イベント管理 |
