# 帳票設計書 8-KTX2Exporter

## 概要

本ドキュメントは、Three.jsライブラリにおけるKTX2Exporterの帳票設計書である。KTX2ExporterはテクスチャデータをKTX2形式でエクスポートするためのモジュールであり、GPU圧縮テクスチャフォーマット出力に対応する。

### 本帳票の処理概要

KTX2Exporterは、Three.jsのDataTexture、Data3DTexture、またはRenderTargetをKTX2形式に変換してエクスポートする機能を提供する。KTX2形式はKhronos Groupが策定したGPUテクスチャコンテナフォーマットで、複数のカラースペースとデータ型に対応する。

**業務上の目的・背景**：KTX2形式はglTFエコシステムにおける標準的なテクスチャフォーマットとして採用されており、WebGL/WebGPUアプリケーションでの高効率なテクスチャ読み込みを実現する。特にBasis Universal圧縮と組み合わせることで、プラットフォームに依存しないGPU圧縮テクスチャの配布が可能となる。PMREMジェネレーターで生成した環境マップの保存に最適。

**帳票の利用シーン**：環境マップ（PMREM）のKTX2形式保存、glTFアセットに埋め込むテクスチャ準備、クロスプラットフォームGPU圧縮テクスチャ作成、物理ベースレンダリング用HDRテクスチャ出力時に利用される。

**主要な出力内容**：
1. KTX2ファイルヘッダー（識別子、バージョン、フォーマット情報）
2. データフォーマット記述子（DFD）
3. キー・バリューデータ（KTXwriter等のメタデータ）
4. レベルデータ（ミップマップレベル）
5. ピクセルデータ（非圧縮、各種フォーマット）

**帳票の出力タイミング**：ユーザーがエクスポート操作を実行した時点でparseメソッドを呼び出すことで非同期に出力される。RenderTargetの場合はピクセル読み取りが必要なため非同期処理となる。

**帳票の利用者**：WebGL/WebGPU開発者、glTFコンテンツ制作者、テクスチャ最適化担当者、ゲーム開発者が主な利用者である。

## 帳票種別

テクスチャデータ出力（バイナリファイル）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Three.js アプリケーション | N/A（ライブラリ使用） | KTX2Exporter.parse() メソッド呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | KTX2 (.ktx2) |
| 用紙サイズ | N/A（テクスチャファイル） |
| 向き | N/A |
| ファイル名 | 任意（アプリケーション側で指定） |
| 出力方法 | Uint8Array として返却 |
| 文字コード | N/A（バイナリ） |

### KTX2固有設定

本エクスポーターはオプションパラメータを持たず、入力テクスチャのプロパティから自動的にフォーマットを決定する。

| 入力プロパティ | 対応するVkFormat |
|--------------|-----------------|
| RGBAFormat + FloatType | VK_FORMAT_R32G32B32A32_SFLOAT |
| RGBAFormat + HalfFloatType | VK_FORMAT_R16G16B16A16_SFLOAT |
| RGBAFormat + UnsignedByteType + sRGB | VK_FORMAT_R8G8B8A8_SRGB |
| RGBAFormat + UnsignedByteType + Linear | VK_FORMAT_R8G8B8A8_UNORM |
| RGFormat + FloatType | VK_FORMAT_R32G32_SFLOAT |
| RGFormat + HalfFloatType | VK_FORMAT_R16G16_SFLOAT |
| RGFormat + UnsignedByteType | VK_FORMAT_R8G8_UNORM/SRGB |
| RedFormat + FloatType | VK_FORMAT_R32_SFLOAT |
| RedFormat + HalfFloatType | VK_FORMAT_R16_SFLOAT |
| RedFormat + UnsignedByteType | VK_FORMAT_R8_UNORM/SRGB |

## 帳票レイアウト

### レイアウト概要

KTX2ファイルはヘッダー、レベルインデックス、DFD、KVD、レベルデータで構成される。

