Post-Processing Effects in Qt 6.5

Qt 6.5のQt Quick 3Dでは、新しいQML型が追加されました。ExtendedSceneEnvironmentです。プレリリース版のドキュメントは、doc-snapshots でご覧いただけます。さらに、既存のQtQuick3D.Effectsモジュールのコンテンツはほとんど非推奨となり、既製のポストプロセス効果も含めて、代替手段として本当の 3D ポストプロセスの ExtendedSceneEnvironment や 2D 向けの効果のための MultiEffect/ Qt Quick Effect Maker、あるいは Effect 型によるカスタム 3D ポストプロセス効果を推奨しています。(明確に言うと既製のポストプロセス効果は引き続き利用可能でありサポートされます、これはQtQuick3D メインモジュールに含まれています)

これはどういうことか?

簡単に言うと、これらの新しい型は、Qt QuickとQt Quick 3Dにおける2Dと3Dのポストプロセス効果を向上させるものです。この記事では、これらのAPIがどのような意味を持つのか、そして2Dと3Dのエフェクト作成においてより一貫性があり、より理にかなっているのかを示します。主に3Dのポスト処理に焦点を当てながら、2DのQt Quickシーンにもある程度触れて、根本的な詳細といくつかの簡単な例を見ていこうと思います。

シンプルな移植の概要

まず、さまざまなコンポーネントが互いにどのように対応しているか、つまり、Qt 6.5 以降の新しいプロジェクトで推奨される API やツールは何かを可視化してみます。同時に表示されているすべてのコンポーネントは Qt 6.5 にも存在し、完全に機能していることに留意してください。

q65effects-2

厳密に言うと、これは簡略化されたものです。つまり、QtQuick3D.Effectsボックスは、Effect MakerアプリケーションやShaderEffectにリンクすることができます。以前はカスタムEffectでしか実装できなかったものが、Qt 6.5ではExtendedSceneEnvironment.Effectで提供されるようになりました。このため、左側の 図のEffect は、右側の図のExtendedSceneEnvironment にもリンクすることができます。

すこしだけ2Dことについて

MultiEffect は、Qt 6.5 のもう一つの新しい型です。これは、Qt Quick で最もよく使用されるシェーダーベースの 2Dエフェクトを提供し、Qt Graphical Effects の最も使用されるサブセットを効果的に置き換えるものです。Qt Graphical Effects は引き続き Qt5Compat モジュールで利用できますが、既存のアプリケーションの移植の補助として扱われるべきです。新しいプロジェクトでは、2D 効果には MultiEffect を使用し、それがカバーしない効果には、新しい Qt Quick Effect Maker ツールを使用することが推奨されます。その上で、頂点シェーダやフラグメントシェーダを直接操作したい人のために、ShaderEffect が引き続き利用可能です。

旧来のグラフィックエフェクトとは異なり、MultiEffectは、チェーン内の各エフェクトを1つずつレンダリングしなければならないというパフォーマンス上の制約がなく、複数のエフェクトを効率的に結合することができます。
各エフェクトは前のエフェクトの出力で動作し、レンダリングパスは、それ自体で完結します。
 さらにそれは Qt Design Studio のようなビジュアルデザインツールに適した API を提供します。
(Qt Quick シーンに個々のオブジェクトとして存在する独立したエフェクトチェーンを作成して管理する必要がないため、どのような効果が必要かを簡単に指定でき、ツールでいくつかのチェックボックスにチェックを入れるだけになります。)

新しい2D指向のエフェクトイネーブラは、他の記事で取り上げる予定です。

ここでは、Qt Quick 3Dと、View3Dアイテムの3Dコンテンツに対して実行されるエフェクトに焦点を当てます。

 

つぎに進むまえに、よくある質問について簡単に説明します。

Q: View3Dでレンダリングされた3Dシーンにブラーや不透明マスクなどの2Dエフェクトを適用するにはどうすればよいですか?

A:最も一般的に使用されているフォームのView3Dは、デフォルトレンダーモードがOffscreenで、ShaderEffect, Graphical Effects, MultiEffectに関しては、他のQQuickItemと何ら変わりはありません。

(技術的には、デフォルトの Offscreen render モードを持つView3Dは、Image、ShaderEffectSource、layer.enabled: trueを持つItemなど、テクスチャープロバイダであるテクスチャベースのアイテムと変わらないという方が正確ですが、ここでは関係ありません。)

