レンダリング ループ オーバーライド

レンダリング ループ オーバーライドは、API で MRenderOverride と表されます。

名前が示すように、このタイプのプラグインは完成したフレームのレンダリング全体をオーバーライドします。古いインタフェースとは異なり、レンダリング ループの特定のレンダリング ロジックを挿入または除去する固定エントリ ポイントはありません。たとえば、「プレ」、「ポスト」、および「パス」コールバックなどはありません。代わりに、構築ブロックの適切な組み合わせとパイプライン エクスポージャーを提供することにより、プラグインで任意の複合パイプライン ロジックを定義できるようにします。

オーバーライドは、操作セットに分けられます。内部パイプラインの一部を実行する定義済みの操作とカスタム操作は、構築ブロックのベース セットを表します。操作は、データ入力および出力を完全に記述するように設計されており、既定では、互いに独立して実行されます。したがって、操作間の主な接続はデータです。すべての操作はレンダー ターゲットにレンダリングされ、データは操作間で共有レンダー ターゲットによって明示的に渡されます。

次の基本操作のセットが利用できます。

これらの操作はレンダリング パイプラインに組み込まれているので、レンダリング状態が必要に応じて操作に提供されます。通常、この情報はフレームの開始時に決定され、各操作の既定値として暗黙に設定されます。操作ごとに設定されているオーバーライドは操作間では維持されません。

カスタマイズの量によっては、インタフェースは描画 API にほとんど依存しません。

以前の API 実装とは異なり、シーケンスはプラグイン コードによって指定され、インタフェースによって定義されません。したがって、目的のレンダリング ループを操作のリニア リストに分けるために、プラグインが必要です。API インタフェースの基本的な外観は指定できるレンダリング ループのタイプ例を示しています(左側)。プラグインは、操作の適切な順序を決定します。右側は、古いインタフェースの基本的なマルチパス ループ ロジックです。ここでは、シーケンスはインタフェースに基づいて定義済みです。

図 45: 左側のレンダー ターゲットは操作間でコンテキストを出力や入力として渡す手段として機能します。右側では、一連のシーン レンダリング「パス」が順次呼び出され、特定のビューポートを更新します。古いインタフェースのコールバックがレンダリング間に提供され、外部のデータまたは状態にアクセスして更新します。これらのデータまたは状態を使用して、現在のレンダリングまたは以降のレンダリングに影響を与えることができます。

レンダー オーバーライドの登録とアクティベーション

オーバーライドがレンダリング フレームワークに統合されているので、これらのオーバーライドはすべてのエクスポーズ インタフェース(3D ビューポート、プレイブラスト、レンダービュー、バッチ レンダリング)に対して機能すると同時に、3D ビューポート(M3dView)などの特定のインタフェースへの依存を避けます。

任意の数のオーバーライドを MRenderer クラスを介して登録することができますが、エクスポーズ インタフェースごとに 1 つだけアクティブに設定できます。各 3D ビューポート(プレイブラストが使用するもの)は異なるオーバーライドを使用できます。一方で、コマンド ライン レンダリング(レンダービューおよびバッチ)はさらに別の異なるオーバーライドを使用できます。

オーバーライドの使用可能なセットを照会したり、アクティブなオーバーライドを設定したりするメイン インタフェースには、インタラクティブなレンダリングとレンダリング オプション用の M3dView および modelEditor または非インタラクティブなレンダリング(レンダービューおよびバッチ)用の MRenderer があります。

MRenderOverride を使用しても、古いインタフェースの使用は常に除外されるとは限りませんが、多くの理由により、古いインタフェースの使用はお勧めしません。古いインタフェースでは、実際、次のようなことがあります。

MRenderOverride プラグインを作成するとき、次のようにしてダイアログ ボックスを開くためのオプション ボックスを追加することができます。このダイアログ ボックスは UI の設定が可能なユーザ オプションをサポートします。