```
┌─────────────────────────────────────┐
│          KTX2ヘッダー                │
│  - 識別子 (12バイト)                 │
│  - vkFormat                         │
│  - typeSize                         │
│  - pixelWidth, pixelHeight, Depth   │
│  - layerCount, faceCount            │
│  - levelCount                       │
│  - supercompressionScheme           │
├─────────────────────────────────────┤
│        レベルインデックス             │
│  (各ミップレベルのオフセット・サイズ)   │
├─────────────────────────────────────┤
│    データフォーマット記述子（DFD）     │
│  - colorModel (RGBSDA)              │
│  - colorPrimaries (BT709)           │
│  - transferFunction (sRGB/Linear)   │
│  - samples (チャンネル定義)          │
├─────────────────────────────────────┤
│     キー・バリューデータ（KVD）       │
│  - KTXwriter = "three.js REVISION"  │
├─────────────────────────────────────┤
│          レベルデータ                │
│  (ピクセルデータ、各レベル)           │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | identifier | KTX2識別子 | 固定値 | 12バイト |
| 2 | vkFormat | Vulkanフォーマット | texture.format + type + colorSpace | Uint32 |
| 3 | typeSize | データ型サイズ | array.BYTES_PER_ELEMENT | Uint32 |
| 4 | pixelWidth | 画像幅 | texture.image.width | Uint32 |
| 5 | pixelHeight | 画像高さ | texture.image.height | Uint32 |
| 6 | pixelDepth | 3Dテクスチャ深度 | texture.image.depth (3Dのみ) | Uint32 |
| 7 | layerCount | レイヤー数 | 0（未使用） | Uint32 |
| 8 | faceCount | 面数 | 1 | Uint32 |
| 9 | levelCount | ミップレベル数 | 1 | Uint32 |
| 10 | supercompressionScheme | 超圧縮方式 | 0（なし） | Uint32 |

### 明細部（DFD）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | colorModel | カラーモデル | 固定 (RGBSDA) | Uint32 |
| 2 | colorPrimaries | 色原点 | colorSpace依存 | Uint32 |
| 3 | transferFunction | 伝達関数 | colorSpace依存 | Uint32 |
| 4 | samples | チャンネル定義 | channelCount依存 | 配列 |

### フッター部

KTX2フォーマットには明示的なフッターは存在しない。

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| arg1 | DataTexture、Data3DTexture、またはRenderer | Yes |
| arg2 | RenderTarget（Renderer指定時） | 状況による |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | ミップレベル | レベル0から |

### 改ページ条件

N/A（単一ファイル出力）

## データベース参照仕様

### 参照テーブル一覧

本エクスポーターはデータベースを使用せず、Three.jsオブジェクトのメモリ上のデータを直接参照する。

| データソース | 用途 | 参照方法 |
|-------------|------|---------|
| DataTexture | 2Dテクスチャデータ | isDataTexture で判定 |
| Data3DTexture | 3Dテクスチャデータ | isData3DTexture で判定 |
| RenderTarget | レンダリング結果 | isRenderTarget で判定 |
| WebGLRenderer | ピクセル読み取り | isWebGLRenderer で判定 |
| WebGPURenderer | ピクセル読み取り | isWebGPURenderer で判定 |

### テーブル別参照項目詳細

#### DataTexture / Data3DTexture

| 参照項目（プロパティ） | 帳票項目との対応 | 取得条件 | 備考 |
|----------------------|----------------|---------|------|
| image.data | levelData | 必須 | TypedArray |
| image.width | pixelWidth | 必須 | Uint32 |
| image.height | pixelHeight | 必須 | Uint32 |
| image.depth | pixelDepth | Data3DTextureのみ | Uint32 |
| format | vkFormat (部分) | 必須 | RGBAFormat等 |
| type | vkFormat (部分) | 必須 | FloatType等 |
| colorSpace | vkFormat (部分) | 必須 | sRGB等 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| チャンネル数 | getChannelCount(texture) | なし | RGBA:4, RG:2, R:1 |
| VkFormat | VK_FORMAT_MAP[format][type][colorSpace] | なし | マッピングテーブル参照 |
| typeSize | array.BYTES_PER_ELEMENT | なし | 1, 2, or 4 |
| bytesPlane[0] | typeSize * channelCount | なし | 1ピクセルあたりのバイト数 |
| bitOffset | i * array.BYTES_PER_ELEMENT * 8 | なし | チャンネルiのビット位置 |
| bitLength | array.BYTES_PER_ELEMENT * 8 - 1 | なし | ビット長（-1はKTX仕様） |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[parse呼び出し] --> B{引数判定}
    B -->|DataTexture/Data3DTexture| C[texture = arg1]
    B -->|Renderer+RenderTarget| D[toDataTexture]
    C --> E[フォーマット検証]
    D --> E
    E --> F{format対応?}
    F -->|No| G[ERROR_FORMAT]
    F -->|Yes| H{type対応?}
    H -->|No| I[ERROR_TYPE]
    H -->|Yes| J{colorSpace対応?}
    J -->|No| K[ERROR_COLOR_SPACE]
    J -->|Yes| L[コンテナ作成]
    L --> M[vkFormat設定]
    M --> N[typeSize設定]
    N --> O[pixelWidth/Height設定]
    O --> P{Data3DTexture?}
    P -->|Yes| Q[pixelDepth設定]
    P -->|No| R[DFD構築]
    Q --> R
    R --> S[samples設定]
    S --> T[levelData設定]
    T --> U[KTXwriter設定]
    U --> V[write関数呼び出し]
    V --> W[Uint8Array返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 入力エラー | 非対応入力 | "Supported inputs are DataTexture, Data3DTexture, or WebGLRenderer and WebGLRenderTarget" | 正しいオブジェクトを渡す |
| フォーマットエラー | 非対応フォーマット | "Supported formats are RGBAFormat, RGFormat, or RedFormat" | 対応フォーマットを使用 |
| 型エラー | 非対応データ型 | "Supported types are FloatType, HalfFloatType, or UnsignedByteType" | 対応型を使用 |
| 色空間エラー | 非対応色空間 | "Supported color spaces are SRGBColorSpace (UnsignedByteType only), LinearSRGBColorSpace, or NoColorSpace" | 対応色空間を使用 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 解像度: 〜4096×4096 |
| 目標出力時間 | 数十ミリ秒〜数百ミリ秒（非圧縮のため高速） |
| 同時出力数上限 | 1（非同期処理） |

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

- KTX2ファイルはテクスチャデータとメタデータのみを含み、実行可能コードは含まれない
- 出力ファイルへのアクセス制御はアプリケーション側の責務
- KTXwriterメタデータにThree.jsリビジョン情報が含まれる

## 備考

- 本エクスポーターは非圧縮KTX2のみ出力（Basis Universal圧縮は非対応）
- ミップマップは出力されない（levelCount = 1）
- supercompressionSchemeは0（なし）
- ktx-parse.module.jsライブラリを使用してKTX2構造を生成

---

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

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

### 推奨読解順序

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

KTX2フォーマットとVkFormatマッピングを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | KTX2Exporter.js | `examples/jsm/exporters/KTX2Exporter.js` | 55-105行目: VK_FORMAT_MAPの定義 |

**読解のコツ**: Three.jsのformat + type + colorSpaceの組み合わせがVulkanフォーマットにマップされる構造を理解する。

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

parseメソッドの入力判定と検証フローを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | KTX2Exporter.js | `examples/jsm/exporters/KTX2Exporter.js` | 140-277行目: parseメソッド |

**主要処理フロー**:
1. **156-170行**: 入力判定（DataTexture/Data3DTexture/Renderer+RenderTarget）
2. **172-188行**: フォーマット/型/色空間の検証
3. **192-206行**: コンテナ基本情報設定
4. **210-256行**: DFD（データフォーマット記述子）構築
5. **260-267行**: レベルデータとメタデータ設定

#### Step 3: DFD構築を理解する

データフォーマット記述子の構築処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | KTX2Exporter.js | `examples/jsm/exporters/KTX2Exporter.js` | 209-256行目: basicDesc設定 |

**主要処理フロー**:
- **211行**: colorModel = KHR_DF_MODEL_RGBSDA
- **212-214行**: colorPrimaries（NoColorSpaceならUNSPECIFIED、それ以外はBT709）
- **215-217行**: transferFunction（sRGB転送ならSRGB、それ以外はLINEAR）
- **227-256行**: samples配列構築（チャンネルごとにbitOffset、bitLength、sampleLower/Upper）

#### Step 4: RenderTarget変換を理解する

toDataTexture関数によるRenderTargetからの変換を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | KTX2Exporter.js | `examples/jsm/exporters/KTX2Exporter.js` | 281-320行目: toDataTexture関数 |

**主要処理フロー**:
- **287-305行**: データ型に応じたTypedArray生成
- **307-311行**: readRenderTargetPixelsAsync呼び出し
- **315-318行**: DataTexture生成と色空間設定

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

```
KTX2Exporter.parse(arg1, arg2)
    │
    ├─ 入力判定
    │      ├─ isDataTexture || isData3DTexture
    │      │      └─ texture = arg1
    │      └─ isWebGLRenderer || isWebGPURenderer
    │             └─ texture = await toDataTexture(renderer, rtt)
    │
    ├─ フォーマット検証
    │      ├─ VK_FORMAT_MAP[format] 存在チェック
    │      ├─ VK_FORMAT_MAP[format][type] 存在チェック
    │      └─ VK_FORMAT_MAP[format][type][colorSpace] 存在チェック
    │
    ├─ コンテナ初期化
    │      └─ createDefaultContainer()
    │
    ├─ コンテナ設定
    │      ├─ vkFormat = VK_FORMAT_MAP[...][...][...]
    │      ├─ typeSize = array.BYTES_PER_ELEMENT
    │      ├─ pixelWidth = texture.image.width
    │      ├─ pixelHeight = texture.image.height
    │      └─ pixelDepth = texture.image.depth (Data3DTextureのみ)
    │
    ├─ DFD構築
    │      ├─ colorModel = KHR_DF_MODEL_RGBSDA
    │      ├─ colorPrimaries = UNSPECIFIED or BT709
    │      ├─ transferFunction = SRGB or LINEAR
    │      ├─ texelBlockDimension = [0, 0, 0, 0]
    │      ├─ bytesPlane[0] = typeSize * channelCount
    │      └─ samples[] = channelごとの定義
    │
    ├─ レベルデータ設定
    │      ├─ levelCount = 1
    │      └─ levels[0] = { levelData, uncompressedByteLength }
    │
    ├─ メタデータ設定
    │      └─ keyValue['KTXwriter'] = "three.js REVISION"
    │
    └─ write(container, { keepWriter: true })
           └─ Uint8Array返却
