ohos-dev-graphics3d-combined-postprocess について
OpenHarmony Graphics3D の LumeRender、Lume3D、LumeScene で単一パスのポストプロセス効果を実装するためのスキルです。手順と、Combined パイプラインを複数パスが必要な効果に使わないための注意点を示します。
主な機能
- 013モジュールの実装手順
- 02設定からシェーダーへのデータ変換
- 03シェーダーと描画パイプラインの統合
- 04ECS コンポーネントとシーン API の登録
- 05パラメーターとインデックスの制約
活用シーン
- 01トーンマッピングやカラーグレーディングの追加
- 02単一パスのビネット効果の実装
- 03効果にマルチパス構成が必要かの判断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ openharmonyinsight/ openharmony-skills --skill ohos-dev-graphics3d-combined-postprocessインストール後、Claude Code で/ohos-dev-graphics3d-combined-postprocessを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/advanced_reference.mdcode_templates.md詳細
複合ポストプロセスの実装ガイド
依存関係の順序に従い、3 つのモジュールにまたがって複合ポストプロセスエフェクトを実装します。 LumeRender → Lume3D → LumeScene
タスクと対象範囲
このスキルでは、OpenHarmony Graphics3D におけるシングルパスのポストプロセスエフェクトの実装方法を説明します。
対象:
- 単一のフルスクリーンシェーダーパスで実行されるエフェクト(トーンマッピング、カラーグレーディング、ビネット)
- 複合ポストプロセスシステムへのエフェクトの追加
対象外:
- 個別のレンダーパスを必要とするエフェクト(ブラー処理を伴うブルーム、被写界深度、モーションブラー)
モジュールの依存関係の概要
LumeRender (AGPRender)
↓
Lume3D (AGP3D)
↓
LumeScene
- LumeRender:低レベルのレンダリングモジュールで、シェーダー/レンダーノードの基盤を提供します
- Lume3D:3D シーンモジュールで、ECS コンポーネントを提供し、LumeRender に依存します
- LumeScene:高レベルのシーンモジュールで、使いやすいインターフェースを提供し、Lume3D に依存します
実装前のチェックリスト
複合ポストプロセスエフェクトを実装する前に、次の点を確認してください。
- ビジュアルエフェクトの目標:どのようなビジュアルエフェクトを実現しますか?(トーンマッピング、カラーグレーディング、ビネット、カスタムエフェクト)
- パラメーターの複雑さ:エフェクトにはいくつのパラメーターが必要ですか?
- 1~4 個のパラメーター:
factors[]の Vec4 のみを使用します - 5~8 個のパラメーター:
factors[]とuserFactors[]に分けます - 8 個を超えるパラメーター:複合システムに適しているか検討します
- 1~4 個のパラメーター:
- レンダーパスの要件:中間フレームバッファーが必要ですか?
- 単一のフルスクリーンパス:✓ 複合ポストプロセスを使用します(このスキルの対象)
- ブラーパス、縮小/拡大、時間的処理:✗ マルチパスシステムを使用します(このスキルの対象外)
- インデックスの空き状況:複合システムでインデックス 0~7 は使用可能ですか?
- 現在使用中:0(トーン)、1(ビネット)、2(ディザ)、3(色変換)、4(フリンジ)、5(アップスケール)、6(ホワイトバランス)、7(色調整)
- 未使用のインデックスが必要な場合:シェーダーと C++ の両方に新しいインデックスを登録する必要があります
判断フロー:
Effect needs >4 params? ─────YES──→ Split: factors[] + userFactors[]
│
NO
↓
Effect needs blur/temporal? ─YES──→ Use multi-pass system (EXIT this skill)
│
NO
↓
Index 0-7 available? ──────YES──→ Continue with Combined implementation ✓
│
NO
↓
Need to register new index → Follow LumeRender Step 1-3 first
ワークフロー
LumeRender(8 ステップ):
- 設定構造体を定義する
- メタデータを登録する
- シェーダー定数を定義する
- 設定からシェーダーへの変換を実装する
- ポストプロセススタックを設定する
- RenderNodeUtil に変換処理を追加する
- シェーダー処理関数を実装する
- レンダーパイプラインに統合する
Lume3D(5 ステップ):
- フラグビットを追加する
- コンポーネントプロパティを定義する
- メタデータを登録する
- レンダーシステムに統合する
- Lume3D シェーダーに統合する
LumeScene(9 ステップ):
- インターフェースを定義する
- IPostProcess インターフェースに追加する
- API ラッパーを実装する
- エフェクトクラスを実装する
- PostProcess に登録する
- コンポーネント型を登録する
- プラグイン型を登録する
- Any 型を登録する
- ビルドファイルを更新する
LumeRender の実装
必須 — ファイル全体を読むこと:LumeRender の手順を始める前に、references/code_templates.md の「LumeRender Templates」セクション(ステップ 1~8、約 300 行)を必ず最後まで読んでください。このファイルを読む際、範囲の上限を設定しないでください。
まだ advanced_reference.md を読み込まないでください — トラブルシューティングの段階まで取っておいてください。
ステップ 1:設定構造体を定義する
ファイル:api/render/datastore/render/render_data_store_render_pods.h
プロパティとデフォルト値を含むエフェクト設定構造体を定義します。列挙型のインデックス、フラグビット、プロパティ型の宣言を追加します。
詳細:references/code_templates.md#step-1-define-configuration-structure を参照してください
ステップ 2:メタデータを登録する
ファイル:src/postprocesses/render_post_process_combined_node.cpp
リフレクションシステムに、列挙値、型メタデータ、設定構造体のメタデータを登録します。
詳細:references/code_templates.md#step-2-register-metadata を参照してください
ステップ 3:シェーダー定数を定義する
ファイル:api/render/shaders/common/render_post_process_structs_common.h
エフェクトの特殊化ビットとインデックス用のシェーダーマクロ定数を定義します。
詳細:references/code_templates.md#step-3-define-shader-constantsを参照してください。
ステップ 4:設定からシェーダーへの変換を実装する
ファイル:src/datastore/render_data_store_post_process.h
設定をシェーダーで扱いやすい Vec4 ファクターにパックする変換関数を実装します。
詳細:references/code_templates.md#step-4-implement-config-to-shader-conversionを参照してください。
ステップ 5:ポストプロセススタックに追加する
ファイル:src/datastore/render_data_store_post_process.cpp
組み込みデータとファクターを使って、エフェクトをポストプロセススタックに追加します。
詳細:references/code_templates.md#step-5-fill-post-process-stackを参照してください。
ステップ 6:RenderNodeUtil に変換処理を追加する
ファイル:src/nodecontext/render_node_util.cpp
GetRenderPostProcessConfiguration() 関数にファクター変換の呼び出しを追加します。
詳細:references/code_templates.md#step-6-add-conversion-in-rendernodeutilを参照してください。
ステップ 7:シェーダー処理関数を実装する
ファイル:api/render/shaders/common/render_post_process_blocks.h
エフェクトのロジックを含む GLSL シェーダー処理関数を実装します。
詳細:references/code_templates.md#step-7-implement-shader-processing-functionを参照してください。
ステップ 8:レンダーパイプラインに統合する
ファイル:assets/render/shaders/shader/fullscreen_combined_post_process.frag
フルスクリーンのレンダーパイプラインでシェーダー処理関数を呼び出します。
詳細:references/code_templates.md#step-8-integrate-into-render-pipelineを参照してください。
Lume3D の実装
必須 — このセクションを読む:ECS 統合の例を確認するため、references/code_templates.mdの「Lume3D Templates」セクション(ステップ 1~5、約 100 行)を読んでください。
まだ advanced_reference.md を読み込まないでください — 引き続きワークフローの手順に従ってください。
ステップ 1:フラグビットを追加する
ファイル:api/3d/ecs/components/post_process_component.h
PostProcessComponent::FlagBits enum にフラグビットを追加します。
詳細:references/code_templates.md#lume3d-step-1-add-flag-bitを参照してください。
ステップ 2:コンポーネントプロパティを定義する
ファイル:api/3d/ecs/components/post_process_component.h
DEFINE_PROPERTY マクロを使ってコンポーネントプロパティを定義します。
詳細:references/code_templates.md#lume3d-step-2-define-component-propertyを参照してください。
ステップ 3:メタデータを登録する
ファイル:src/ecs/components/post_process_component_manager.cpp
列挙値と設定のメタデータを登録します。
詳細:references/code_templates.md#lume3d-step-3-register-metadataを参照してください。
ステップ 4:レンダーシステムに統合する
ファイル:src/ecs/systems/render_system.cpp
ProcessPostProcessComponents() 関数で設定を割り当てます。
詳細:references/code_templates.md#lume3d-step-4-integrate-into-render-systemを参照してください。
ステップ 5:Lume3D シェーダーに統合する
ファイル:api/3d/shaders/common/3d_dm_inplace_post_process.h
Lume3D のインプレースポストプロセスでシェーダー処理関数を呼び出します。
詳細:references/code_templates.md#lume3d-step-5-integrate-into-lume3d-shaderを参照してください。
LumeScene の実装
必須 — このセクションを読むこと:API ラッパーと登録の例について、references/code_templates.md の「LumeScene Templates」セクション(ステップ 1~9、約 400 行)を読んでください。
まだ advanced_reference.md を読み込まないでください。エラーが発生した場合や、データフロー図が必要な場合にのみ読み込んでください。
ステップ 1:インターフェースを定義する
ファイル:include/scene/interface/postprocess/intf_your_effect.h
META_INTERFACE とプロパティ宣言を含むインターフェースクラスを定義します。
詳細:references/code_templates.md#lumescene-step-1-define-interface を参照してください。
ステップ 2:IPostProcess インターフェースに追加する
ファイル:include/scene/interface/intf_postprocess.h
エフェクトインターフェースの include と META_READONLY_PROPERTY を追加します。
詳細:references/code_templates.md#lumescene-step-2-add-to-ipostprocess-interface を参照してください。
ステップ 3:API ラッパーを実装する
ファイル:include/scene/api/post_process.h
META_INTERFACE_OBJECT とプロパティマクロを含むラッパークラスを実装します。
詳細:references/code_templates.md#lumescene-step-3-implement-api-wrapper を参照してください。
ステップ 4:エフェクトクラスを実装する
ファイル:
- ヘッダー:
src/postprocess/your_effect.h - 実装:
src/postprocess/your_effect.cpp
META_OBJECT マクロを使用し、PostProcessEffect テンプレートを継承するエフェクトクラスを実装します。
詳細:references/code_templates.md#lumescene-step-4-implement-effect-class を参照してください。
ステップ 5:PostProcess に登録する
ファイル:
- ヘッダー:
src/postprocess/postprocess.h - 実装:
src/postprocess/postprocess.cpp
静的プロパティデータと InitDynamicProperty ハンドラーを追加します。
詳細:references/code_templates.md#lumescene-step-5-register-in-postprocess を参照してください。
ステップ 6:コンポーネント型を登録する
ファイル:src/component/postprocess_component.h
META_TYPE 登録とプロパティマクロを追加します。
詳細:references/code_templates.md#lumescene-step-6-register-component-type を参照してください。
ステップ 7:プラグイン型を登録する
ファイル:src/plugin.cpp
RegisterObjectType と UnregisterObjectType の呼び出しを追加します。
詳細:references/code_templates.md#lumescene-step-7-register-plugin-type を参照してください。
ステップ 8:Any 型を登録する
ファイル:src/register_anys.cpp
ObjectTypes リストにインターフェースポインター型を追加します。
詳細:references/code_templates.md#lumescene-step-8-register-any-type を参照してください。
ステップ 9:ビルドファイルを更新する
ファイル:
include/CMakeLists.txtsrc/CMakeLists.txtBUILD.gn
インターフェースファイルとソースファイルをビルドターゲットに追加します。
詳細:references/code_templates.md#lumescene-step-9-update-build-files を参照してください。
禁止されている実践
マルチパスエフェクトには絶対に適用しないでください
個別のレンダーパスを必要とするエフェクト(ブラーを伴うブルーム、被写界深度、モーションブラー、FXAA、TAA):
- 理由:結合ポストプロセスシェーダー(
fullscreen_combined_post_process.frag)が処理するのはインデックス 0~7 だけです。マルチパスエフェクトは、個別のシェーダーと中間フレームバッファーを使用し、インデックス 8 以降を使います。 - 結果:Combined 方式を試みると、インデックス 9 の
factors[INDEX_BLOOM]は Combined シェーダーで無視されます。エフェクトがレンダリングされないか、誤ったメモリーオフセットのデータを読み込む可能性があります。 - 検証:エフェクトが中間レンダーパス(ブラー、ダウンスケール/アップスケールのパス)を必要とするか確認します。必要な場合は、Combined ではなくマルチパスシステムを使用します。
- 正しい方法:個別のレンダーノードグラフを使う専用のマルチパスポストプロセス実装を使用します。
シェーダーと C++ のインデックスを絶対に不一致にしないでください
GLSL 定数と C++ 列挙値のインデックスの整合性:
- 理由:シェーダーは
uGlobalData.factors[POST_PROCESS_INDEX_TONEMAP]に直接アクセスします。シェーダーでPOST_PROCESS_INDEX_TONEMAP 0と定義されている一方、C++ でINDEX_TONEMAP 1と定義されていると、シェーダーは factors 配列から誤った Vec4 を読み込みます。 - 結果:描画の異常(色が不正、パラメーターが適用されない)が発生するか、インデックスが
POST_PROCESS_GLOBAL_VEC4_FACTOR_COUNT (14)を超えると、GPU 検証エラー「array index out of bounds」が発生します。 - 検証:次の 3 つのファイルを照合します。
- シェーダー:
render_post_process_structs_common.h→POST_PROCESS_INDEX_*の値 - C++ 設定:
render_data_store_render_pods.h→PostProcessConfiguration::INDEX_*の値 - DataStore 変換:
render_data_store_post_process.cpp→factors[INDEX_*]の代入
- シェーダー:
- 正しい方法:3 か所すべてで同じ数値を使います。ファイル内のコメントには「api/core/render/render_data_store_render_pods.h と一致させる必要があります」と明記されています。
パラメーターが 4 個を超える場合、userFactors を絶対に忘れないでください
浮動小数点パラメーターが 4 個を超えるエフェクト:
- 理由:Vec4 に格納できる浮動小数点数は 4 個です。GlobalPostProcessStruct には
factors[14](Vec4 配列)とuserFactors[16](Vec4 配列)があります。エフェクトのパラメーターが 5 個以上ある場合は、factors と userFactors に分ける必要があります。 - 結果:シェーダーが
uGlobalData.userFactors[USER_INDEX_*]を読み込もうとしても、定数が未定義だと「undefined macro」というコンパイルエラーが発生します。また、定義されていても値が設定されていない場合、シェーダーはゼロの Vec4 を読み込み、エフェクトのパラメーターが誤った値になります。 - 検証:エフェクトのパラメーター数を数えます。4 個を超える場合は、次を確認します。
render_data_store_render_pods.hでUSER_INDEX_*定数が定義されていることrender_data_store_post_process.hで userFactors 用のGetFactorXXX()関数があること- シェーダーが正しい userFactors インデックスを使用していること:
uGlobalData.userFactors[POST_PROCESS_USER_INDEX_*]
- 正しい方法:パラメーターが 5~8 個の場合は、factors[0-3] と userFactors[0-3] を使用します。
USER_INDEX_*定数を定義し、変換関数を実装して、FillDefaultPostProcessData で呼び出します。
LumeRender/Lume3D/LumeScene の整合性を絶対に省略しないでください
3 つのモジュールすべてを更新する必要があります:
- 理由:結合ポストプロセスは 3 つのモジュールを通ります。LumeRender でシェーダー定数を定義し、Lume3D で ECS に統合し、LumeScene で API をラップします。いずれかのモジュールを省略すると、連携が壊れます。
- 結果:
- LumeRender を省略:シェーダーが
PostProcessXXXBlock()関数を見つけられず、コンパイルエラーが発生します - Lume3D を省略:
PostProcessComponentにプロパティがなく、ECS システムが設定を伝播できないため、シェーダーにゼロの factors が渡されます - LumeScene を省略:ユーザー API がなく、開発者がエフェクトを設定できないため、使用できません
- LumeRender を省略:シェーダーが
- 検証:実装チェックリスト(3 つのモジュール全体で 22 ステップ)を使用します。各モジュールの主要なファイルが存在し、変更されていることを確認します。
- 正しい方法:22 ステップすべてに従います。LumeRender(8)→ Lume3D(5)→ LumeScene(9)の順に進めます。
例外とフォールバック
エフェクトに複数のレンダリングパスが必要
症状:エフェクトで、ぼかしパス、ダウンスケール/アップスケール、時間方向の累積が必要です。
- 代替策:このスキルは適用できません。専用のマルチパスポストプロセスシステムを使用し、個別のレンダーノードグラフを用意してください。
- 根拠:シェーダーで
uImgSamplerとuBloomSampler、および中間フレームバッファー(ブルームなど)が必要か確認してください。必要な場合は、マルチパスです。
シェーダーのコンパイルエラー
症状:「undefined macro POST_PROCESS_INDEX_XXX」または「array index out of bounds」が発生します。
- 診断:インデックスの不一致、または定数定義の欠落です。
- 修正:シェーダーの定数が C++ の enum 値と一致しているか確認してください。インデックスが 14(POST_PROCESS_GLOBAL_VEC4_FACTOR_COUNT)未満であることを確認してください。
ビジュアルアーティファクト、またはエフェクトが適用されない
症状:色が正しくない、パラメーターが無視される、エフェクトが見えないなどが発生します。
- 診断:ファクターのインデックスが誤っている、または DataStore で GetFactorXXX() が呼び出されていません。
- 修正:変換関数が
render_data_store_post_process.cpp(ステップ 5)とrender_node_util.cpp(ステップ 6)の両方で呼び出されていることを確認してください。
参考資料
主な参照ファイル
references/code_templates.md(785 行):全 22 ステップの汎用テンプレートとトーンマッピングの例を含む、完全なコードテンプレートです。実装中に必ず読み込んでください。references/advanced_reference.md(306 行):データフロー図、実装チェックリスト、トラブルシューティングガイドを含む高度なリファレンスです。トラブルシューティング時、またはデータフローの理解が必要な場合にのみ読み込んでください。
読み込み方針
フェーズ 1 - 初期実装:
- ✅ 必須:
code_templates.mdを 3 段階(LumeRender → Lume3D → LumeScene セクション)で読み込む - ❌ 読み込まないでください:
advanced_reference.md(後で使用します)
フェーズ 2 - トラブルシューティング:
- ✅ 必要に応じて読み込む:エラーが発生した場合、データフロー図または実装チェックリストが必要な場合は
advanced_reference.mdを読み込む - ❌ 再読み込みしないでください:すでに読み込んでいる場合は
code_templates.mdを再読み込みしない
要点
-
アーキテクチャ:設定と変換の分離
- ユーザーインターフェース用の設定構造体
- 変換関数でシェーダーに適した Vec4 に格納
-
重要:シェーダーと C++ のインデックス/ビットの整合性
POST_PROCESS_INDEX_*↔PostProcessConfiguration::INDEX_*POST_PROCESS_SPECIALIZATION_*_BIT↔FlagBitsenum- 不一致は GPU の検証エラーやビジュアルアーティファクトの原因になります
-
必須:二重パスのサポート
- DataStore(ステップ 5)と RenderNodeUtil(ステップ 6)の両方に変換処理を追加する
- 単一パスの実装は、一部のシナリオで失敗します
-
命名規則とマクロの規約
- シェーダー関数:
PostProcess<Effect>Blockという命名 - META_TYPE:インターフェースに enum 型がある場合にのみ含める
- META_READONLY_PROPERTY:IPostProcess インターフェースに追加する必要があります
- シェーダー関数: