# 機能設計書 9-RenderTarget

## 概要

本ドキュメントは、Three.jsライブラリにおけるオフスクリーンレンダリング機能を提供するRenderTargetクラスの機能設計について記述する。RenderTargetは、シーンを画面ではなくテクスチャにレンダリングするためのバッファを提供し、ポストプロセッシングや動的テクスチャ生成などの高度なレンダリング技術を可能にする。

### 本機能の処理概要

RenderTargetクラスは、GPU上のフレームバッファオブジェクト（FBO）を抽象化し、カラーアタッチメント（テクスチャ）、デプスバッファ、ステンシルバッファの管理を行う。レンダラーはこのRenderTargetを指定してシーンをレンダリングし、結果をテクスチャとして後続の処理で使用できる。

**業務上の目的・背景**：モダンな3Dグラフィックスでは、最終出力前に複数のレンダリングパスを実行することが一般的である。例えば、シャドウマップ、反射マップ、ポストプロセッシングエフェクト（ブルーム、モーションブラー等）、ピッキング用IDレンダリングなど、多くの技術がオフスクリーンレンダリングを必要とする。RenderTargetはこれらの技術の基盤となる機能を提供する。

**機能の利用シーン**：
- ポストプロセッシングエフェクト（EffectComposer）
- シャドウマップのレンダリング
- 環境マップ（CubeCamera）の動的生成
- ピッキング用IDレンダリング
- G-Buffer（遅延レンダリング）
- MRT（Multiple Render Targets）

**主要な処理内容**：
1. **サイズ管理**: width、height、depthプロパティによるレンダーターゲットサイズ管理
2. **テクスチャ管理**: texturesプロパティによる複数カラーアタッチメントの管理
3. **デプスバッファ**: depthBuffer、depthTextureによる深度情報の管理
4. **ステンシルバッファ**: stencilBufferによるステンシル情報の管理
5. **ビューポート/シザー**: viewport、scissorによる部分レンダリングの制御
6. **MSAA**: samplesプロパティによるマルチサンプリング
7. **リソース解放**: dispose()によるGPUリソースの解放

**関連システム・外部連携**：
- WebGLRenderer/WebGPURendererのsetRenderTarget()メソッド
- EffectComposerによるポストプロセッシングパイプライン
- CubeCameraによる環境マップ生成
- ShadowMapによるシャドウレンダリング

**権限による制御**：特になし（ライブラリレベルの機能のため、アプリケーション側での権限管理は行わない）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | WebGL上級サンプル | 主機能 | ポストプロセッシング等のオフスクリーンレンダリング |

## 機能種別

レンダリング / リソース管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| width | number | No | レンダーターゲットの幅 | デフォルト: 1 |
| height | number | No | レンダーターゲットの高さ | デフォルト: 1 |
| options.generateMipmaps | boolean | No | ミップマップ生成 | デフォルト: false |
| options.minFilter | number | No | 縮小フィルタ | デフォルト: LinearFilter |
| options.magFilter | number | No | 拡大フィルタ | 継承 |
| options.format | number | No | テクスチャフォーマット | 継承 |
| options.type | number | No | テクスチャタイプ | 継承 |
| options.depthBuffer | boolean | No | デプスバッファ有無 | デフォルト: true |
| options.stencilBuffer | boolean | No | ステンシルバッファ有無 | デフォルト: false |
| options.depthTexture | DepthTexture | No | デプステクスチャ | デフォルト: null |
| options.samples | number | No | MSAAサンプル数 | デフォルト: 0 |
| options.count | number | No | カラーアタッチメント数 | デフォルト: 1 |
| options.depth | number | No | テクスチャ深度 | デフォルト: 1 |

### 入力データソース

- コンストラクタ引数
- setSize()メソッドの呼び出し
- レンダラーからのレンダリング結果

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| texture | Texture | メインカラーアタッチメントテクスチャ |
| textures | Array<Texture> | すべてのカラーアタッチメントテクスチャ |
| depthTexture | DepthTexture | デプステクスチャ（設定時） |
| width | number | ターゲット幅 |
| height | number | ターゲット高さ |
| viewport | Vector4 | ビューポート設定 |
| scissor | Vector4 | シザー設定 |

### 出力先

- シェーダーのuniform sampler2Dとしてアクセス
- ポストプロセッシングパイプラインへの入力
- disposeイベントによるリソース解放通知

## 処理フロー

### 処理シーケンス

