# 画面設計書 42-ビジュアルシェーダーエディタ

## 概要

本ドキュメントは、Godot Engineエディタにおけるビジュアルシェーダーエディタ（VisualShaderEditor）の画面設計書である。ノードベースのグラフィカルインターフェースを通じてシェーダーを視覚的に作成・編集するための画面仕様を定義する。

### 本画面の処理概要

ビジュアルシェーダーエディタは、プログラミング知識がなくてもシェーダーを作成できるノードベースのビジュアルエディタである。ノードを接続してシェーダーグラフを構築し、リアルタイムでプレビューしながらマテリアルの視覚効果を設計できる。

**業務上の目的・背景**：シェーダープログラミングは高度な専門知識を必要とし、テキストベースのシェーダーコードは習得が困難である。本ビジュアルシェーダーエディタは、ノードをドラッグ＆ドロップで配置・接続するだけでシェーダーを作成でき、アーティストやデザイナーでも直感的にマテリアル効果を実現できる。また、生成されるシェーダーコードのプレビュー機能により、学習ツールとしても活用可能。

**画面へのアクセス方法**：VisualShaderリソースをダブルクリックするか、インスペクタでVisualShaderを選択し「Edit」ボタンをクリックすることで、メインエディタ領域にビジュアルシェーダーエディタが表示される。

**主要な操作・処理内容**：
1. ノードの追加：Add Nodeボタンまたは右クリックメニューからノードを選択して追加
2. ノードの接続：出力ポートから入力ポートへドラッグして接続を作成
3. ノードの編集：ノード内のパラメータを直接編集（定数値、テクスチャ選択など）
4. シェーダータイプの切り替え：Vertex/Fragment/Lightなどのシェーダーステージを切り替え
5. コードプレビュー：生成されるGLSLコードをリアルタイムで確認
6. マテリアルプレビュー：3Dオブジェクトでシェーダー効果をプレビュー
7. Varying変数の管理：シェーダーステージ間でデータを受け渡すVarying変数の追加・削除

**画面遷移**：エディタ内のドッキング領域に表示され、他のリソース編集時は非表示になる。VisualShaderリソースを選択すると再表示される。

**権限による表示制御**：エディタ機能のため、特定の権限制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| F-042 | シェーダー編集 | 主機能 | ビジュアルシェーダーの作成・編集 |
| - | GraphEdit | API連携 | ノードグラフの表示・操作 |
| - | VisualShader | API連携 | シェーダーリソースの管理 |
| - | EditorUndoRedoManager | 補助機能 | 編集操作のUndo/Redo対応 |
| - | MaterialEditor | 補助機能 | マテリアルのプレビュー表示 |
| - | ShaderLanguage | API連携 | シェーダーコードのコンパイル・検証 |

## 画面種別

グラフエディタ（Node-based Graph Editor）

## URL/ルーティング

該当なし（エディタプラグインとして実装）

## 入出力項目

### 入力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | バリデーション | 説明 |
|--------|--------|----------|------|----------|----------------|------|
| VisualShaderリソース | visual_shader | Ref<VisualShader> | 必須 | リソース参照 | 有効なVisualShader | 編集対象のシェーダーリソース |

### 出力項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 編集済みVisualShader | Ref<VisualShader> | ノードグラフが更新されたシェーダーリソース |
| 生成シェーダーコード | String | ビジュアルグラフから生成されたGLSLコード |

## 表示項目

### ツールバーエリア

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| ノード追加ボタン | add_node | Button | ノード追加ダイアログを表示 |
| シェーダータイプ選択 | edit_type | OptionButton | Vertex/Fragment/Lightなどの切り替え |
| Varyingメニュー | varying_button | MenuButton | Varying変数の追加・削除メニュー |
| コードプレビューボタン | code_preview_button | Button | 生成コードプレビューの表示切替 |
| シェーダープレビューボタン | shader_preview_button | Button | マテリアルプレビューの表示切替 |
| ツールメニュー | tools | MenuButton | Expand All / Collapse All |

### グラフエリア

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| グラフエディタ | graph | GraphEdit | ノードグラフの表示・編集領域 |
| ノード | VSGraphNode | GraphNode | 個々のシェーダーノード |
| 接続線 | - | Connection | ノード間の接続 |
| フレーム | GraphFrame | GraphFrame | ノードをグループ化するフレーム |

### サイドパネル

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| パラメータフィルタ | param_filter | LineEdit | パラメータ検索フィルタ |
| パラメータツリー | parameters | Tree | パラメータ一覧表示 |
| マテリアルエディタ | material_editor | MaterialEditor | 3Dプレビュー表示 |

