# 機能設計書 21-CubeCamera

## 概要

本ドキュメントは、Three.jsにおけるCubeCamera（キューブカメラ）機能の詳細設計を記述する。CubeCameraは環境マッピング用のリアルタイムリフレクション（反射）を実現するための6面キューブカメラである。

### 本機能の処理概要

CubeCameraは、3D空間内の特定の位置から6方向（+X, -X, +Y, -Y, +Z, -Z）に向けてシーンをレンダリングし、キューブマップテクスチャを生成する特殊なカメラクラスである。

**業務上の目的・背景**：3Dグラフィックスにおいて、リアルタイムの反射効果や環境マッピングは、金属やガラスなどの反射面をリアルに表現するために不可欠な技術である。静的な環境マップでは動的なシーンの変化を反映できないため、CubeCameraを使用してリアルタイムにキューブマップを更新することで、動的に変化するシーンにおいてもリアルな反射効果を実現できる。

**機能の利用シーン**：
- 自動車やバイクなどの金属ボディの反射表現
- ガラスや鏡面のリアルタイムリフレクション
- 水面の環境反射
- PBR（物理ベースレンダリング）マテリアルの環境マップ更新

**主要な処理内容**：
1. 6つのPerspectiveCameraを内部に生成し、各方向に向ける
2. 座標系（WebGL/WebGPU）に応じたカメラの向きを設定
3. 指定されたレンダラーとシーンを使用して6面をレンダリング
4. レンダリング結果をWebGLCubeRenderTargetに書き込み
5. ミップマップの生成とPMREM更新フラグの設定

**関連システム・外部連携**：WebGLRenderer、WebGPURenderer、WebGLCubeRenderTarget、PMREMGeneratorと連携して動作する。

**権限による制御**：特になし（ライブラリ機能として権限制御は行わない）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | - | - | 内部処理機能のため直接の画面関連なし |

## 機能種別

計算処理 / データ生成（キューブマップテクスチャの生成）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| near | number | Yes | カメラのニアクリップ面距離 | 正の数値であること |
| far | number | Yes | カメラのファークリップ面距離 | near より大きい正の数値であること |
| renderTarget | WebGLCubeRenderTarget | Yes | 出力先のキューブレンダーターゲット | WebGLCubeRenderTargetインスタンスであること |

### 入力データソース

- コンストラクタパラメータ（near, far, renderTarget）
- update()メソッド呼び出し時のrendererとsceneオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| renderTarget.texture | CubeTexture | 6面のレンダリング結果を含むキューブテクスチャ |
| needsPMREMUpdate | boolean | PMREMの再生成が必要かどうかのフラグ |

### 出力先

- WebGLCubeRenderTargetのテクスチャバッファ
- マテリアルのenvMapとして使用可能

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ実行
   └─ 6つのPerspectiveCameraを生成（FOV=-90度、アスペクト比1:1）
   └─ 各カメラにレイヤー設定を適用
   └─ 子オブジェクトとして追加

2. update()メソッド呼び出し
   └─ 親がない場合はワールドマトリクスを更新
   └─ 座標系が変更されていれば updateCoordinateSystem() を呼び出し
   └─ 現在のレンダーターゲット、キューブフェイス、ミップマップレベルを保存
   └─ XRを一時的に無効化
   └─ ミップマップ生成を一時的に無効化
   └─ 6方向それぞれについてレンダリング実行（0-5のフェイスインデックス）
   └─ ミップマップ生成フラグを復元（最終フェイスで生成）
   └─ レンダー状態を復元
   └─ needsPMREMUpdateフラグを設定
```

### フローチャート

```mermaid
flowchart TD
    A[update開始] --> B{親オブジェクト<br>が存在?}
    B -->|No| C[updateMatrixWorld実行]
    B -->|Yes| D{座標系が<br>変更された?}
    C --> D
    D -->|Yes| E[updateCoordinateSystem実行]
    D -->|No| F[現在のレンダー状態を保存]
    E --> F
    F --> G[XRを無効化]
    G --> H[ミップマップ生成を無効化]
    H --> I[Face 0-4をレンダリング]
    I --> J[ミップマップ生成を復元]
    J --> K[Face 5をレンダリング]
    K --> L[レンダー状態を復元]
    L --> M[needsPMREMUpdate=true]
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | FOV固定 | 視野角は-90度に固定（負のFOVは特殊処理） | 常時 |
| BR-02 | アスペクト比固定 | アスペクト比は1:1に固定 | 常時 |
| BR-03 | 座標系対応 | WebGLとWebGPUの座標系の違いに対応 | 座標系変更時 |
| BR-04 | XR無効化 | キューブマップ生成中はXRを一時的に無効化 | update実行時 |

### 計算ロジック

- **カメラ向き（WebGL座標系）**：
  - +X: up(0,1,0), lookAt(1,0,0)
  - -X: up(0,1,0), lookAt(-1,0,0)
  - +Y: up(0,0,-1), lookAt(0,1,0)
  - -Y: up(0,0,1), lookAt(0,-1,0)
  - +Z: up(0,1,0), lookAt(0,0,1)
  - -Z: up(0,1,0), lookAt(0,0,-1)

