# 機能設計書 58-MeshDistanceMaterial

## 概要

本ドキュメントは、Three.jsにおけるMeshDistanceMaterialクラスの機能設計を定義する。MeshDistanceMaterialは、ポイントライトのシャドウマップ実装に内部的に使用されるマテリアルクラスである。光源からの距離値を描画する。

### 本機能の処理概要

MeshDistanceMaterialは、ポイントライト（点光源）のシャドウマッピング用に設計されたマテリアルである。ポイントライトは全方向に光を放射するため、通常の平行投影シャドウマップではなく、キューブマップベースのシャドウマップが必要となる。このマテリアルは、光源からの距離をピクセル値として出力し、オムニディレクショナルシャドウマップの生成に使用される。

**業務上の目的・背景**：ポイントライトのシャドウマッピングでは、全方向からの影を計算する必要がある。MeshDistanceMaterialは、各ピクセルの光源からの距離を記録し、キューブマップの6面にレンダリングすることで、全方向のシャドウ情報を生成する。

**機能の利用シーン**：ポイントライトのシャドウマップ生成（レンダラー内部）、カスタムシャドウキャストの実装時（Object3D.customDistanceMaterialへの割り当て）、透明部分がシャドウをキャストしないようにする場合に使用される。

**主要な処理内容**：
1. マテリアルの初期化とパラメータ設定
2. 光源からの距離値の計算
3. カラーマップとアルファマップによるアルファテスト
4. ディスプレイスメントマップによる頂点変形

**関連システム・外部連携**：WebGLRenderer、WebGPURendererと連携。PointLightのシャドウマップ生成時に内部的に使用される。Object3D.customDistanceMaterialプロパティを通じてカスタマイズ可能。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | （画面機能マッピングに登録なし） |

## 機能種別

マテリアル設定 / 距離シェーディング処理（シャドウマップ用）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| map | Texture | No | カラーマップ（アルファテスト用） | Texture型またはnull |
| alphaMap | Texture | No | アルファマップ | Texture型またはnull |
| displacementMap | Texture | No | ディスプレイスメントマップ | Texture型またはnull |
| displacementScale | number | No | ディスプレイスメントスケール（デフォルト: 1） | 数値 |
| displacementBias | number | No | ディスプレイスメントバイアス（デフォルト: 0） | 数値 |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isMeshDistanceMaterial | boolean | 型判定フラグ（常にtrue） |
| type | string | マテリアルタイプ（'MeshDistanceMaterial'） |
| マテリアルプロパティ | 各種 | 設定されたマテリアル属性 |

### 出力先

WebGLRenderer/WebGPURendererによるシェーダープログラムへの入力（キューブマップシャドウマップ）

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ 親クラスMaterialのコンストラクタを呼び出し
2. 型フラグの設定
   └─ isMeshDistanceMaterial = true
3. マテリアルタイプの設定
   └─ type = 'MeshDistanceMaterial'
4. テクスチャマップの初期化
   └─ map, alphaMap, displacementMap等をnullで初期化
5. パラメータの適用
   └─ setValues(parameters)でパラメータを適用
```

### フローチャート

```mermaid
flowchart TD
    A[開始: new MeshDistanceMaterial] --> B[super() 呼び出し]
    B --> C[isMeshDistanceMaterial = true]
    C --> D[type = 'MeshDistanceMaterial']
    D --> E[テクスチャマップ初期化]
    E --> F[setValues parameters]
    F --> G[終了: マテリアルインスタンス]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 内部使用マテリアル | 主にレンダラー内部でPointLightシャドウに使用 | PointLightのshadow有効時 |
| BR-02 | カスタムシャドウ | Object3D.customDistanceMaterialで影のカスタマイズが可能 | customDistanceMaterial設定時 |
| BR-03 | 透明度対応 | mapまたはalphaMapを使用して透明部分のシャドウを制御 | 透明オブジェクトのシャドウ時 |
| BR-04 | ライト非対応 | ライティングの影響を受けない | 常時 |

### 計算ロジック

距離計算:
- 距離 = length(光源位置 - フラグメント位置)
- この値がキューブマップシャドウマップに書き込まれる

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 非常に軽量な計算（距離計算のみ）
- ポイントライトシャドウは6回のレンダリングが必要（キューブマップの各面）

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

特になし

## 備考

- MeshDepthMaterialと似ているが、距離値（線形）を出力する点が異なる
- ポイントライトシャドウはキューブマップを使用するため、DirectionalLightより計算コストが高い

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Material.js | `src/materials/Material.js` | マテリアルの基底クラス |
| 1-2 | MeshDistanceMaterial.js | `src/materials/MeshDistanceMaterial.js` | 距離マテリアル固有のプロパティ |

**読解のコツ**: MeshDistanceMaterialはMaterialを直接継承し、非常にシンプルなプロパティセットを持つ。wireframeプロパティすら持たない最小限のマテリアルである。

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

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

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

**主要処理フロー**:
1. **25-27行目**: コンストラクタでsuper()を呼び出し
2. **36行目**: isMeshDistanceMaterialフラグをtrueに設定
3. **38行目**: typeを'MeshDistanceMaterial'に設定
4. **47行目**: mapをnullで初期化
5. **62行目**: alphaMapをnullで初期化
6. **75行目**: displacementMapをnullで初期化
7. **85行目**: displacementScaleを1で初期化
8. **95行目**: displacementBiasを0で初期化
9. **97行目**: setValues(parameters)でパラメータを適用

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

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

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

**主要処理フロー**:
- **103行目**: 親クラスのcopyを呼び出し
- **105-111行目**: 全プロパティをコピー

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

```
MeshDistanceMaterial (constructor)
    │
    ├─ Material (super())
    │      └─ EventDispatcher (super())
    │
    └─ setValues (parameters)
           └─ Material.setValues (inherited)
```

### データフロー図

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

parameters ────────▶ constructor() ────────▶ MeshDistanceMaterial
  (map, alphaMap,       - super()呼び出し       インスタンス
   displacementMap,     - プロパティ初期化        (距離シェーダーで
   etc.)                - setValues()適用         使用される
                                                  マテリアル設定)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Material.js | `src/materials/Material.js` | ソース | マテリアル基底クラス |
| MeshDistanceMaterial.js | `src/materials/MeshDistanceMaterial.js` | ソース | 距離マテリアル実装 |
| EventDispatcher.js | `src/core/EventDispatcher.js` | ソース | イベント管理 |
| PointLight.js | `src/lights/PointLight.js` | ソース | ポイントライト（シャドウマップで使用） |
| Object3D.js | `src/core/Object3D.js` | ソース | customDistanceMaterialプロパティ定義 |
