# 機能設計書 74-LightShadow

## 概要

本ドキュメントは、Three.jsライブラリにおけるLightShadow（ライトシャドウ）機能の設計を記述する。LightShadowは、光源が生成するシャドウマップの設定と管理を行う抽象基底クラスである。

### 本機能の処理概要

LightShadowは、DirectionalLight、SpotLight、PointLightなどの光源が生成する影（シャドウ）の設定を管理するクラスである。シャドウマップの解像度、バイアス、ブラー半径などのパラメータを管理し、レンダラーがシャドウマッピングを実行するために必要な行列やカメラ情報を提供する。

**業務上の目的・背景**：3Dグラフィックスにおいて、影は空間的な深さとリアリズムを表現するための重要な要素である。LightShadowクラスは、各光源タイプに応じたシャドウマップの生成と管理を統一的に行うためのフレームワークを提供する。シャドウアクネ（影のアーティファクト）やピーターパン現象（影の浮き）を防ぐためのバイアス設定や、ソフトシャドウを実現するためのブラー設定など、影の品質を制御する機能を備える。

**機能の利用シーン**：リアルタイム3Dシーンでの影生成、ゲームやシミュレーションでの照明効果、建築ビジュアライゼーションでの影表現、インタラクティブな3Dアプリケーション。

**主要な処理内容**：
1. シャドウマップ用カメラ（視点）の管理
2. シャドウマップの解像度（mapSize）設定
3. バイアス（bias, normalBias）によるアーティファクト制御
4. ブラー半径（radius）によるソフトシャドウ設定
5. シャドウ行列の計算と管理
6. 視錐台（Frustum）の管理

**関連システム・外部連携**：WebGLRenderer/WebGPURendererのシャドウマップレンダリングパイプライン、DirectionalLightShadow、SpotLightShadow、PointLightShadowなどの派生クラス。

**権限による制御**：特になし。

## 関連画面

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

## 機能種別

シャドウマップ管理 / レンダリング設定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| camera | Camera | Yes | 光源から見たシーンを撮影するカメラ | Camera型 |

### 入力データソース

光源クラス（DirectionalLight、SpotLight、PointLight）の内部で生成される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| camera | Camera | シャドウマップ用カメラ |
| intensity | number | シャドウの強度（0-1、デフォルト: 1） |
| bias | number | 深度バイアス（デフォルト: 0） |
| biasNode | Node | ノードベースのバイアス（WebGPU用） |
| normalBias | number | 法線方向バイアス（デフォルト: 0） |
| radius | number | ブラー半径（デフォルト: 1） |
| blurSamples | number | VSMブラーサンプル数（デフォルト: 8） |
| mapSize | Vector2 | シャドウマップ解像度（デフォルト: 512x512） |
| mapType | number | シャドウテクスチャタイプ（デフォルト: UnsignedByteType） |
| map | RenderTarget | 深度マップ（レンダリング時に生成） |
| mapPass | RenderTarget | 分布マップ（VSM用） |
| matrix | Matrix4 | シャドウ行列 |
| autoUpdate | boolean | 自動更新フラグ（デフォルト: true） |
| needsUpdate | boolean | 更新要求フラグ（デフォルト: false） |

### 出力先

レンダラーのシャドウマップレンダリングパイプライン

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ カメラとデフォルトパラメータの設定
2. updateMatrices() - 光源位置に基づく行列更新
   └─ カメラ位置とルックアットの設定
   └─ 投影行列とビュー行列の計算
   └─ 視錐台の更新
   └─ シャドウ行列の計算
3. getViewport() - ビューポート取得
4. getFrameExtents() - フレーム範囲取得
5. dispose() - リソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[LightShadowコンストラクタ]
    B --> C[カメラ設定]
    C --> D[パラメータ初期化]
    D --> E[終了]

    F[updateMatrices] --> G[光源位置取得]
    G --> H[カメラ位置設定]
    H --> I[ターゲット方向設定]
    I --> J[投影行列計算]
    J --> K[視錐台更新]
    K --> L[シャドウ行列計算]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-1 | mapSizeは2の累乗 | シャドウマップ解像度は2の累乗である必要がある | 常時 |
| BR-74-2 | biasの微調整 | biasは0.0001単位で調整してアーティファクトを防ぐ | シャドウアクネ発生時 |
| BR-74-3 | BasicShadowMap非対応 | radiusはBasicShadowMapタイプでは効果がない | shadowMap.type = BasicShadowMap |

### 計算ロジック