- **カメラ向き（WebGPU座標系）**：
  - +X: up(0,-1,0), lookAt(-1,0,0)
  - -X: up(0,-1,0), lookAt(1,0,0)
  - +Y: up(0,0,1), lookAt(0,1,0)
  - -Y: up(0,0,-1), lookAt(0,-1,0)
  - +Z: up(0,-1,0), lookAt(0,0,1)
  - -Z: up(0,-1,0), lookAt(0,0,-1)

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

該当なし（クライアントサイドのみの処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-01 | Error | 無効な座標系が指定された場合 | 'THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: ' + coordinateSystem |

### リトライ仕様

リトライ処理は不要

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

該当なし（クライアントサイドのみの処理）

## パフォーマンス要件

- 6面のレンダリングを毎フレーム実行するため、レンダーターゲットの解像度に注意
- 高解像度のキューブマップは描画負荷が高いため、適切な解像度選択が重要
- activeMipmapLevelを調整することで、低解像度のミップマップレベルのみ更新可能

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

特になし（ブラウザのセキュリティモデルに依存）

## 備考

- FOVが-90度に設定されているのは、Three.jsの内部的な仕様によるもの
- reversedDepthBufferに対応している（WebGLRendererで使用時）
- ミップマップは最後のフェイス（-Z）レンダリング時にのみ生成される

---

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

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

### 推奨読解順序

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

CubeCameraは内部で6つのPerspectiveCameraを管理する。まず、カメラの基本構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Object3D.js | `src/core/Object3D.js` | CubeCameraの親クラス。位置、回転、子オブジェクト管理を理解 |
| 1-2 | PerspectiveCamera.js | `src/cameras/PerspectiveCamera.js` | 内部で使用される6つのカメラの型 |

**読解のコツ**: CubeCameraはObject3Dを継承しており、PerspectiveCameraを子オブジェクトとして保持する。`this.children`配列で6つのカメラにアクセスできる。

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

CubeCameraの主要なエントリーポイントはコンストラクタとupdate()メソッド。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CubeCamera.js | `src/cameras/CubeCamera.js` | 全体の実装（249行） |

**主要処理フロー**:
1. **47-100行目**: コンストラクタ - 6つのPerspectiveCameraを生成し、レイヤー設定を適用
2. **105-169行目**: updateCoordinateSystem() - 座標系に応じたカメラの向き設定
3. **178-244行目**: update() - 6面のレンダリング実行

#### Step 3: 座標系処理を理解する

WebGLとWebGPUで座標系が異なるため、カメラの向きを適切に設定する必要がある。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | constants.js | `src/constants.js` | WebGLCoordinateSystem, WebGPUCoordinateSystemの定義 |

**主要処理フロー**:
- **115-133行目**: WebGL座標系のカメラ向き設定
- **135-153行目**: WebGPU座標系のカメラ向き設定

#### Step 4: レンダリング処理を理解する

update()メソッドで実際にキューブマップを生成する処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | WebGLCubeRenderTarget.js | `src/renderers/WebGLCubeRenderTarget.js` | 出力先のレンダーターゲット |

**主要処理フロー**:
- **194-196行目**: 現在のレンダー状態を保存
- **200行目**: XRを一時的に無効化
- **204行目**: ミップマップ生成を一時的に無効化
- **209-236行目**: 6面のレンダリング（Face 0-5）
- **238行目**: レンダー状態を復元
- **242行目**: needsPMREMUpdateフラグを設定

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

```
CubeCamera
    |
    +-- constructor(near, far, renderTarget)
    |       |
    |       +-- super() [Object3D]
    |       +-- new PerspectiveCamera() x 6
    |       +-- this.add(camera) x 6
    |
    +-- updateCoordinateSystem()
    |       |
    |       +-- camera.up.set()
    |       +-- camera.lookAt()
    |       +-- camera.updateMatrixWorld()
    |
    +-- update(renderer, scene)
            |
            +-- this.updateMatrixWorld()
            +-- updateCoordinateSystem()
            +-- renderer.getRenderTarget()
            +-- renderer.setRenderTarget()
            +-- renderer.render() x 6
```

### データフロー図

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

near/far/renderTarget ───> CubeCamera構築 ───────────> CubeCameraインスタンス
                                  |
                                  v
                           6xPerspectiveCamera

renderer/scene ──────────> update()実行 ────────────> renderTarget.texture
                                  |                         |
                                  v                         v
                           6面レンダリング           needsPMREMUpdate=true
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CubeCamera.js | `src/cameras/CubeCamera.js` | ソース | CubeCameraクラスの実装 |
| PerspectiveCamera.js | `src/cameras/PerspectiveCamera.js` | ソース | 内部で使用するカメラクラス |
| Object3D.js | `src/core/Object3D.js` | ソース | 親クラス（3Dオブジェクト基底） |
| WebGLCubeRenderTarget.js | `src/renderers/WebGLCubeRenderTarget.js` | ソース | 出力先レンダーターゲット |
| constants.js | `src/constants.js` | ソース | 座標系定数の定義 |
