MRenderOverride を使用してプラグインを作成し、レンダリング パイプラインを置き換えることができます。このプラグインでは、パイプラインの標準操作(またはパス)が使用でき、また他のカスタム操作も追加できます。このためには、プラグインで、まず現在のパイプラインを表す操作セットを取得し、次に、操作の追加、挿入、削除により、これを修正する必要があります。
標準操作は、パスの動作を決めるさまざまな設定およびフィルタによってコントロールされます。これにより、基本的なビューポートのコントロールが可能になり、表示するオブジェクトのフィルタリング、使用する表示モード、マテリアル オーバーライド、ポスト プロセスなどが便利になります。
操作リストに設定することによって MRenderOverride のプラグインを作成する利点は、ターゲットの作成または管理をプラグインの実装に含める必要がない点です。これは、システムによって自動的に処理され、操作レベルまで押し下げられます。
MRenderOverride を使用する欠点は、パイプライン全体をオーバーライドする必要があり、パイプラインに対するいかなるカスタマイズも、まったく新しいレンダラとして使用する必要がある点です。MRenderOverride の詳細については、「レンダリング オーバーライド」を参照してください。
次のクラスおよびインタフェースを使って、上記の MRenderOverride を作成できます。
MRenderOperationList クラスは、MRenderOperation のコレクションの所有権を保持、取得します。このクラスには、リスト内の操作について、インデックス作成、追加、削除、置換を行うための、リストの標準メソッドがあり、リストから操作の所有権を取得するメソッドも含まれています。
MRenderer::getStandardViewportOperations() インタフェースを使うと、オーバーライドされていない描画に使用される標準ビューポート操作でリストを埋めることができます。
MRenderOverride の保護されたメンバーである、
MRenderOperationList mOperations
MRenderOverride から派生するクラスで必要なことは、標準リストを取得する、独自の操作を追加する、またはこの両方を組み合わせることにより、リストに操作を設定することだけです。
//Get the standard list of operations MHWRender::MRenderer::theRenderer()->getStandardViewportOperations(mOperations); //Create a custom quad render operation PostQuadRender* swirlOp = new PostQuadRender( kSwirlPassName, "FilterSwirl", "" ); swirlOp->setEnabled(false); // swirl is disabled by default //Insert swirlOp in the pipeline after the kStandardSceneName operation mOperations.insertAfter(MHWRender::MRenderOperation::kStandardSceneName, swirlOp);
使いやすくするために、標準操作の名前がいくつか定義されています。これらの名前は、標準操作リストの操作を見つけるのに使用できます。
大きな操作リストに追加されたときに、操作がより自律的で自己記述的であるようにするために、ターゲットの管理は操作レベルで処理されます。
MRenderOperation から派生するクラスでは、次の実装を行う必要があります。
MRenderOperation には、上記の最初の手順で使用できる、保護されたメンバー変数が 2 つあります。
MStringArray mInputTargetNames
MStringArray mOutputTargetNames
入力と出力を宣言するには、操作で使用するターゲットの名前(つまり、セマンティック)を追加する必要があります。MRenderOperation クラスでは、一般的なターゲット タイプがいくつか定義されています。
static const MString kColorTargetName; static const MString kDepthTargetName; static const MString kAuxiliaryTargetName; static const MString kAuxiliaryTarget2Name; static const MString kAuxiliaryTarget3Name; static const MString kAuxiliaryTarget4Name; static const MString kAuxiliaryDepthTargetName;
既定では、すべての MRenderOperation は、標準のカラー ターゲットおよび深度ターゲットの名前を入力として使用するため、書き込みまたは読み取りに標準ターゲットを使用する、リスト内の他の操作に自動的に接続します。現在アクティブなターゲットに単に書き込む操作に必要なことはこれだけであり、これはベース クラスで実装されています。
たとえば、次のコードの断片では、2 つの既定の入力と、2 つの既定の出力を宣言しています。
mInputTargetNames.append(kColorTargetName); mInputTargetNames.append(kDepthTargetName); mOutputTargetNames.append(kColorTargetName); mOutputTargetNames.append(kDepthTargetName);
複数のターゲットに対して読み取りまたは書き込みを行う MRenderOperation クラスでは、リストをクリアして独自の入力、出力を追加することにより、既定の入力および出力をオーバーライドできます。
mInputTargetNames.append(kAuxiliaryTargetName); mInputTargetNames.append(kAuxiliaryDepthTargetName); mInputTargetNames.append(“sceneTarget”); mInputTargetNames.append(“sceneDepthTarget”); mOutputTargetNames.append(kColorTargetName); mOutputTargetNames.append(kDepthTargetName);
次に、カスタム パスにおいて、名前が付けられた入力ターゲットのディスクリプションを提供できます。次の例では、マルチサンプル アンチエイリアシングのプロパティおよびサイズが一致するように、補助ターゲットからディスクリプションをコピーしています。
bool PostQuadRender::getInputTargetDescription(const MString& name, MHWRender::MRenderTargetDescription& description) { if (name == “sceneTarget”) { MHWRender::MRenderTarget* outTarget = getInputTarget(kAuxiliaryTargetName); if (outTarget) outTarget->targetDescription(description); description.setName("_post_target_1"); return true; } else if (name == “sceneDepthTarget”) { MHWRender::MRenderTarget* outTarget = getInputTarget(kAuxiliaryDepthTargetName); if (outTarget) outTarget->targetDescription(description); description.setName("_post_target_depth"); return true; } return false; }
MRenderOverride プラグインでは、名前が一致するように操作を接続できます。
//Get MRenderOperationList of the standard viewport operations MHWRender::MRenderer::theRenderer()->getStandardViewportOperations(mOperations); //Get the index of the operation kStandardSceneName int sceneOpID = mOperations.indexOf(MHWRender::MRenderOperation::kStandardSceneName); //Set sceneOp to point to the kStandardSceneName operation in the MRenderOperationList MRenderOperation* sceneOp = mOperations[sceneOpID]; //Rename the output target of the kStandardSceneName operation from kColorTargetName to sceneTarget sceneOp->renameOutputTarget(MHWRender::MRenderOperation::kColorTargetName, “sceneTarget”); //Create the new MRenderOperation swirlOp PostQuadRender* swirlOp = new PostQuadRender( kSwirlPassName, "FilterSwirl", "" ); // Insert swirlOp after the operation named kStandardSceneName // Because swirlOp has an input named sceneTarget, and you have renamed the output target // of kStandardSceneName to sceneTarget, the two operations will share the same target. // The target is constructed from the description provided by the swirl // operation and is the target that the scene operation should render to. mOperations.insertAfter(MHWRender::MRenderOperation::kStandardSceneName, swirlOp);
開始インデックスと、MRenderOperation が書き込むターゲット数を指定するには、次のようにします。
int PostQuadRender::writableTargets(unsigned int& count) { count = 2; return 0; }