MRenderOverride の名前が FooRenderer である場合、FooRendererOptionBox という名前のグローバル MEL プロシージャを提供すると(ポスト フィックスとして OptionBox が追加されていることを確認してください)、オプション ボックス アイコンがビューポート メニュー アイテムの横に自動的に表示されます。

FooRendererOptionBox プロシージャでオプション ダイアログ ボックスの UI レイアウトを管理することができます。

ベース レンダリング操作とユーティリティ オーバーライド

インスタンス化できるすべてのレンダリング操作は、ベース クラス MRenderOperation から派生します。これらのクラスはそのまま使用できます。または、より多くのクラス派生を通じてさらにカスタマイズすることができます。派生は、オーバーライド パラメータ、または操作ごとに要求されるメソッドを提供するために使用するアプローチです。

MRenderOperation は、すべての操作に対して一般的なインタフェースを提供します。これには、次のものが含まれます。

  1. 名前: すべての操作に対して、一意の識別子が必要です。
  2. 出力レンダー ターゲット(MRenderTarget)に対して可能なオーバーライド。
  3. (描画コンテキストの) 2D ビューポート長方形に対して可能なオーバーライド。

シーン レンダリングやカスタム ユーザ操作などの一部の操作はカメラ入力をオーバライドすることができます。ユーティリティ ストラクチャ MCameraOverride は、こうしたオーバーライドを提供するインタフェースです。

カメラのオーバーライドは、次の 2 つのレベルで指定することができます。

また、カメラ オーバーライド パラメータを使用して、カメラのリストの 3D UI を非表示にすることができます。

シーン操作およびクアッド レンダリング操作と併用される別のユーティリティ ストラクチャは、レンダー ターゲット クリアです。このストラクチャは MClearOperation です。ユーティリティ パラメータを必要に応じて次のオプションを示すように設定することができます。

必要に応じて、ユーザ操作によって独自のクリアを実行できます。

クリア操作によってポスト効果に必要なデータが除去される可能性があるので、レンダリング ループに埋め込まれているクリア操作オーバーライドは内部 2D ポスト効果のレンダリングを許可しません。

すべての操作とサポート クラスは単に動作の説明であり、リソースではありません。したがって、これらはフレーム レンダリングの寿命を超えて維持されます。

シーン レンダリング

シーン レンダリングを表すコンストラクトは、MSceneRender です。

既定では、シーン レンダリング操作は、現在表示されているシーンのすべてまたは一部を現在のレンダー ターゲットにレンダリングします。表示では、オブジェクトの現在の状態、表示フィルタ、およびカメラ フラスタム カリングを考慮します。

パス コンテキスト情報を照会するときに、シーン レンダリングがアクティブであれば、その名前が現在のパス ID になり「カラー パス」セマンティックでマークされます。

操作ごとのオーバーライドが多数あります。これらのオーバーライドは、3D ビューポートまたはコマンド ライン レンダリングで設定できるものを反映しています。オーバーライドは、操作が実行される時間に対して設定されます。

次のオーバーライドが可能です。

シーンごとのレンダリングの準備で、プレまたはポスト レンダリング コールバックも指定することができます。

複数のタイプをレンダリングする固有のコストがかかりますが、指定できるシーン操作の数に制限はありません。各呼び出しにより、レンダリング パイプラインが実行されるので、複数の更新と描画フェーズを呼び出すことができます。新しいシステムと古いシステムの主な違いは、複数のシーン トラバーサルがパイプライン ロジックの固有な部分ではなくなったので、複数のシーン トラバーサルが呼び出されないことです。

シェーディングされたパイプライン分割とシェーディングされていないパイプライン分割の例を次の図に示します。オーバーライドの各バリエーションを使用して、シーン操作ごとに異なるパイプラインを作成することができます。

図 48: 最上部のパイプラインは、「シェーディング」と「シェーディングなし」が分離されていないときに発生することの概要の例です。その下に 2 つのパイプライン構成への分割が示されています。「シェーディング」のみのパイプライン(中段)と「シェーディングなし」のパイプライン(最下部)。

クアッド レンダリング