例えば、View3D でレンダリングされた 3D シーンをぼかすには、Qt Quick シーンの他のアイテムと同じ方法を使用します。例えば MultiEffect を使用して、View3D またはその子に (2D) ブラー効果を適用します。

3Dレンダラの3Dポストプロセス機能を使用して同様の効果を得るには、カスタムの3Dポストプロセスエフェクト、またはQtQuick3D.Effectsモジュールの現在廃止されたBlurやGaussianBlur効果を使用しますが、ほとんどの場合、3Dレンダラの出力に2Dブラーを実行すると同じ結果になるのでこれは必要ではありません。

QtQuick3D.Effects の Flip や Emboss など、現在では非推奨のエフェクトも同様で、3D ポスト処理システムで作り直すのではなく、Qt Quick の機能を使って実行した方が良い 2D 向けのエフェクトです。

Let's see a short example. We will assume that the Sponza and Suzanne models are imported from the glTF 2.0 assets in the Khronos glTF Sample Models repository via the balsam tool (and so the generated Sponza.qml and Suzanne.qml components are available and instantiable). For simplicity, image based lighting is used.

簡単な例を見てみましょう。ここでは、SponzaとSuzanneのモデルが、Khronos glTF Sample ModelsリポジトリのglTF 2.0アセットからBalsam ツールでインポートします。(したがって、生成されたSponza.qmlとSuzanne.qmlコンポーネントが利用できインスタンス化できる)と仮定しています。シンプルにするため、イメージ・ベースド・ライティングを使用しています。

import QtQuick
import QtQuick3D
import QtQuick3D.Helpers

Item {
    width: 1280
    height: 720

    View3D {
        id: v3d
        anchors.fill: parent
        environment: SceneEnvironment {
            backgroundMode: SceneEnvironment.SkyBox
            lightProbe: Texture { source: "00455_OpenfootageNET_field_low.hdr" }
        }

        Node {
            scale: Qt.vector3d(100, 100, 100)

           
Sponza {
            }

            Suzanne {
                y: 1
                scale: Qt.vector3d(0.5, 0.5, 0.5)
                eulerRotation.y: -90
            }
        }

        PerspectiveCamera {
            id: camera
            y: 100
        }

        WasdController {
            controlledObject: camera
        }
    }
}

これをqmlツールで実行すると、次のようなものが得られます。

testscene

 

例えば、あるUI要素が上に表示されたときに有効になる背景ぼかしを実装している場合などです、これをぼかす必要がある場合はどうすればよいでしょうか。

Qt 6.5 の MultiEffect を使えば、これは簡単で、2D シーンの他のアイテムにブラーを適用するのと変わりはありません。
まず、QtQuick.Effects のインポートを追加し、そこに MultiEffect を組み込みます。

import QtQuick.Effects

そして、MultiEffectのドキュメントにあるサンプルスニペットにヒントを得て、ルートItem(View3Dの後ろ)に以下を追加しています。さらに、Tabキーでぼかしを切り替えられるようにしています。

    MultiEffect {
        id: effect
        source: v3d
        anchors.fill: v3d
        blurEnabled: true
        blurMax: 64
        blur: 1.0
autoPaddingEnabled: false

    }

    focus: true
    Keys.onTabPressed: effect.blurEnabled = !effect.blurEnabled

これによって

testscene_blur

すべて期待通りに動作しております。さて、次は深度バッファ、マルチパス、トーンマッピングなどの 3D ポスト処理について説明します。

3Dワールドのポストプロセス

Qt Quick 3D の新しい ExtendedSceneEnvironment は、3D レンダラで実行されるポストプロセス効果に対して、主に MultiEffect に類似したアプローチを提供します。

以下ののエフェクトが含まれます。

  • グロー、ブルーム
  • 被写界深度
  • レンズフレア
  • ヴィネット
  • ルックアップテーブルを使用したカラーグレーディング
  • 色調整
  • アンチエイリアス処理(FXAA)が可能

さらに、SceneEnvironment の既存のトーンマッピングシステムは、ExtendedSceneEnvironment のいくつかの新しいプロパティで強化されています。
ハイダイナミックレンジの値を0-1の範囲でマッピングする方法をより詳細に制御することができます。

Qt 6.5 では、新しい Fog 型と SceneEnvironment の フォグ プロパティを通じて、シンプルなフォグのサポートも導入されています。

