# 機能設計書 65-ShadowMaterial

## 概要

本ドキュメントは、Three.jsライブラリにおける影専用マテリアル「ShadowMaterial」の機能設計について記述する。ShadowMaterialは、影を受け取りつつ自身は透明に描画される特殊なマテリアルで、影のみを表示する地面やキャッチャーオブジェクトの作成に使用される。

### 本機能の処理概要

ShadowMaterialは、オブジェクト自体は完全に透明でありながら、他のオブジェクトから投影される影を受け取って表示することができるマテリアルクラスである。ARアプリケーションでの影合成や、製品ビューアでの影キャッチャーとして使用される。

**業務上の目的・背景**：3Dビジュアライゼーションにおいて、オブジェクトの影を地面に表示したいが、地面自体は見えなくしたいというニーズがある。例えば、AR（拡張現実）アプリケーションでは、仮想オブジェクトの影を現実世界の地面に合成する必要がある。また、製品ビューアやコンフィギュレーターでは、製品の下に自然な影を表示しつつ、背景を透明にして他のUI要素と重ねたい場合がある。ShadowMaterialは、このような「影だけを表示する透明な面」を実現するための専用マテリアルである。

**機能の利用シーン**：
- ARアプリケーションでの影合成
- 製品ビューア・コンフィギュレーターでの影キャッチャー
- 360度製品プレビューでの床面影表示
- 建築ビジュアライゼーションでの影検証
- ゲーム内での透明な影受けオブジェクト

**主要な処理内容**：
1. マテリアルプロパティの初期化（色、透明度）
2. デフォルトで透明マテリアルとして設定
3. 影を受け取りつつ自身は透明として描画
4. 影の色のカスタマイズ

**関連システム・外部連携**：WebGLRenderer/WebGPURendererと連携。シャドウマップと組み合わせて使用。

**権限による制御**：特になし（クライアントサイドライブラリ）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接の関連画面なし |

## 機能種別

データ定義 / 外観設定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| color | number/Color/string | No | 影の色（デフォルト: 0x000000 黒） | Color.setで受け付ける形式 |
| transparent | boolean | No | 透明度有効化（デフォルト: true） | boolean |
| opacity | number | No | 不透明度（デフォルト: 1.0、Material基底クラスから） | 0.0-1.0 |
| fog | boolean | No | フォグの影響を受けるか（デフォルト: true） | boolean |

### 入力データソース

コンストラクタのparametersオブジェクトから入力。receiveShadow=trueをメッシュに設定する必要がある。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isShadowMaterial | boolean | 型判定用フラグ（常にtrue） |
| type | string | マテリアルタイプ識別子（'ShadowMaterial'） |
| color | Color | 影の色（デフォルト黒） |
| transparent | boolean | 透明度フラグ（デフォルトtrue） |
| fog | boolean | フォグ影響フラグ |

### 出力先

レンダラー（WebGLRenderer/WebGPURenderer）に描画パラメータとして提供される。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ Material基底クラスのコンストラクタ実行
2. デフォルトプロパティの初期化
   └─ isShadowMaterial, type, color(黒), transparent(true), fog
3. setValues(parameters)でパラメータ適用
4. メッシュに適用（receiveShadow=trueを設定）
5. レンダリング時:
   a. シャドウマップから影情報を取得
   b. 影の部分のみマテリアルのcolorで描画
   c. 影のない部分は完全透明として描画
```

### フローチャート

```mermaid
flowchart TD
    A[new ShadowMaterial] --> B[super - Material初期化]
    B --> C[デフォルト値設定]
    C --> D[color = 黒]
    D --> E[transparent = true]
    E --> F{parameters存在?}
    F -->|Yes| G[setValues実行]
    F -->|No| H[初期化完了]
    G --> H
    H --> I[メッシュに適用]
    I --> J{mesh.receiveShadow?}
    J -->|true| K[シャドウマップから影取得]
    J -->|false| L[影なしで描画]
    K --> M[影部分のみ描画]
    M --> N[影なし部分は透明]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-65-1 | デフォルト透明 | ShadowMaterialはデフォルトでtransparent=trueが設定される | 常時 |
| BR-65-2 | デフォルト黒色 | colorのデフォルト値は黒（0x000000）で、一般的な影の色を表現 | 常時 |
| BR-65-3 | receiveShadow必須 | 影を表示するにはメッシュのreceiveShadow=trueが必要 | 影表示時 |
| BR-65-4 | シャドウマップ必須 | 影を表示するにはレンダラーでシャドウマップが有効である必要がある | 影表示時 |