これは、2D スクリーン位置合わせジオメトリック四角形のパッケージ済みレンダリングです。クアッド レンダリングを表すコンストラクトは MQuadRender です。

この操作では、シェーダと指定されたビューポート領域に応じて、レンダー ターゲット全体またはその一部のみを塗り潰してレンダリングすることができます。サブ領域のレンダリングが必要な場合、この操作からクリア操作(MClearOperation)を返すことができます。

MQuadRender は、状態セッタの指定を許可します。既定では、クアッド レンダリング操作のジオメトリをレンダリングするときに、ブレンディングが無効になり、深度書き込みが無効になり、カリングが無効になります。MQuadRender から派生したクラスによって次の方法を実装し、特定の状態に対して既定の動作を置換することができます。

この操作を使用して、レンダー ターゲット(MRenderTarget)にレンダリングできます。このレンダー ターゲットは、クアッド操作に関連付けられているシェーダ インスタンス(MShaderInstance)の適切なシェーダ ロジックを作成することによって、出力として指定されます。また、シェーダ インスタンスは入力として MRenderTargets のセットを取得できるので、クアッド操作で、共有ターゲットを介して操作間の接続を生成できます。

ソース データおよび出力データとしてのレンダー ターゲットの可能なフローを次に示します。

図 49: シェーダ インスタンスは、入力として 0 (ゼロ)または複数のターゲットを取得できます。シェーダは、1 つまたは複数の出力ターゲットに書き込むことができます。

レンダー ターゲットを入力および出力として使用してレンダリングすることができます。デバイス リソース管理によっては、テンポラリ ターゲットが必要な場合があります。この方法でレンダリング ループ ロジックを記述することによって得られる簡略化または明確さと、この機能固有のコストを比較検討する必要があります。

一般に、レンダー ターゲットの「ピンポン」(ターゲットの入れ替え)では、テンポラリ ターゲットが作成されません。これは、プラグインが、競合を回避するためにさまざまな入出力ターゲットを明示的に指定できるためです。たとえば、一連のクアッド操作で、T1 から T2 へ、T2 から T1 へ、T1 から T2 などと書き込むと、ソースとしてのターゲット T1 と宛先としてターゲット T2 の使用を切り替えられます。「ポスト シーン レンダリング カラーの操作」 を参照してください。

クアッド レンダリングでは、いくつかの基本的なセマンティックが提供され、クアッド レンダリングに使用できるパラメータの自動バインドが実行できます。これには、次のものが含まれます。

一般に、パラメータ バインドは操作が実行するので、シェーダ インスタンスの使用可能なパラメータを照会し、必要に応じてバインドできます。たとえば、レンダー ターゲット バインドは手動で実行されます。

反転操作(CgFX)の例

// World-view-projection transformation.
float4x4 gWVPXf : WorldViewProjection < string UIWidget = "None"; >;

// The single filter input, i.e. the image to be manipulated.
texture gInputTex : InputTexture
<
    string UIName = "Input Texture";
>;

// Filter input sampler.
sampler2D gInputSampler = sampler_state
{
    Texture = <gInputTex>;
    MinFilter = Point;
    MagFilter = Point;
    MipFilter = Point;
};

// Vertex shader input structure.
struct VS_INPUT
{
    float4 Pos : POSITION;
    float3 UV : TEXCOORD0;
};

// Vertex shader output structure.
struct VS_TO_PS
{
    float4 HPos : POSITION;
    float3 UV : TEXCOORD0;
};

// Vertex shader.
VS_TO_PS VS_Invert(VS_INPUT In)
{
    VS_TO_PS Out;
    
    // Transform the position from object space to clip space for output.
    Out.HPos = mul(gWVPXf, In.Pos);
    
    // Pass the texture coordinates unchanged.
    Out.UV = In.UV;
    
    return Out;
}

// Pixel shader.
float4 PS_Invert (VS_TO_PS In) : COLOR0
{
    float4 output = tex2D(gInputSampler, In.UV);
    return 1.0f - output;
}

