# 機能設計書 90-DataArrayTexture

## 概要

本ドキュメントは、Three.jsにおける生バッファデータから配列テクスチャを生成する `DataArrayTexture` クラスの機能設計を定義する。DataArrayTextureはTypedArrayから複数レイヤーの3Dテクスチャを生成し、テクスチャアトラス、アニメーションテクスチャ、ボリュームレンダリングなどに使用される。

### 本機能の処理概要

DataArrayTextureクラスは、Textureを継承し、TypedArrayから幅×高さ×深度（レイヤー数）の3次元テクスチャ配列を生成する。WebGL2/WebGPUのTexture2DArray機能を使用し、複数のテクスチャをバインドすることなくシェーダーでレイヤーインデックスを指定してアクセスできる。

**業務上の目的・背景**：3Dアプリケーションにおいて、複数のテクスチャを効率的に管理・切り替える必要がある。テクスチャアトラスの代替として、配列テクスチャを使用することでUV計算が不要になり、ミップマップも正しく生成される。また、ボリュームレンダリングやアニメーションフレームの格納にも使用される。

**機能の利用シーン**：
- テクスチャアトラスの代替（マテリアルごとのテクスチャ）
- アニメーションテクスチャ（フレームをレイヤーとして格納）
- 地形テクスチャ（複数の地面テクスチャをブレンド）
- ボリュームレンダリング（3Dボリュームデータ）
- パーティクルシステムの複数テクスチャ
- デカールシステム

**主要な処理内容**：
1. TypedArrayから3次元テクスチャデータを構築
2. 幅・高さ・深度（レイヤー数）・フォーマット・型の指定
3. wrapRによる深度方向のラッピング設定
4. addLayerUpdate()による部分レイヤー更新の最適化

**関連システム・外部連携**：Texture（基底クラス）、WebGLRenderer/WebGPURenderer、シェーダー（texture2DArray / sampler2DArray）と連携。

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

## 関連画面

画面機能マッピング.csvに本機能（No.90）の関連画面情報は記載されていない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

配列テクスチャ生成 / GPU転送

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data | TypedArray | No | テクスチャデータ（デフォルト: null） | - |
| width | number | No | テクスチャ幅（デフォルト: 1） | - |
| height | number | No | テクスチャ高さ（デフォルト: 1） | - |
| depth | number | No | レイヤー数（デフォルト: 1） | - |

### 入力データソース

- TypedArray: Uint8Array, Uint16Array, Float32Array等
- データレイアウト: RGBA順（RGBAFormatの場合）で幅×高さ×深度分のピクセルデータ
- データは連続したメモリレイアウトで、レイヤー0から順に格納

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isDataArrayTexture | boolean | 型判定フラグ（常にtrue） |
| image | {data, width, height, depth} | 画像定義オブジェクト（深度付き） |
| magFilter | number | 拡大フィルタ（デフォルト: NearestFilter） |
| minFilter | number | 縮小フィルタ（デフォルト: NearestFilter） |
| wrapR | number | 深度ラッピング（デフォルト: ClampToEdgeWrapping） |
| generateMipmaps | boolean | ミップマップ生成フラグ（デフォルト: false） |
| flipY | boolean | 垂直反転フラグ（デフォルト: false） |
| unpackAlignment | number | アライメント（デフォルト: 1） |
| layerUpdates | Set<number> | 更新対象レイヤーのセット |

### 出力先

WebGL/WebGPUテクスチャユニットにバインドされ、シェーダーでsampler2DArrayとして参照される。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ Textureコンストラクタ呼び出し → プロパティ上書き
2. image設定
   └─ {data, width, height, depth}オブジェクトとして設定
3. wrapR設定
   └─ 深度方向のラッピングモード
4. layerUpdates初期化
   └─ 空のSetオブジェクト
5. 部分更新時
   └─ addLayerUpdate(layerIndex)でレイヤー登録
6. needsUpdate設定
   └─ GPUアップロードトリガー（全体または部分）
```

### フローチャート

```mermaid
flowchart TD
    A[DataArrayTexture生成] --> B[Textureコンストラクタ呼び出し]
    B --> C[isDataArrayTexture=true設定]
    C --> D[image設定: data,width,height,depth]
    D --> E[フィルタ設定: NearestFilter]
    E --> F[wrapR=ClampToEdgeWrapping]
    F --> G[generateMipmaps=false]
    G --> H[flipY=false]
    H --> I[unpackAlignment=1]
    I --> J[layerUpdates=new Set]
    J --> K[待機状態]
    K --> L{部分更新?}
    L -->|Yes| M[addLayerUpdate呼び出し]
    M --> N[layerUpdates.add]
    N --> K
    L -->|No| O{needsUpdate?}
    O -->|Yes| P{layerUpdates.size > 0?}
    P -->|Yes| Q[部分レイヤーアップロード]
    Q --> R[clearLayerUpdates]
    R --> K
    P -->|No| S[全体GPUアップロード]
    S --> K
    O -->|No| T[シェーダーで使用]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-90-01 | フィルタデフォルト | mag/minFilterはNearestFilterがデフォルト | 常時 |
| BR-90-02 | wrapRデフォルト | wrapRはClampToEdgeWrappingがデフォルト | 常時 |
| BR-90-03 | flipYデフォルト | flipYはfalseがデフォルト（データそのまま） | 常時 |
| BR-90-04 | mipmapデフォルト | generateMipmapsはfalseがデフォルト | 常時 |
| BR-90-05 | アライメント | unpackAlignmentは1（バイトアライメント） | 常時 |
| BR-90-06 | 部分更新 | addLayerUpdateでレイヤー単位の部分更新が可能 | パフォーマンス最適化時 |
| BR-90-07 | データサイズ | data.length = width * height * depth * チャンネル数 | 常時 |

