# 機能設計書 11-UniformsGroup

## 概要

本ドキュメントは、Three.jsライブラリにおけるUniformsGroup機能の設計を詳細に記述するものである。UniformsGroupは、複数のシェーダーユニフォーム変数をグループ化し、単一のUniform Buffer Object (UBO) として効率的にGPUへ転送するための機能を提供する。

### 本機能の処理概要

UniformsGroupクラスは、WebGLにおけるUniform Buffer Object (UBO) の概念を抽象化し、複数のユニフォーム変数を効率的に管理・転送するためのクラスである。

**業務上の目的・背景**：3Dレンダリングにおいて、シェーダープログラムへのユニフォーム変数（定数データ）の転送は頻繁に発生する処理である。従来の個別転送方式では、多数のユニフォーム変数がある場合にCPU-GPU間の通信オーバーヘッドが問題となる。UniformsGroupは複数のユニフォームをまとめて転送することで、この問題を解決し、レンダリングパフォーマンスを向上させる。特に、複数のオブジェクトで共通のユニフォーム（カメラ行列、ライト情報など）を使用する場合に効果的である。

**機能の利用シーン**：カスタムShaderMaterialを使用する際に、複数のシェーダーで共有されるユニフォーム変数をグループ化して効率的に管理したい場合に使用される。典型的な例として、ビュー・プロジェクション行列、ライティングパラメータ、時間ベースのアニメーション値などがある。

**主要な処理内容**：
1. 複数のUniformオブジェクトをグループとして管理
2. ユニフォームの追加・削除機能の提供
3. バッファ使用パターン（StaticDraw、DynamicDraw等）の設定
4. リソースの破棄とイベント通知
5. グループのコピー・クローン機能

**関連システム・外部連携**：WebGL 2のUniform Buffer Object (UBO) 機能と連携し、WebGLRendererのWebGLUniformsGroupsモジュールによって実際のGPUバッファ操作が行われる。ShaderMaterialと組み合わせて使用される。

**権限による制御**：特になし。ただし、WebGL 2コンテキストが必要であり、WebGL 1では利用できない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | UniformsGroupは内部APIであり、直接的な画面関連はない |

## 機能種別

データ管理 / GPU通信最適化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | コンストラクタは引数なし | - |

### 入力データソース

- Uniformオブジェクト（プログラムから追加される）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | number | ユニフォームグループの一意識別子 |
| name | string | グループの名前 |
| usage | number | バッファ使用パターン定数 |
| uniforms | Array&lt;Uniform&gt; | 管理対象のユニフォーム配列 |

### 出力先

- WebGLレンダラーのWebGLUniformsGroupsモジュール（GPU転送用）

## 処理フロー

### 処理シーケンス

```
1. UniformsGroupインスタンスの生成
   └─ 一意のID割り当て、初期プロパティ設定

2. Uniformオブジェクトの追加
   └─ add()メソッドでユニフォームを配列に追加

3. 使用パターンの設定（オプション）
   └─ setUsage()でStaticDraw/DynamicDraw等を指定

4. レンダリング時のバッファ処理
   └─ WebGLUniformsGroupsによるUBOへの転送

5. 不要時のリソース解放
   └─ dispose()でdisposeイベント発行
```

### フローチャート