// The main technique.
technique Main
{
    pass p0
    {
        VertexProgram = compile glslv VS_Invert();
        FragmentProgram  = compile glslf PS_Invert();
    }
}

ユーザ操作

プレおよびポスト パス コールバックの固定ストラクチャを持つ代わりに、ユーザ操作は API でエクスポーズされます。この API コンストラクトは MUserRenderOperation です。

この操作は、古いシステムの MViewportRenderer によく似ています。主な違いは、統合のレベルです。MViewportRenderer は非ストラクチャ レンダリング オーバーライドであり、MUserRenderOperation はレンダリング ループ サポート ストラクチャに統合されているアクションです。

MUserRenderOperation は、親 MRenderOperation クラスから継承されるビューポートおよびレンダー ターゲット オーバーライドに加えて、カメラ オーバーライドを指定することができます。

パス コンテキスト情報を照会するときに、ユーザ操作がアクティブであれば、その名前が現在のパス ID になり、パスが「ユーザ パス」セマンティックでマークされます。

「実行」操作にエクスポーズされている 1 つのエントリ ポイントがあります。リファレンスのいくつかのフレームを用意するために、描画コンテキスト(MDrawContext)が提供されています。

図 50: ユーザ操作のために、カメラをオーバーライドできます。実行時に、MDrawContext が提供されます。出力を 1 つまたは複数のレンダー ターゲットに向けることができます。

ダイレクト API コールを経由して描画状態に影響を及ぼすすべてのプラグインと同様に、操作は常にエントリ状態に復元する必要があります。これは、現在の出力ターゲットに対して特に重要です。アクティブな OpenGL コンテキスト、FBO、PBO などの状態は、操作で設定できません。設定されている場合は、前の値を操作の終了時に復元する必要があります。

たとえば、M3dView::beginGL()/endGL() などのコールは、アクティブな OpenGL コンテキストを設定するので、呼び出すことはできません。また、DirectX またはバッチ モードで実行することはできません。

現在の操作

インタラクティブ ビューのレンダー ターゲットを表示するために、現在の操作が提供されます。API では、この操作は MPresentTarget で表されます。

これは、OpenGL のスワップ バッファ コールまたは DirectX での SwapChain の存在にほぼ相当します。

バッチ レンダリングのときは、この操作に意味はなく、自動的に無視されます。

この操作によって、表示されるカラー レンダー ターゲットを指定することができます。指定しない場合は、アクティブな内部設定カラー ターゲットが使用されます。表示される深度をオプションで指定できます。深度ターゲット オーバーライドを指定した場合は、ターゲットからの深度値がスクリーン上のターゲットにコピーされます。

アクティブな立体視レンダリングを処理するときに、出力を左視点または右視点に向けることができます。レンダリング ループでこれを実現するには、左側のバッファにレンダー ターゲットの内容を表示し、右側のバッファにもレンダー ターゲットの内容を表示します。既定のモノ ビューは、センター バッファにレンダリングを指定することによって得られます。

アクティブな立体視レンダリングがビデオ カードでサポートされていて、ドライバが適切に設定されている場合、必要に応じて、MTargetBackBuffer 入力を表示用のルート ターゲットに設定することができます。

図 51: 出力バッファをオーバーライドするようにバックバッファ オプションを設定できます。「現在の」操作は、適切なレンダー ターゲットを「スクリーン上のターゲット」の正しいバッファに送ります。

HUD レンダリング

この操作は、3D ビューポートで 2D HUD の表示を可能にします。API では、これは MHUDRender で表されます。

ストラクチャの概要

図 52

上の図は、さまざまな操作の全体的なストラクチャを示しています。また、さまざまなオーバーライドとリソース(シェーダ インスタンス、レンダー ターゲット)が共有および再利用される方法を示しています。

MShaderInstance から MRenderItem への接続は、レンダリング ループ ストラクチャの明示的な部分ではありませんが、レンダリング ループ(パイプライン)の出力から別のパイプラインを流れるレンダー項目の入力への、データ(レンダー ターゲットまたはテクスチャ)の可能なフローを示しています。この例は、シャドウ マップをシェーダへの入力として提供しています。このシェーダは、シャドウでアイテムをレンダリングします。