### ノード追加ダイアログ

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| ノードフィルタ | node_filter | LineEdit | ノード検索フィルタ |
| ノードツリー | members | Tree | 利用可能なノード一覧 |
| ノード説明 | node_desc | RichTextLabel | 選択ノードの説明表示 |
| High-endラベル | highend_label | Label | High-end GPU専用ノードの警告 |

## イベント仕様

### 1-ノード追加イベント

**トリガー**: Add Nodeボタン押下、右クリックメニュー、ドラッグ＆ドロップ

**処理内容**:
1. ノード追加ダイアログを表示
2. ノードを選択してダブルクリックまたはOK押下
3. Undo/Redoアクションを作成
4. VisualShaderにノードを追加
5. グラフにノードを描画

**関連メソッド**: `_add_node()` (L3800-4074), `_show_members_dialog()` (L376)

### 2-ノード接続イベント

**トリガー**: 出力ポートから入力ポートへのドラッグ

**処理内容**:
1. 接続の有効性をチェック（can_connect_nodes）
2. 既存接続がある場合は切断
3. Undo/Redoアクションを作成
4. VisualShaderに接続を登録
5. グラフに接続線を描画

**関連メソッド**: `_connection_request()` (L4233-4280)

### 3-ノード切断イベント

**トリガー**: 接続線の右クリック切断、ポートからのドラッグ切断

**処理内容**:
1. Undo/Redoアクションを作成
2. VisualShaderから接続を削除
3. グラフから接続線を削除

**関連メソッド**: `_disconnection_request()` (L4282-4304)

### 4-シェーダータイプ変更イベント

**トリガー**: edit_type OptionButtonの選択変更

**処理内容**:
1. 現在のシェーダータイプを変更（Vertex/Fragment/Light等）
2. グラフを再描画
3. 対応するノードリストを更新

**関連メソッド**: `_type_selected()` (L572)

### 5-ノード削除イベント

**トリガー**: Deleteキー押下、右クリックメニューのDelete

**処理内容**:
1. 選択されたノードの接続をすべて切断
2. フレームからのデタッチ処理
3. Undo/Redoアクションを作成
4. ノードを削除
5. パラメータ参照を更新

**関連メソッド**: `_delete_nodes()` (L4462-4559)

### 6-ノードドラッグイベント

**トリガー**: ノードのドラッグ移動

**処理内容**:
1. ドラッグ位置をバッファに記録
2. ドラッグ終了時にUndo/Redoアクションを作成
3. ノード位置を更新
4. フレームへのアタッチ判定

**関連メソッド**: `_node_dragged()` (L4188-4195), `_nodes_dragged()` (L4197-4231)

### 7-コードプレビュー表示イベント

**トリガー**: code_preview_button押下

**処理内容**:
1. プレビューウィンドウの表示切替
2. シェーダーコードを生成
3. シンタックスハイライト適用
4. エラーがあれば該当行をハイライト

**関連メソッド**: `_show_preview_text()` (L6344-6362), `_update_preview()` (L6374-6442)

### 8-Varying追加イベント

**トリガー**: VaryingメニューのAdd選択

**処理内容**:
1. Varying追加ダイアログを表示
2. 名前・タイプ・モードを入力
3. バリデーションを実行
4. Undo/Redoアクションを作成
5. VisualShaderにVaryingを追加

**関連メソッド**: `_add_varying()` (L4076-4109), `_varying_create()` (L6015-6018)

### 9-定数パラメータ変換イベント

**トリガー**: 右クリックメニューのConvert Constants to Parameters

**処理内容**:
1. 選択された定数ノードを取得
2. 対応するパラメータノードに置換
3. パラメータ名を自動設定
4. グラフを更新

**関連メソッド**: `_convert_constants_to_parameters()` (L4594-4790)

### 10-ノードドロップオン接続イベント

**トリガー**: 接続線上にノードをドロップ

**処理内容**:
1. ドロップ位置の接続線を検出
2. 既存接続を切断
3. 新ノードを接続線に挿入
4. 新しい接続を作成

**関連メソッド**: `_handle_node_drop_on_connection()` (L4422-4460)

## データベース更新仕様

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

本画面はデータベースを使用せず、VisualShaderリソースファイル（.tres/.res）への書き込みを行う。