**シャドウ行列の計算**：
1. カメラの投影行列とワールド逆行列を乗算
2. 深度値を[0,1]範囲にマッピングするオフセット行列を適用
3. reversedDepthの場合は異なる変換行列を使用

```javascript
// reversedDepth = false の場合
shadowMatrix.set(
    0.5, 0.0, 0.0, 0.5,
    0.0, 0.5, 0.0, 0.5,
    0.0, 0.0, 0.5, 0.5,
    0.0, 0.0, 0.0, 1.0
);
```

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 表示異常 | mapSizeが小さすぎる | mapSizeを増加 |
| - | 表示異常 | シャドウアクネ | biasを調整 |
| - | 表示異常 | ピーターパン現象 | normalBiasを調整 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- シャドウマップの解像度はパフォーマンスに大きく影響
- 複数の光源で影を有効にするとドローコールが増加
- autoUpdate=falseで静的シーンのパフォーマンスを向上可能

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

特になし。

## 備考

- LightShadowは抽象基底クラスであり、直接インスタンス化されることは想定されない
- DirectionalLightShadow、SpotLightShadow、PointLightShadowが派生クラスとして存在
- PointLightは6面のキューブマップシャドウを使用するため、特殊な処理が必要

---

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

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

### 推奨読解順序

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

LightShadowが持つプロパティの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Vector2.js | `src/math/Vector2.js` | mapSizeの型 |
| 1-2 | Matrix4.js | `src/math/Matrix4.js` | シャドウ行列の型 |
| 1-3 | Frustum.js | `src/math/Frustum.js` | 視錐台の型 |

**読解のコツ**: LightShadowは多くの数学クラスを組み合わせてシャドウマッピングを実現している。

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

LightShadowクラスの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LightShadow.js | `src/lights/LightShadow.js` | クラス全体の構造 |

**主要処理フロー**:
1. **25-32行目**: コンストラクタでcameraを受け取る
2. **39-41行目**: intensityの設定（デフォルト1）
3. **52-53行目**: biasの設定（デフォルト0）
4. **74行目**: normalBiasの設定（デフォルト0）
5. **87行目**: radiusの設定（デフォルト1）
6. **104行目**: mapSizeの設定（512x512）
7. **201-238行目**: updateMatrices()メソッド

#### Step 3: 行列計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LightShadow.js | `src/lights/LightShadow.js` | updateMatrices()（201-238行目） |

**主要処理フロー**:
- **203-204行目**: シャドウカメラとシャドウ行列の取得
- **206-211行目**: 光源位置の取得とカメラ位置の設定
- **213-214行目**: 投影行列の計算と視錐台の更新
- **216-234行目**: シャドウ行列の設定（reversedDepth対応）
- **236行目**: 投影行列との乗算

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

```
LightShadow (abstract)
    │
    ├─ DirectionalLightShadow
    │      └─ 平行光源用シャドウ（OrthographicCamera使用）
    │
    ├─ SpotLightShadow
    │      └─ スポットライト用シャドウ（PerspectiveCamera使用）
    │
    └─ PointLightShadow
           └─ 点光源用シャドウ（CubeCamera相当、6面レンダリング）

LightShadow.updateMatrices()
    │
    ├─ Matrix4.setFromMatrixPosition()
    ├─ Camera.lookAt()
    ├─ Camera.updateMatrixWorld()
    ├─ Matrix4.multiplyMatrices()
    └─ Frustum.setFromProjectionMatrix()
```

### データフロー図

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

camera (引数) ────────────────▶ 直接代入 ───────────────────────▶ this.camera
light.matrixWorld ────────────▶ updateMatrices() ──────────────▶ this.matrix
light.target.matrixWorld ────▶ updateMatrices() ──────────────▶ this._frustum

レンダリング時
this.mapSize ─────────────────▶ RenderTarget生成 ──────────────▶ this.map
this.camera ──────────────────▶ シャドウパス描画 ──────────────▶ this.map
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LightShadow.js | `src/lights/LightShadow.js` | ソース | シャドウ設定の基底クラス |
| Matrix4.js | `src/math/Matrix4.js` | ソース | 変換行列クラス |
| Vector2.js | `src/math/Vector2.js` | ソース | 2Dベクトル（mapSize用） |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトル（位置計算用） |
| Vector4.js | `src/math/Vector4.js` | ソース | 4Dベクトル（ビューポート用） |
| Frustum.js | `src/math/Frustum.js` | ソース | 視錐台クラス |