オーバーライドの設定と実行

使用可能な操作の基本を解説しましたので、このセクションでは、プラグインによってオーバーライドを設定し、これらの操作を適切に構成して実行する方法を示します。

レンダリング パイプラインを説明するときに使用した用語フェーズは、ここでプラグインの主要機能を説明するために再び使用されます。基本のフェーズは、セットアップ実行、およびクリーンアップです。

セットアップ フェーズの際に次の操作が行われます。

実行フェーズの際に次の操作が行われます。

クリーンアップ フェーズの際に次の操作が行われます。

レンダー オーバーライドのインスタンスおよび操作のインスタンス自体には、暗黙的なリソースがなく、代わりに、外部リソースへのリファレンスのみが維持されます。これらのリソースの寿命を決定するのはプラグインです。可能な場合は、使用可能なリソース マネージャを使用する方法が最適です。プラグインがリソースへのリファレンスを保持している限り、リソースは割り当てられたままになります。操作に戻されるリソース(たとえば、MDrawContext を介して)は、操作が実行される期間のみに存在するリソースの可能性があるので保持することはできません。

図 53: オーバーライドの「フェーズ」の大まかな要素: 事前データ評価と更新、実行時間ロジックの定義と操作呼び出し、最終のクリーンアップ。1 つまたは複数のパイプラインをセットアップすると、操作の更新が操作データ依存関係の変更を表すことができます。たとえば、シェーダ インスタンス パラメータによって使用されるレンダー ターゲットを実行時に変更することができます。

レンダー オーバーライドの例

このセクションでは、いくつかの操作構成例を説明します。

ポスト シーン レンダリング カラー エフェクト

図 54

この例は、深度およびカラー出力ターゲットへの基本的なシーン レンダリングを示しています。2 番目の操作は、最初の操作からカラー ターゲットにカラー エフェクト(たとえば、「ポスタライズ」)を適用し、同じターゲットに書き込みます。これは、同じカラー ターゲットの読み込みおよび書き込みの許可に類似しています。上記の例のように実装することができます。または、2 番目のカラー ターゲットをカラー エフェクトの対象として取得および使用できます。カラー ターゲットを指定しないこともできます。後の例では、アクティブな内部カラー ターゲットが使用されます。

グローの例

「グロー」ポスト効果をサポートするために使用される複合構成は、viewRenderOverride SDK サンプルの一部です。

図 55: この例では、オリジナルのシーン レンダーのしきい値は強度の値に基づいています。結果は 2 パス フィルタを使用してブラー処理され、元のイメージと組み合わせられて非常に基本的な「グロー」エフェクトを生成します。 ユーザ インタフェース要素は最後に描画されます。オリジナルの深度バッファは適切な UI および非 UI 要素の合成を提供するために使用されます。

立体視レンダリング

図 56

これは、立体視表示をサポートするために使用されるプラグインの例です。左にある 2 つのシーン レンダリングは最初に実行される 2 つの操作です。各シーン レンダリングでは、異なるカメラ オーバーライドが使用され、左視点から右視点(カメラ)にレンダリングされます。出力は、2 つのカラー入力に基づいて最終的な合成を実行するために、2 つのカラー ターゲットに渡されます。深度ターゲットは、最終的な内容は必要ないので再利用されます。上部の右側で、アナグリフ パッシブ立体視表示をサポートするために、クアッド レンダリング操作が次の操作として指定されます。必要な最終的なパッシブ立体視表示モードに応じて、クアッド操作に別のシェーダをダイナミックに返すことができます。アクティブな立体視は右下に示されています。これは、左側と右側のカラー ターゲットを左側と右側のスクリーン上のバッファにそれぞれ渡す別の操作構成である場合があります。

Maya の立体視プラグインはこの設計を実装しています。

ビューティ パス カラー合成

図 57

この例は、カラー イメージのみを出力として生成する外部レンダラを、内部フレームワークを使用してレンダリングした残りのシーンと合成する方法を示しています。