### 計算ロジック

影の不透明度は、シャドウマップの値とmaterial.opacityの組み合わせで決定される:
```
最終的なアルファ = シャドウ強度 * opacity
```

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

該当なし（クライアントサイドライブラリ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 視覚的問題 | receiveShadow=falseの場合 | メッシュのreceiveShadowをtrueに設定 |
| - | 視覚的問題 | シャドウマップ未有効 | renderer.shadowMap.enabled=trueに設定 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- シャドウマップのサイズに依存
- 透明オブジェクトとしてソートされるため、描画順序に注意

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

特になし（クライアントサイドライブラリ）

## 備考

- 影を投影するライトでcastShadow=trueが必要
- 影を落とすオブジェクトでcastShadow=trueが必要
- 非常にシンプルな実装（92行程度）

---

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

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

### 推奨読解順序

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

まず、ShadowMaterialが継承するMaterialクラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Material.js | `src/materials/Material.js` | 基底クラスのプロパティ（transparent、opacity等） |
| 1-2 | Color.js | `src/math/Color.js` | colorプロパティで使用されるColorクラス |

**読解のコツ**: Material.jsのtransparentプロパティ（119-122行目）がデフォルトfalseであることを確認し、ShadowMaterialでtrueに上書きされることを理解する。

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

ShadowMaterialクラス自体の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ShadowMaterial.js | `src/materials/ShadowMaterial.js` | クラス全体（92行程度の簡潔な実装） |

**主要処理フロー**:
1. **22-33行目**: コンストラクタ開始、parametersの受け取り
2. **37-44行目**: isShadowMaterialフラグ、type設定
3. **48-54行目**: colorプロパティ初期化（**デフォルト黒 0x000000**）
4. **56-63行目**: transparentプロパティ（**デフォルトtrue**）
5. **65-71行目**: fogプロパティ
6. **73行目**: setValuesでパラメータ適用
7. **77-87行目**: copyメソッドの実装

#### Step 3: 影の仕組みを理解する

ShadowMaterialが影を表示する仕組みを理解するため、シャドウマップ関連を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | shadow.glsl.js | `src/renderers/shaders/ShaderChunk/shadow.glsl.js` | 影計算のシェーダーチャンク |
| 3-2 | shadowmask_pars_fragment.glsl.js | `src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js` | シャドウマスク |

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

```
ShadowMaterial (継承: Material)
    │
    ├─ constructor(parameters)
    │      │
    │      ├─ super() → Material.constructor()
    │      │                 └─ EventDispatcher()
    │      │
    │      ├─ this.color = new Color(0x000000)  ← 黒（影の色）
    │      ├─ this.transparent = true           ← 重要：透明有効
    │      │
    │      └─ setValues(parameters)
    │               └─ Material.setValues()
    │
    ├─ copy(source)
    │      │
    │      ├─ super.copy(source)
    │      ├─ this.color.copy(source.color)
    │      └─ this.fog = source.fog
    │
    └─ [レンダリング時]
           │
           ├─ シャドウマップ参照
           │
           └─ 影部分: color描画
              影なし: 透明描画
```

### データフロー図

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

parameters ───────▶ ShadowMaterial.constructor()
{                           │
  color: 0x333333,          ├─ プロパティ初期化
  opacity: 0.5              ├─ color = 黒（デフォルト）
}                           └─ transparent = true
                                         │
                                         ▼
                              マテリアルインスタンス
                                         │
                                         ▼
                              Mesh (receiveShadow=true)
                                         │
                     ┌───────────────────┴───────────────────┐
                     ▼                                       ▼
              シャドウマップ                          フラグメントシェーダー
              (影情報)                               (影描画判定)
                     │                                       │
                     └───────────────────┬───────────────────┘
                                         ▼
                              ┌─────────────────────┐
                              │ 影部分: color表示   │
                              │ 影なし: 完全透明    │
                              └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ShadowMaterial.js | `src/materials/ShadowMaterial.js` | ソース | ShadowMaterialクラス定義 |
| Material.js | `src/materials/Material.js` | ソース | 基底マテリアルクラス |
| Color.js | `src/math/Color.js` | ソース | 色管理クラス |
| shadow.glsl.js | `src/renderers/shaders/ShaderChunk/shadow.glsl.js` | シェーダー | 影計算シェーダーチャンク |
| shadowmask_pars_fragment.glsl.js | `src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js` | シェーダー | シャドウマスク |
| WebGLShadowMap.js | `src/renderers/webgl/WebGLShadowMap.js` | ソース | シャドウマップ管理 |