| 操作（イベント） | 対象データ | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ノード追加 | VisualShader.nodes | INSERT | ノードをシェーダーグラフに追加 |
| ノード削除 | VisualShader.nodes | DELETE | ノードをシェーダーグラフから削除 |
| ノード接続 | VisualShader.connections | INSERT | ノード間の接続を追加 |
| 接続切断 | VisualShader.connections | DELETE | ノード間の接続を削除 |
| ノード位置変更 | VisualShaderNode.position | UPDATE | ノードのグラフ上の位置を更新 |
| Varying追加 | VisualShader.varyings | INSERT | Varying変数を追加 |
| Varying削除 | VisualShader.varyings | DELETE | Varying変数を削除 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | アクション | "Move VisualShader Node(s)" | ノードドラッグ時のUndoアクション名 |
| - | アクション | "Nodes Connected" | 接続作成時のUndoアクション名 |
| - | アクション | "Nodes Disconnected" | 接続切断時のUndoアクション名 |
| - | アクション | "Add Node(s) to Visual Shader" | ノード追加時のUndoアクション名 |
| - | アクション | "Add Varying to Visual Shader: %s" | Varying追加時のUndoアクション名 |
| - | アクション | "Remove Varying from Visual Shader: %s" | Varying削除時のUndoアクション名 |
| - | アクション | "Convert Constant Node(s) To Parameter(s)" | 定数→パラメータ変換時 |
| - | アクション | "Convert Parameter Node(s) To Constant(s)" | パラメータ→定数変換時 |
| - | エラー | "Invalid name for varying." | Varying名が無効な場合 |
| - | エラー | "Varying with that name already exists." | Varying名が重複する場合 |
| - | 警告 | "Boolean type cannot be used with `Vertex -> [Fragment, Light]` varying mode." | Boolean型のVarying制限 |
| - | ヒント | "Drag and drop nodes here to attach them." | フレームノードのヒント |

## 例外処理

| 例外条件 | 処理内容 |
|---------|----------|
| 接続互換性エラー | ポートタイプが互換性のない接続を試みた場合、接続を拒否 |
| シェーダーコンパイルエラー | プレビューウィンドウでエラー行をハイライト、エラーメッセージを表示 |
| 無効なノード削除 | 出力ノード（ID 0, 1）は削除不可 |
| リソース読み込みエラー | テクスチャ等のリソースが見つからない場合、警告を表示 |

## 備考

- 各ノードはカテゴリ別に色分けされたタイトルバーを持つ
- グラフのズーム・パン操作に対応（MSDF フォント使用によりズーム時のエイリアシング軽減）
- ノードのポートプレビュー機能で出力値を視覚的に確認可能
- フレームノードで関連ノードをグループ化可能
- Rerouteノードで接続線を整理可能
- Float定数としてE, Epsilon, Phi, Pi/4, Pi/2, Pi, Tau, Sqrt2が利用可能

---

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

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

### 推奨読解順序

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

ビジュアルシェーダーの核となるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | visual_shader.h | `scene/resources/visual_shader.h` | VisualShaderクラス、Type enum、Connection構造体 |
| 1-2 | visual_shader_editor_plugin.h | `editor/shader/visual_shader_editor_plugin.h` | VisualShaderEditor、VisualShaderGraphPlugin、Link構造体 |

**読解のコツ**: VisualShaderGraphPluginがVisualShaderとGraphEdit間のブリッジとして機能し、links HashMapでノードの状態を管理している。

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

エディタの初期化と表示開始点を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | visual_shader_editor_plugin.cpp | `editor/shader/visual_shader_editor_plugin.cpp` | コンストラクタ（L6514-）でUI構築 |

**主要処理フロー**:
1. **L6514-6522**: EditorNode接続、vs_editor_cache読み込み
2. **L6523-6536**: HSplitContainer、GraphEdit作成
3. **L6527-6565**: GraphEditのシグナル接続（connection_request, delete_nodes_request等）
4. **L6566-6599**: ポートタイプ間の接続互換性設定

#### Step 3: ノード追加処理を理解する

ノード追加の詳細フローを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | visual_shader_editor_plugin.cpp | `editor/shader/visual_shader_editor_plugin.cpp` | _add_node()（L3800-4074）でノード追加ロジック |

**主要処理フロー**:
- **L3800-3850**: ノードタイプに応じたインスタンス生成
- **L3900-3950**: Undo/Redoアクション作成
- **L4000-4030**: 接続自動作成（ドラッグで空ポートに接続した場合）

#### Step 4: グラフプラグインの役割を理解する