```

### データフロー図

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

DataTexture ────────▶ 入力判定 ─────────────────▶ texture
Data3DTexture                                         │
      │                                               │
      └───────────────────────────────────────────────┼───
                                                      │
Renderer ──────────▶ toDataTexture() ──────────▶ DataTexture
RenderTarget               │                          │
      │                    └─ readRenderTargetPixelsAsync()
      │                                               │
      └───────────────────────────────────────────────┼───
                                                      │
texture ───────────▶ フォーマット検証 ─────────▶ VK_FORMAT
      │                    │
      │                    ├─ format → VK_FORMAT_MAP
      │                    ├─ type → [format][type]
      │                    └─ colorSpace → [...][colorSpace]
      │                                               │
      ▼                                               ▼
texture.format ────▶ createDefaultContainer() ─▶ container
texture.type               │
texture.colorSpace         │
      │                    │
      │                    ├─ vkFormat
      │                    ├─ typeSize
      │                    ├─ pixelWidth/Height/Depth
      │                    │
      ▼                    ▼
texture.image.data ▶ DFD構築 ─────────────────▶ basicDesc
      │                    │
      │                    ├─ colorModel
      │                    ├─ colorPrimaries
      │                    ├─ transferFunction
      │                    └─ samples[]
      │                    │
      ▼                    ▼
      └────────────▶ levelData設定 ────────────▶ levels[0]
                           │
                           ▼
                    write(container)
                           │
                           ▼
                      Uint8Array
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| KTX2Exporter.js | `examples/jsm/exporters/KTX2Exporter.js` | ソース | メインエクスポーター実装 |
| ktx-parse.module.js | `examples/jsm/libs/ktx-parse.module.js` | ライブラリ | KTX2コンテナ生成（createDefaultContainer, write） |
| three.module.js | `build/three.module.js` | ソース | Three.jsコアライブラリ（ColorManagement, DataTexture等） |