3 つの基本的な操作が実行されます。

  1. 最初の(左の) MSceneRender は、シーン内のシェーディングされたオブジェクトに基づいて深度値で深度バッファを用意します。表示モードをシェーディングに設定し、シーン フィルタをシェーディングされたアイテムのみの描画に設定します。使用するシェーダには、いくつかの選択肢があります。カスタム深度シェーダまたは、この例に示すように、アンビエント ライトを使用するソリッド カラー シェーダが使用できます。カラー マスクは、深度ターゲットのみに書き込むように設定されています。
  2. 次の操作(MUserRenderOperation)は、外部レンダラのカラー イメージをカラー ターゲットのみに転送するために使用されます。
  3. 最後の操作(右) MSceneRender は、シェーディングなしのシーン要素のオーバーレイを行います。ここでは、アクティブな Maya オブジェクトのみがレンダリングされます。ターゲットはクリアされませんが、シェーディングされた適切なシーン合成とシェーディングされていない適切なシーン合成(たとえば、「ワイヤフレーム付きシェード」)をサポートするために、深度テストが有効になっています。

複数のレンダー ターゲット

図 58

複数のカラー ターゲットの簡単な使用例は、viewRenderOverrideMRT サンプル プラグインにあります。 ここでは、単一のシーン レンダがシェーダ オーバーライドを使用し、位置と法線値を同時に 2 つの異なるカラー ターゲットに出力します。 結果を視覚化するために、クアッド レンダー オプションを追加してこれら 2 つのターゲットをシェーダへの入力として確保し、これによって 2 つのターゲットの内容を同時進行で転送します。 クアッド レンダリング操作の結果は、2 つの既存のカラー ターゲットのいずれかに書き込まれます。 その後、「現在の」操作がビューポート(図に示されていない)への表示に使用されます。

深度およびカラー レンダリングの合成

外部レンダラが使用され、既存のターゲットへの直接レンダリングが望まれない(あるいは可能でない)場合、推奨されるアプローチは中間ターゲットまたはテクスチャにレンダリングすることです。

続いて、これらの中間データは表示に使用される最終ターゲットに転送することができます。 一度実行されると、深度が適切に準備されている限り、外部レンダラが扱わない追加の UI 要素を合成することができます。

次に、Maya シーンのレンダリング イメージを示します。表示されているのは、最終のカラー(ビューティ)イメージと対応する深度イメージ(オリジナルの値から 0..1 のグレー スケールにリマップ)です。

図 59

サンプルの viewImageBlitOverride プラグインの中の簡単なパイプラインを、次の図に示します。

図 60

レンダリングされたイメージが取得され、カラーと深度のテクスチャとして適切に読み込まれます。 単一のクアッド レンダーは、シェーダを使用してテクスチャをカラーと深度のターゲットに転送します。 これを実行したら、オプションとして、シーン レンダーを使用して「UI」要素の深度を合成します。 ここでは、クリアは無効にして、シェーディングされたレンダー アイテムを無視するためにフィルタが適用されます。

レンダーの作成に使用されるオリジナルのシーンが Maya にロードされると仮定すると、結果は次のようになります。 ワイヤフレームと IK レンダリングは、すべてシーン レンダー パスにより実行されます。

図 61

MQuadRender 操作は状態セッターのオーバーライドを使用します。 既定では、クアッド レンダーのジオメトリをレンダリングする場合、アルファ ブレンディング、深度の書き込み、背面カリングはすべて無効になります。 MQuadRender から派生したクラスによって次の方法を実装し、特定の状態に対して既定の動作を置換することができます。

  • virtual const MDepthStencilState* depthStencilStateOverride(); // 深度ステンシルの状態をオーバーライドします
  • virtual const MRasterizerState* rastersizerStateOverride(); // ラスタライザの状態をオーバーライドします
  • virtual const MBlendState* blendStateOverride(); // ブレンドの状態をオーバーライドします