技術的には、このタイプのフォグは、マテリアルの中で実装されています。
 (すなわち、有効化されたときに自動的に実行されます。
技術的には、この型のフォグはマテリアル内に実装され (すなわち、有効化された場合、シェーディングモードが Shaded に設定された PrincipledMaterial または CustomMaterial によって自動的に実行されます) 
後処理で行われるものではありません。
しかし、APIやデザイナーの観点からは、同じカテゴリに分類されます。

以前の Qt バージョンで SceneEnvironment を介してすでに利用可能なシーンスペースのアンビエントオクルージョンサポートは、同様に利用し続けることができます。

SceneEnvironment のエフェクトリストプロパティに、既存の Effect サブタイプのインスタンスをリストアップする従来の方法と比較して、ExtendedSceneEnvironment を使用すると、以下の利点があります。

  • 有効なエフェクトは効率的に結合され、エフェクトチェーンを1つずつ処理する代わりに、レンダーパスの回数を減らすことができます。
  • トーンマッピングは、ポストプロセススタックのすべてのレベルで考慮され、正しく処理されます。エフェクトの上に構築されたスタンドアロンポストプロセッシングエフェクトでは、これが正しく処理されないケースもありました。
  • 被写界深度やグロー/ブルームなどのエフェクトの品質と設定可能なレベルは、旧来のエフェクトシェーダとは全く異なる実装であるため、大幅に改善されています。
  • レンズフレア!

ExtendedSceneEnvironment を使用するには、QtQuick3D.Helper をインポートし、View3D の環境プロパティから参照されるオブジェクトを作成する際に SceneEnvironment の前に Extended という単語を追加してください。

前節のサンプルアプリケーションのコードを、View3D上の環境を以下のように置き換えると、以下のようになります。

        environment: ExtendedSceneEnvironment {
backgroundMode: SceneEnvironment.SkyBox
lightProbe: Texture { source: "00455_OpenfootageNET_field_low.hdr" }

tonemapMode: SceneEnvironment.TonemapModeFilmic
sharpnessAmount: 0.4

vignetteEnabled: true
vignetteRadius: 1.5

glowEnabled: true
glowStrength: 1.25
glowBloom: 0.25
glowBlendMode: ExtendedSceneEnvironment.GlowBlendMode.Additive
}

このような結果になります。

testscene_extscene

ここでは、一つひとつのプロパティについて詳しく説明することは控えます。代わりに、プレリリース版のドキュメントをご覧ください。多くのプロパティのスクリーンショットが付属しており、何をするのかがよくわかるようになっています。

シーンエフェクトサンプル

あるプロパティの値を少し変えただけで、レンダリング結果にどのような影響が出るかは、必ずしも明らかではない場合があります。
1. .qmlファイル内のプロパティ値を変更する。
2. アプリケーションを実行する 
3. 1を実行する
上記の開発ワークフローは、すぐにフラストレーションが溜まってしまいます。そのため、このようなチューニングはインタラクティブに行うことが推奨されます。

Qt Design Studio 内で作業するデザイナーは、通常、プロパティパネルでいくつかのスライダーを調整し、結果をライブですぐに確認することができます。
デザインツールを使用しない場合、最初にテストベッド・アプリケーションの助けを借りて実験することが役に立ちます。
Qt 6.5 には、sceneeffects と呼ばれる新しいサンプルが付属しています。これは、ExtendedSceneEnvironment のすべての新しいプロパティのインタラクティブなコントロールを提供し、新しい深度/高さフォグの設定も提供します。

大きなアセットの出荷には制限がありますので、このサンプルを使用する最良の方法は、例えば Khronos glTF Sample Models リポジトリから Import ボタンでアセットをロードすることです。
図は、このリポジトリにあるglTF 2.0アセットから直接読み込んだスポンザ宮殿のモデルで、必須のレンズフレアを有効にし、いくつかのパラメータを変更するなど、いくつかのエフェクトを加えています。

testscene_example

ExtendedSceneEnvironmentを使い始めるには、まずこのアプリケーションで遊んでみることをお勧めします。

デバッグビュー:パフォーマンスとリソースの使用状況を調査します。

開発の後期には、3D シーンでポストプロセスを行うコストをよりよく理解することが重要になると思われま す。使用されるリソースの量、特に追加レンダーパスの数は、正確な設定に依存します。様々な効果は可能な限り一緒に結合されますが、それらのいくつかは、本質的に複数のレンダーパスと中間バッファを含んでいます。

Qt 6.5では、いくつかの簡単な洞察を得る方法があります。右上にある "Click here for DebugView "というラベルに注目してください。これをクリックすると、DebugView の項目が表示されます。Quick 3D のサンプルには組み込まれていますが、どのアプリケーションでも Qt Quick のシーンに DebugView を配置し、View3D と関連付けて、その可視性を自由にコントロールすることができます。

一般的なタイミング情報に加え、テクスチャ、メッシュ、View3Dの最終出力をレンダリングするために必要なレンダーパスのリストをライブで表示することができます。

testscene_dbg1 testscene_dbg2 testscene_dbg3-1

デフォルトのレンダリングモードが Offscreen の View3D は、1 つのレンダリングパスを報告します。ポストプロセス効果を追加すると、より多くのパスが表示され、その数とレンダーターゲットサイズは多くの要因に依存し、ExtendedSceneEnvironment の効果のプロパティに影響されることが多く、追加のテクスチャが読み込まれることがあります。

カスタム3Dポストプロセッシングエフェクト

このことは、Effect QML 型を使用して実装されたカスタムエフェクトにどのような影響を与えるのでしょうか?ほとんどの場合、影響はありません。カスタムエフェクトは、これまでと同じように動作します。注意すべき重要な点は、環境のエフェクトリストに追加されたエフェクトは、ビルトインのポスト処理ステップの前に実行されることです。

Effect {
    id: simpleEffect
    property real someUniformValue
    property TextureInput someTexture: TextureInput {
        texture: Texture { source: "image.png" }
    }
    passes: Pass {
       shaders: Shader {
           stage: Shader.Fragment
           shader: "effect.frag"
       }
    }
}

environment: ExtendedSceneEnvironment {
    effects: [ simpleEffect ]
    vignetteEnabled: true
}

ここでは、カスタムの 'simpleEffect' は、ヴィネット効果の前に処理を行うようになります。トーンマッピングに関しては、カスタムエフェクトはその出力がリニアスペース(HDR)であると仮定することができ、トーンマッピングはパイプラインの最後で自動的に実行されます。

まとめ

  • When it comes to 2D effects, get familiar with MultiEffect. For the most common effects, such as blur or drop shadow, this should be the primary choice

  • 2Dエフェクトに関しては、MultiEffectに慣れるようにしてください。ブラーやドロップシャドウのような最も一般的なエフェクトは、これを第一に選択すべきです。

    • ....たとえ、3Dシーンに効果を適用することが目的であっても。上記のように、典型的なView3DでMultiEffectを使用しても、他のItemにエフェクトを適用するのと変わりはありません。

    • Qt5Compat モジュールからレガシーな Qt Graphical Effects 型を引っ張ってこないようにしてください。MultiEffectやQt Quick Effect Makerを使用することで、より良い方法で同じ効果を実装することができるはずです

  • MultiEffect で十分でない場合は、Qt Quick Effect Maker ツールを見てから、カスタムシェーダコードによる ShaderEffect の実装を検討してください。

  • 3Dの世界では、常にExtendedSceneEnvironmentのポストプロセッシング機能の使用を最初に検討してください。

  • QtQuick3D.Effectsモジュールの古いスタンドアロンポストプロセッシングエフェクトは使用しないでください。

    • Blur, GaussianBlur, Emboss, Flip などのいくつかは、MultiEffect や Qt Quick Effect Maker を使って 2D エフェクトとして実装することができます (また、そうすべきです)。

    • DepthOfFieldHQBlur、HDRBloomTonemap、ColorMaster、Fxaa、Vignette などの多くは、ExtendedSceneEnvironment でより良い代替が用意されています。

    • 他のいくつかの効果は、歴史的な理由(例えば、古い製品からそのまま受け継いだもの)のみで存在し、実用的な価値は限られています。これらは、Qt 6 でも当分の間利用できますが、代わりにカスタムエフェクトとしてアプリケーションに取り込み、アプリケーションが現在も将来も完全にコントロールできるようにすることが推奨されます。

  • ポストプロセッシングエフェクトとそのパラメータに精通するとき、最初にインタラクティブな環境でそれらを実験することは非常に役に立ちます。これは、sceneeffects のサンプルQt Design Studio、または Qt Quick Effect Maker を使用することができます。

  • Qt 6.5 で強化された DebugView に注意してください。以前のバージョンでは、いくつかのタイミングを表示するだけでしたが、アセットとレンダラーの情報も表示されるようになりました。

ここまでお読みいただきありがとうございました。今後、Qt Quick や Qt Quick 3D のエフェクトに関するブログ記事が登場する可能性は少なくありません。

 


Blog Topics:

Comments