```
1. RenderTargetインスタンス生成
   └─ コンストラクタ(width, height, options)
       └─ EventDispatcher初期化
       └─ オプションのデフォルト値設定
       └─ width, height, depth設定
       └─ viewport, scissor初期化
       └─ テクスチャ配列生成（count個）
       └─ depthBuffer, stencilBuffer設定
       └─ depthTexture設定
       └─ samples設定

2. レンダラーへの設定
   └─ renderer.setRenderTarget(renderTarget)
       └─ フレームバッファをバインド
       └─ viewport, scissorを適用

3. レンダリング
   └─ renderer.render(scene, camera)
       └─ テクスチャにシーンをレンダリング

4. テクスチャ使用
   └─ material.map = renderTarget.texture
   └─ シェーダーでsampler2Dとしてアクセス

5. サイズ変更
   └─ setSize(width, height, depth)
       └─ サイズ更新
       └─ 全テクスチャのimage更新
       └─ dispose()呼び出し（リソース再生成のため）
       └─ viewport, scissor更新

6. リソース解放
   └─ dispose()
       └─ disposeイベント発行
       └─ GPUリソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[RenderTarget生成] --> B[オプション処理]
    B --> C[テクスチャ配列生成]
    C --> D[バッファ設定]
    D --> E{レンダリング?}
    E -->|Yes| F[setRenderTarget]
    F --> G[render]
    G --> H[テクスチャにレンダリング]
    H --> I{テクスチャ使用?}
    I -->|Yes| J[material.map等に設定]
    J --> K[シェーダーで参照]
    K --> E
    I -->|No| L{サイズ変更?}
    L -->|Yes| M[setSize]
    M --> N[dispose + 再生成]
    N --> E
    L -->|No| O{破棄?}
    O -->|Yes| P[dispose]
    P --> Q[disposeイベント]
    O -->|No| E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルトサイズ | width=1, height=1がデフォルト | コンストラクタ |
| BR-02 | ミップマップ無効 | レンダーターゲットはデフォルトでミップマップ生成しない | コンストラクタ |
| BR-03 | フィルタ設定 | デフォルトはLinearFilter（バイリニア） | コンストラクタ |
| BR-04 | サイズ変更時dispose | setSize()でサイズが変わるとdispose()が呼ばれる | setSize() |
| BR-05 | MRT対応 | countオプションで複数カラーアタッチメント | コンストラクタ |
| BR-06 | depthTexture参照管理 | depthTextureのrenderTarget参照を自動管理 | setter |

### 計算ロジック

**テクスチャ配列の生成:**
```javascript
const texture = new Texture(image);
this.textures = [];
for (let i = 0; i < count; i++) {
    this.textures[i] = texture.clone();
    this.textures[i].isRenderTargetTexture = true;
    this.textures[i].renderTarget = this;
}
```

**サイズ変更処理:**
```javascript
setSize(width, height, depth = 1) {
    if (this.width !== width || this.height !== height || this.depth !== depth) {
        // テクスチャのimage更新
        for (const texture of this.textures) {
            texture.image.width = width;
            texture.image.height = height;
            texture.image.depth = depth;
        }
        this.dispose(); // GPUリソース再生成のため
    }
    // viewport, scissor更新
}
```

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

### 操作別データベース影響一覧

該当なし（RenderTargetはデータベースを使用しない）

## エラー処理

### エラーケース一覧

該当なし（RenderTargetは明示的なエラー処理を行わない）

### リトライ仕様

該当なし

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

該当なし（GPUリソース管理のみ）

## パフォーマンス要件

- サイズ変更は高コスト（GPUリソース再生成）のため、頻繁な変更は避ける
- 大きなサイズのレンダーターゲットはVRAMを消費
- samplesを増やすとMSAAのコストが増加
- MRT（複数カラーアタッチメント）は帯域幅を消費

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

該当なし（クライアントサイドのグラフィックスライブラリ）

## 備考

- WebGLRendererではWebGLRenderTargetを、WebGPURendererではRenderTargetを直接使用
- multiviewオプションはVRのマルチビューレンダリング用
- resolveDepthBuffer/resolveStencilBufferはMSAAリゾルブの制御

---

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

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

### 推奨読解順序

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

RenderTargetが使用する関連クラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Texture.js | `src/textures/Texture.js` | テクスチャの基本構造 |
| 1-2 | Vector4.js | `src/math/Vector4.js` | viewport/scissorの表現 |

**読解のコツ**: RenderTargetのtexturesプロパティはTextureの配列。各TextureにはisRenderTargetTexture=trueが設定される。

#### Step 2: コンストラクタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RenderTarget.js | `src/core/RenderTarget.js` | コンストラクタでのオプション処理とテクスチャ生成 |

**主要処理フロー**:
- **49-203行目**: コンストラクタ
- **53-66行目**: オプションのデフォルト値設定
- **83-91行目**: width, height, depth設定
- **108行目**: scissorの初期化
- **125行目**: viewportの初期化
- **129行目**: imageオブジェクト生成
- **137-146行目**: texturesの配列生成（count個）
- **148行目**: テクスチャオプション適用
- **156-180行目**: バッファ設定

#### Step 3: テクスチャアクセスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RenderTarget.js | `src/core/RenderTarget.js` | textureゲッター/セッター、depthTextureゲッター/セッター |

**主要処理フロー**:
- **242-252行目**: textureゲッター/セッター（textures[0]へのエイリアス）
- **254-275行目**: depthTextureゲッター/セッター（renderTarget参照管理付き）

#### Step 4: サイズ変更を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | RenderTarget.js | `src/core/RenderTarget.js` | setSize()メソッド |

**主要処理フロー**:
- **284-317行目**: setSize() - サイズ変更処理
- **286行目**: サイズ変更チェック
- **292-308行目**: テクスチャのimage更新とisArrayTexture設定
- **310行目**: dispose()呼び出し
- **314-315行目**: viewport/scissor更新

#### Step 5: リソース管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | RenderTarget.js | `src/core/RenderTarget.js` | clone(), copy(), dispose() |

**主要処理フロー**:
- **324-328行目**: clone() - 複製
- **338-376行目**: copy() - コピー（テクスチャもクローン）
- **384-388行目**: dispose() - リソース解放とイベント発行

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

```
RenderTarget (extends EventDispatcher)
    │
    ├─ constructor(width, height, options)
    │      ├─ super() → EventDispatcher
    │      ├─ オプションのデフォルト値設定
    │      ├─ viewport = new Vector4()
    │      ├─ scissor = new Vector4()
    │      ├─ textures[] = Texture.clone() × count
    │      ├─ _setTextureOptions(options)
    │      └─ depthTexture設定
    │
    ├─ texture [getter/setter]
    │      └─ textures[0]へのエイリアス
    │
    ├─ depthTexture [getter/setter]
    │      ├─ [setter] 旧depthTexture.renderTarget = null
    │      ├─ [setter] 新depthTexture.renderTarget = this
    │      └─ [getter] _depthTextureを返す
    │
    ├─ setSize(width, height, depth)
    │      ├─ サイズ変更チェック
    │      ├─ textures[].image更新
    │      ├─ dispose()
    │      └─ viewport/scissor更新
    │
    ├─ clone()
    │      └─ new this.constructor().copy(this)
    │
    ├─ copy(source)
    │      ├─ サイズコピー
    │      ├─ textures[]クローン
    │      ├─ depthTextureクローン
    │      └─ バッファ設定コピー
    │
    └─ dispose()
           └─ dispatchEvent({ type: 'dispose' })
```

### データフロー図

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

width, height ─────┐
                   │
options ──────────┼─→ constructor() ────→ RenderTarget
                   │                           │
                   │                           ├─→ textures[]
                   │                           ├─→ viewport
                   │                           ├─→ scissor
                   │                           └─→ depthTexture
                   │
                   ↓
              ┌─────────────────────┐
              │ setRenderTarget()   │
              │ (WebGLRenderer)     │
              └─────────────────────┘
                        │
                        ↓
              ┌─────────────────────┐
              │ render(scene,camera)│
              │                     │
              │ シーンを            │
              │ テクスチャにレンダリング
              └─────────────────────┘
                        │
                        ↓
              ┌─────────────────────┐
              │ renderTarget.texture│──→ material.map
              │                     │──→ shader uniform
              └─────────────────────┘
                        │
                        ↓
              ┌─────────────────────┐
              │ dispose()           │
              │ disposeイベント     │
              └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RenderTarget.js | `src/core/RenderTarget.js` | ソース | RenderTargetクラス本体 |
| EventDispatcher.js | `src/core/EventDispatcher.js` | ソース | イベント機能の基底クラス |
| Texture.js | `src/textures/Texture.js` | ソース | テクスチャクラス |
| Source.js | `src/textures/Source.js` | ソース | テクスチャソース |
| Vector4.js | `src/math/Vector4.js` | ソース | viewport/scissor用 |
| constants.js | `src/constants.js` | ソース | LinearFilter等の定数 |
| WebGLRenderTarget.js | `src/renderers/WebGLRenderTarget.js` | ソース | WebGL用派生クラス |