### 計算ロジック

データサイズの計算:
```javascript
// RGBAFormat, UnsignedByteTypeの場合
dataSize = width * height * depth * 4  // 4 bytes per pixel (RGBA) * layer count

// RGBAFormat, FloatTypeの場合
dataSize = width * height * depth * 4  // 4 floats per pixel * layer count
```

レイヤーオフセットの計算:
```javascript
// layerIndex番目のレイヤーの開始オフセット
layerOffset = width * height * channels * layerIndex
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | - | - |

### リトライ仕様

特になし

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

該当なし

## パフォーマンス要件

- addLayerUpdate()による部分更新で転送データ量を削減
- NearestFilterデフォルトにより補間コストを削減
- unpackAlignment=1で任意サイズのデータに対応
- テクスチャ配列により、バインド切り替えコストを削減

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

特になし（クライアントサイドレンダリング）

## 備考

- WebGL2以上が必要（WebGL1では使用不可）
- TypedArrayの型はformatとtypeに合わせる必要がある
- シェーダーでは`texture(sampler2DArray, vec3(u, v, layer))`でアクセス
- レイヤーインデックスは整数で指定（浮動小数点でも切り捨て）

---

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

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

### 推奨読解順序

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

DataArrayTextureの構造とTextureからの差分を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Texture.js | `src/textures/Texture.js` | 基底クラスのプロパティ |
| 1-2 | DataTexture.js | `src/textures/DataTexture.js` | 比較: 2Dデータテクスチャ |
| 1-3 | constants.js | `src/constants.js` | NearestFilter, ClampToEdgeWrapping等の定数 |

**読解のコツ**: DataArrayTextureはDataTextureに深度（レイヤー）次元とwrapRを追加したもの。

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

DataArrayTextureクラス本体を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DataArrayTexture.js | `src/textures/DataArrayTexture.js` | メインクラス（135行） |

**主要処理フロー**:
1. **19-21行目**: コンストラクタでTextureコンストラクタ呼び出し（nullで初期化）
2. **30行目**: `this.isDataArrayTexture = true`
3. **37行目**: `this.image = { data, width, height, depth }`
4. **47行目**: `this.magFilter = NearestFilter`
5. **57行目**: `this.minFilter = NearestFilter`
6. **66行目**: `this.wrapR = ClampToEdgeWrapping`
7. **76行目**: `this.generateMipmaps = false`
8. **87行目**: `this.flipY = false`
9. **97行目**: `this.unpackAlignment = 1`
10. **104行目**: `this.layerUpdates = new Set()`

#### Step 3: レイヤー更新メソッドを理解する

部分更新の最適化メカニズムを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DataArrayTexture.js | `src/textures/DataArrayTexture.js` | addLayerUpdate(), clearLayerUpdates() |

**主要処理フロー**:
- **117-121行目**: `addLayerUpdate(layerIndex)` - Setにレイヤーインデックスを追加
- **126-130行目**: `clearLayerUpdates()` - Setをクリア

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

```
DataArrayTexture
    │
    └─ Texture (継承)
           │
           ├─ EventDispatcher (継承)
           │
           ├─ Source (source)
           │      └─ data経由でimageを管理
           │
           └─ プロパティ（上書き/追加）
                  ├─ isDataArrayTexture: true
                  ├─ image: {data, width, height, depth}
                  ├─ magFilter: NearestFilter
                  ├─ minFilter: NearestFilter
                  ├─ wrapR: ClampToEdgeWrapping (追加)
                  ├─ generateMipmaps: false
                  ├─ flipY: false
                  ├─ unpackAlignment: 1
                  └─ layerUpdates: Set<number> (追加)
                         ├─ addLayerUpdate(layerIndex)
                         └─ clearLayerUpdates()
```

### データフロー図

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

TypedArray ───────────▶ DataArrayTexture Constructor ─▶ DataArrayTexture Object
(data)                       │                              │
width, height ───────────────┤                              ├─ isDataArrayTexture: true
depth ───────────────────────┘                              ├─ image: {data,width,height,depth}
                                                            ├─ magFilter: NearestFilter
                                                            ├─ minFilter: NearestFilter
                                                            ├─ wrapR: ClampToEdgeWrapping
                                                            ├─ generateMipmaps: false
                                                            ├─ flipY: false
                                                            ├─ unpackAlignment: 1
                                                            └─ layerUpdates: Set()

addLayerUpdate(i) ─────▶ layerUpdates.add(i) ────────▶ 部分更新マーク

needsUpdate = true ────▶ Texture.needsUpdate ─────────▶ GPU Upload
                             │
                             ├─ layerUpdates.size > 0 → 部分レイヤー更新
                             └─ layerUpdates.size = 0 → 全体更新

clearLayerUpdates() ───▶ layerUpdates.clear() ────────▶ 更新マーククリア
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DataArrayTexture.js | `src/textures/DataArrayTexture.js` | ソース | DataArrayTextureメインクラス |
| Texture.js | `src/textures/Texture.js` | ソース | テクスチャ基底クラス |
| DataTexture.js | `src/textures/DataTexture.js` | ソース | 2Dデータテクスチャ（比較参照） |
| Source.js | `src/textures/Source.js` | ソース | 画像データソース |
| constants.js | `src/constants.js` | ソース | 定数（NearestFilter, ClampToEdgeWrapping等） |