ノード描画とグラフ管理の詳細。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | visual_shader_editor_plugin.cpp | `editor/shader/visual_shader_editor_plugin.cpp` | VisualShaderGraphPlugin::add_node()（L606-788） |

**主要処理フロー**:
- **L622-648**: ポートタイプ・カテゴリ別カラー設定
- **L652-676**: ノードタイプ判定（Frame、Reroute、通常ノード）
- **L677-710**: GraphNode生成とタイトルバー色設定

#### Step 5: 接続処理を理解する

ノード間接続の管理方法。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | visual_shader_editor_plugin.cpp | `editor/shader/visual_shader_editor_plugin.cpp` | _connection_request()（L4233-4280） |

**主要処理フロー**:
- **L4240-4242**: 接続可否チェック
- **L4250-4265**: 既存接続の切断処理
- **L4267-4270**: 新規接続の作成

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

```
edit_shader() [ShaderEditorPlugin経由]
    │
    ├─ _update_graph()
    │      └─ VisualShaderGraphPlugin::add_node() [各ノード描画]
    │             ├─ VSGraphNode/VSRerouteNode/GraphFrame 作成
    │             ├─ register_link() [linksに登録]
    │             └─ ポート設定、シグナル接続
    │
    └─ [ユーザー操作]
           │
           ├─ _show_members_dialog() [ノード追加ダイアログ]
           │      └─ _add_node()
           │             ├─ EditorUndoRedoManager::create_action()
           │             ├─ VisualShader::add_node()
           │             ├─ VisualShaderGraphPlugin::add_node()
           │             └─ EditorUndoRedoManager::commit_action()
           │
           ├─ _connection_request() [ノード接続]
           │      ├─ visual_shader->can_connect_nodes()
           │      ├─ visual_shader->connect_nodes()
           │      └─ graph_plugin->connect_nodes()
           │
           ├─ _node_dragged() → _nodes_dragged() [ノード移動]
           │      └─ visual_shader->set_node_position()
           │
           ├─ _delete_nodes_request() → _delete_nodes() [ノード削除]
           │      ├─ 接続切断
           │      ├─ フレームデタッチ
           │      └─ visual_shader->remove_node()
           │
           └─ _show_preview_text() → _update_preview() [コードプレビュー]
                  └─ visual_shader->get_code()
```

### データフロー図

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

VisualShader              ─────▶ edit_shader()               ─────▶ GraphEdit
  - nodes                        └─ _update_graph()                   └─ GraphNode群
  - connections                        └─ add_node()                        └─ 接続線

ユーザー操作              ─────▶ イベントハンドラ            ─────▶ VisualShader更新
  - ノードドラッグ               └─ _node_dragged()                  └─ node_position
  - ポート接続                   └─ _connection_request()            └─ connections
  - Delete押下                   └─ _delete_nodes()                  └─ nodes削除

VisualShader              ─────▶ get_code()                  ─────▶ GLSLコード
  - 全ノード・接続情報                                                 └─ preview_text表示

GLSLコード                ─────▶ ShaderLanguage::compile()   ─────▶ エラー/成功
                                                                      └─ error_label表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| visual_shader_editor_plugin.cpp | `editor/shader/visual_shader_editor_plugin.cpp` | ソース | エディタ実装（8000行超） |
| visual_shader_editor_plugin.h | `editor/shader/visual_shader_editor_plugin.h` | ヘッダ | エディタクラス定義 |
| visual_shader.cpp | `scene/resources/visual_shader.cpp` | ソース | VisualShaderリソース実装 |
| visual_shader.h | `scene/resources/visual_shader.h` | ヘッダ | VisualShaderクラス定義 |
| visual_shader_nodes.cpp | `scene/resources/visual_shader_nodes.cpp` | ソース | 標準ノード実装 |
| visual_shader_particle_nodes.cpp | `scene/resources/visual_shader_particle_nodes.cpp` | ソース | パーティクル用ノード実装 |
| graph_edit.cpp | `scene/gui/graph_edit.cpp` | ソース | グラフエディタ基底クラス |
| graph_node.cpp | `scene/gui/graph_node.cpp` | ソース | グラフノード基底クラス |
| shader_editor.cpp | `editor/shader/shader_editor.cpp` | ソース | ShaderEditor基底クラス |
| material_editor_plugin.cpp | `editor/scene/material_editor_plugin.cpp` | ソース | マテリアルプレビュー |
| editor_undo_redo_manager.cpp | `editor/editor_undo_redo_manager.cpp` | ソース | Undo/Redo管理 |