```mermaid
flowchart TD
    A[UniformsGroup生成] --> B[ID・プロパティ初期化]
    B --> C{Uniformの追加?}
    C -->|Yes| D[add: 配列に追加]
    D --> C
    C -->|No| E{使用パターン設定?}
    E -->|Yes| F[setUsage: usage更新]
    E -->|No| G[レンダリング待機]
    F --> G
    G --> H[WebGLUniformsGroupsによる処理]
    H --> I{破棄要求?}
    I -->|Yes| J[dispose: イベント発行]
    I -->|No| G
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 一意識別子 | 各UniformsGroupは一意のIDを持つ | インスタンス生成時 |
| BR-02 | デフォルト使用パターン | usage初期値はStaticDrawUsage | インスタンス生成時 |
| BR-03 | WebGL 2専用 | UBOはWebGL 2でのみサポート | ShaderMaterial使用時 |

### 計算ロジック

IDはモジュール内のカウンタ変数 `_id` をインクリメントして割り当てる。

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

該当なし（GPU側のメモリ操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 機能制限 | WebGL 1コンテキストでの使用 | WebGL 2環境を使用する |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 複数のユニフォームを単一のバッファ転送にまとめることで、個別転送と比較してCPU-GPU通信オーバーヘッドを削減
- StaticDrawUsage使用時は初回転送のみ、DynamicDrawUsage使用時は毎フレーム転送最適化

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

- GPUメモリへの直接アクセスはWebGL APIを介して行われ、サンドボックス内で安全に動作
- dispose()呼び出しによるリソースリークの防止

## 備考

- EventDispatcherを継承しており、disposeイベントをリッスン可能
- clone()メソッドでユニフォームの深いコピーが行われる
- WebGPURendererでは異なるユニフォーム管理機構が使用される

---

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

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

### 推奨読解順序

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

UniformsGroupの構造とその依存関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | UniformsGroup.js | `src/core/UniformsGroup.js` | クラス定義と全プロパティの把握 |
| 1-2 | EventDispatcher.js | `src/core/EventDispatcher.js` | イベント機構の継承元 |
| 1-3 | Uniform.js | `src/core/Uniform.js` | uniforms配列に格納されるオブジェクトの構造 |

**読解のコツ**: UniformsGroupはEventDispatcherを継承しているため、addEventListener/removeEventListener/dispatchEventメソッドが利用可能。dispose時のクリーンアップ処理に活用される。

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

UniformsGroupのインスタンス化と基本操作を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | UniformsGroup.js | `src/core/UniformsGroup.js` | コンストラクタとメソッド群 |

**主要処理フロー**:
1. **20-64行目**: コンストラクタでID割り当て、isUniformsGroupフラグ、name、usage、uniforms配列を初期化
2. **72-78行目**: add()メソッドでユニフォームを配列に追加
3. **86-94行目**: remove()メソッドでユニフォームを配列から削除
4. **116-122行目**: setUsage()でバッファ使用パターンを設定
5. **130-134行目**: dispose()でdisposeイベントを発行しリソース解放を通知

#### Step 3: WebGLレンダラーとの連携を理解する

UniformsGroupがどのようにWebGLRendererで処理されるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WebGLUniformsGroups.js | `src/renderers/webgl/WebGLUniformsGroups.js` | UBOへの実際の転送処理 |
| 3-2 | WebGLRenderer.js | `src/renderers/WebGLRenderer.js` | uniformsGroupsの初期化（456行目付近） |

**主要処理フロー**:
- **WebGLUniformsGroups**: UniformsGroupをWebGLのUniform Buffer Objectに変換し、GPUへデータを転送

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

```
ShaderMaterial
    │
    └─ UniformsGroup
           │
           ├─ add(uniform) ─────────▶ uniforms配列に追加
           │
           ├─ setUsage(value) ──────▶ usage更新
           │
           └─ dispose() ────────────▶ EventDispatcher.dispatchEvent
                                            │
                                            ▼
                                     WebGLUniformsGroups
                                            │
                                            ▼
                                     WebGL UBO解放
```

### データフロー図

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

Uniformオブジェクト ───▶ UniformsGroup.add() ───▶ uniforms配列
                              │
                              ▼
                     WebGLUniformsGroups ───▶ WebGL Uniform Buffer Object
                              │
                              ▼
                         GPU Memory
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| UniformsGroup.js | `src/core/UniformsGroup.js` | ソース | メインクラス定義 |
| EventDispatcher.js | `src/core/EventDispatcher.js` | ソース | イベント機構の基底クラス |
| Uniform.js | `src/core/Uniform.js` | ソース | 個別ユニフォームの管理 |
| constants.js | `src/constants.js` | ソース | StaticDrawUsage等の定数定義 |
| WebGLUniformsGroups.js | `src/renderers/webgl/WebGLUniformsGroups.js` | ソース | WebGLでのUBO操作 |
| ShaderMaterial.js | `src/materials/ShaderMaterial.js` | ソース | UniformsGroupを使用するマテリアル |