この例では、深度ステンシル状態インスタンスが作成されました。これは、深度書き込みを有効にし、深度比較を「常に(Always)」に設定します。 その後、インスタンスは depthStencilStateOverride() メソッドのオーバーライドにより返されます。

もう 1 つの可能性(プラグインの例には示されていない)は、レンダラがレンダリングしない非 UI オブジェクトのための追加シーン レンダーを追加することです。 オブジェクト タイプによる基本フィルタを使用することができます。 たとえば、プラグインのオブジェクトはレンダラによって処理されない場合があります。その場合は別のパスで合成されます。 合成の統合のレベルは異なります。

一般に、カラーと深度の両方をレンダリングする統合は、スクリーンスペース アンビエント オクルージョンなどの内部ハードウェアポスト エフェクトと同時には実行されません。 UI の描画のみを行う操作では、ポスト エフェクトは有効になりません。 追加の非 UI シーン レンダーでも、処理の一環でポスト エフェクトを無効にする可能性があります。

デバイスのアクセス権を持つユーザ操作

これは、レンダリング ループ ロジック パースペクティブの単純な構成です。そのロジックは、古いシステムからの MViewportRenderer フリーフォーム実装に最も類似しています。MUserRenderOperation が 1 つだけあります。SDK のサンプル viewDX11DeviceAccess は、フレームワークからさまざまなリソースを割り当てる方法と、レンダー ターゲットおよびテクスチャ(シェーダ リソース ビュー)の GPU ハンドル、状態のブロック、サンプラの状態を抽出する方法を示しています。古い MDrawTraversal インタフェースは、一部のバウンディング ボックスを描画するために、シーン全体をスキャンするのに使用されます。

図 62: セットアップ フェーズでは、GPU デバイス ハンドルが抽出され、いくつかのストック DX ジオメトリが作成されます。テクスチャとサンプラの状態は、フレームワークの適切なマネージャによって割り当てられます。出力ターゲットも割り当てられます。実行フェーズでは、リソースの GPU ハンドルを取得するために一連の手順が実行され、ネイティブ DX コールを使用してすべてのレンダリングが実行されます。

レンダー ターゲット/フレームのキャッシング

レンダリングされたフレームをキャッシングまたは保存することが望ましい場合があります。たとえば、アニメーションを再生するため、または別のアプリケーションで編集するためにフレームをディスク上に保存することができます。このセクションの例では、レンダー オーバーライドを使用してメモリ内にビューポートのフレームをキャッシングし、より素早く再生する方法を示します。

次の図は、フレームをキャッシングしたり、キャッシングされたフレームを再生するシステムを構成する一連のアクションを示しています。色の付いた各エリアは利用可能なアクションの論理的なサブセットを表しています。リソースは緑で示しています。

図 63: 通常のリフレッシュ(青いボックス)、フレーム キャッシュ(緑のボックス)、キャッシングを行うレンダリング パイプライン操作(赤いボックス)、再生でシーン レンダリングの置き換えを行うレンダリング パイプライン操作(黄色いボックス)を示しています。現在の操作は、想定される最終的な表示出力として示しています。出力をシリアル化して保存することもできます。出力はグレーのボックスで示しています。

アニメーション再生時には、各タイム ステップのシーンがビューポートにレンダリングされます。青いボックスでは 2 つの操作を示しています: カラー レンダー ターゲットにシーンをレンダーする MSceneRenderとカラー ターゲットをビューポートに表示する MPresentTarget です。レンダー ターゲットの内容は現在時間にのみ有効です。現在時間が変更されるたびに、新しいコンテンツをターゲットに描画する必要があります。

この再描画を行わないようにするため、内容をキャッシュすることができます。この図では、各キャッシュの要素がハードウェア テクスチャ(MTexture)とフレーム時間(MTime)を参照する、単純なキャッシュを示しています。これらの各要素をシリアル化して保存することができます。

この構造では、レンダー ターゲットのスナップショット(またはコピー)を任意のタイム フレームで取得することができます。この実装では、シーンをレンダーした後、ユーザ操作(MUserRenderOperation、赤)が実行されます。この操作は、テクスチャ(MTexture)にレンダー ターゲットのハードウェア コピーを作成します。この実装ではMDrawContext::copyCurrentColorRenderTargetToTexture()という便利なメソッドを使用してキャッシュされたテクスチャを作成しています。また、このコピーを MSceneRender のポスト レンダー(postRender())メソッドで行うこともできます。

キャッシング操作によるデータの流れは Cache というラベルが付いたリンクで示しています。

再生中にシーンの再レンダリングを停止するため、シーンのレンダー操作をクアッド レンダリング操作(MQuadRender、黄色)で置き換えています。この操作は、指定されたタイム フレームに対してフレーム(テクスチャ)がキャッシュされているかどうかを判断します。フレームが見つかった場合は、カラー レンダー ターゲットにそのテクスチャを描画します。現在の操作はこれまでと同じように実行できます。再生時のデータの流れは Playback というラベルが付いたリンクで示しています。

この例のコードは、開発キットの viewRenderOverrideFrameCache SDK サンプルで確認できます。

複数のパス シーンのレンダリング

次のサンプルは、複数の draw インタフェース(旧式の既定ビューポート内の MPx3dModelView にのみあります)がレンダー オーバーライドを使用してビューポート 2.0 で実行できる方法を説明しています。

このサンプルでは、draw の代わりに、シーン操作が実行されることがあります。この場合、2 つのシーン操作が表示されます。

図 64: プラグインで実装される操作は緑色で表示されます。現在の操作(明るい緑色)はオプションです。クリア メソッドとオブジェクト セット メソッドをオーバーライドするために、目的の実行順序とフィルタ オプションに応じたメソッドごとに、異なる戻りパラメータで新しいクラスが派生します。

最初のシーン操作で、clearOperation() メソッドの戻り値を介してバックグラウンドをクリアします。オブジェクトのサブセットが描画されると、objectSetOverride() メソッドは、適切な値を返します。

2 番目のシーン操作(図の最初の下に表示)は、バックグラウンドをクリアしないことを示します。これにより、描画が累積されます。

オプションで実行できる最後の操作は、現在の操作です。この手順は、アクティブでインタラクティブなビューポートに結果を表示する場合に必要になります。

内側ターゲットは、レンダリングが現在の内部のカラーと深度のターゲットに描画され、プレゼンテーション用のソース ターゲットであることを示します。

開発キットのサンプル viewObjectSetOverride は、このシナリオを実装するソース コードを提供します。サンプルは、Maya の 2 つのセットの内容を照会しています。最初のシーン操作は最初のセットを、2 番目のシーン操作は 2 番目のセットをレンダリングします。

ポスト シーン レンダリング カラーの操作

図 65

この例では、シーン レンダリング後に一連の 2D カラー操作がどのように実行されるかについて説明します。詳細については、Developer Kit サンプル viewRenderOverridePostColor を参照してください。

このプラグインの例には、3 つの 2D クアッド操作(MQuadRender) があり、各操作で異なるシェーダ(MShaderInstance)が使用されています。シーン レンダリングは、カスタム ターゲット(この図ではターゲット 1 (Target 1)と表記)内に格納されています。このターゲットは、2 つ目のターゲット(ターゲット 2 (Target 2)と表記)に対する入力値として使用されます。次のカラー操作では、入力としてターゲット 2 (Target 2)を取得し、ターゲット 1 (Target 1)にルーティングします。以降のカラー操作では、ターゲット 1 (Target 1)からターゲット 2 (Target 2)、ターゲット 2 (Target 2)からターゲット 1 (Target 1)などと書き込むことで、ソースとしてのターゲット 1 (Target 1)と宛先ターゲットとしてターゲット 2 (Target 2)の使用を切り替えられます。

カラー操作の実行後、HUD は HUD 操作を使用して描画され、現在の操作では、最後のカラー操作で使用した出力ターゲットが表示されます。

関連する画像には、魚眼とエッジ検出のシェーダが有効化されたクアッド操作のみが表示されます。