カスタム プリミティブ データ (CPD:Custom Primitive Data) ワークフローでは、マテリアルを使用してブループリントとコードからアクセス可能なインデックス配列にカスタム データを保存することができます。このデータを使用して、ランタイム時のシーン プリミティブに変更を加えることができます。
これは マテリアル インスタンス ダイナミクス (MID:Material Instance Dynamics) と同様に機能し、スカラー パラメータおよびベクター パラメータを使用して、ランタイム時にマテリアル グラフの一部を動的に制御することができます。この違いは、カスタム プリミティブ データには、マテリアル インスタンスではなくプリミティブ自体にデータを保存する利点があることです。これにより、壁、床、その他の複製されたジオメトリなど、レベル内に同様に配置されたジオメトリのドローコール回数を減らすことができます。
使用方法とワークフロー
カスタム プリミティブ データは、次の方法でシーンのプリミティブに対して機能します。
- スカラーとベクターのマテリアル パラメータを設定して、マテリアル ロジックの一部を制御する。動的に設定および制御する各パラメータで [Use Custom Primitive Data (カスタム プリミティブ データを使用)] を有効にします。
- このオプションが設定されたパラメータごとに、ブループリントやコードで参照可能な一意の [Primitive Data Index (プリミティブ データ インデックス)] を指定する。
- ブループリントの Set Custom Primitive Data ノードを使用して、カスタム データ配列に保存された値にマテリアル パラメータを設定して制御する。
マテリアルの設定
マテリアル インスタンス のように、スカラー パラメータ および ベクター パラメータ の式をグラフに追加してマテリアルの属性を制御します。
パラメータを選択した状態で、[Details] パネルで Use Custom Primitive Data プロパティを検索して有効にします。
有効にすると、パラメータには指定した名前の下に「Custom Primitive Data」という文字と、Primitive Data Index で割り当てられた値が表示されます。この値は、ノード自体にも表示されます。
Primitive Data Index の値には、このパラメータを保存する割り当て済みのインデックスを設定します。このインデックスはブループリントとコードでのパラメータの参照に使用されます。
インデックスを スカラー (浮動小数) パラメータに割り当てる場合、インデックスは単一の値です。ベクター パラメータで同じことを行う場合、パラメータの各チャンネルには Primitive Data Index の別の値が割り当てられます。上の画像では、スカラー パラメータが Index 0 に割り当てられ、ベクター パラメータが Index 1、2、3、および 4 に割り当てられています。RGBA 出力ごとに 1 つのインデックス値です。
ブループリントの使用方法
次のノードを使用するブループリントを介して、カスタム プリミティブ データを使用するシーン プリミティブにアクセスすることができます。
- Set Custom Primitive Data Float
- Set Custom Primitive Data Vector
これらのノードで、パラメータ名と文字列を一致させる必要はありません。代わりに、割り当てられた Primitive Data Index を使用して、プリミティブごとに配列のデータを設定して取得します。
この配列のカスタム データにマテリアルからアクセスする操作は、マテリアル インスタンスのマテリアル パラメータの操作に似ていますが、パラメータ ノードでは、マテリアルのパラメータが番号付きインデックスではなく、文字列に一致する必要があるという点で異なります。
アクタのデフォルトの使用方法
アクタにカスタム プリミティブ データのデフォルト値を設定するには、[Details] パネルでスタティックメッシュ コンポーネントを選択し、[Custom Primitive Data Defaults] セクションを展開します。プラス記号 (+) のアイコンを使用して要素を配列に追加します。配列には、Primitive Data Index の値とともにマテリアルの名前付きカスタム データ パラメータが入力されます。
それぞれの番号付き配列要素は、対応する値を持つカスタム プリミティブ データ インデックスを参照します。配列要素のインデックスが存在しない場合は無視されます。この方法でデフォルト値を設定することは、ブループリントをアタッチしたり、これを制御するマテリアル インスタンスを作成したりすることなく、いくつかの値を手動で調整する場合に最適です。
設定例
次の例は、いくつかのパラメータ (スカラーとベクターの両方) で実行される単純なマテリアルの使用方法を示しています。ここではベクター パラメータからランダムに色を選択し、シーンのメッシュにエミッシブとオブジェクト スケールを設定します。ブループリントは、保存したカスタム データに対してこれら 3 つのパラメータを実行するために使用します。
マテリアルの設定例
このマテリアル設定では、このマテリアル グラフ内の 3 つのパラメータで Use Custom Primitive Data が有効になっています。
ベース カラー と エミッシブ の強度は、「Color Param」という名前の Vector 4 パラメータと「Emissive Power」という名前のスカラー パラメータの 2 つのパラメータによって制御されます。
グラフの下の部分では、ロジックを使用して、レベル内で割り当てられているメッシュを均一にスケールしています。「Scale_XYZ」という名前のスカラー パラメータは、割り当てられているオブジェクトをどれくらいスケールするかを制御します。
ブループリントの設定例
マテリアル インスタンス ダイナミクスと同様に、パラメータのカスタム データにより、ランタイム時にブループリントまたはコードを使用して変更を加えることができます。次に示すグラフでは、こうしたマテリアル パラメータの値を設定して更新し、ゲームプレイ中に色、エミッシブ、および初期スケールをランダム化します。
Event BeginPlay では、Set Custom Primitive Data ノードを使用して色、スケール、およびエミッシブのパラメータ初期値を設定します。Data Index プロパティにより、そのノードのターゲットとなるマテリアル パラメータが決まります。
たとえば、Emissive Power パラメータが Index 4 に割り当てられると、その値は Data Index 4 をターゲットとするブループリント ノードによって設定されます。
Event Tick では、Set ノードで各 Custom Primitive Data パラメータのプリミティブ データ インデックスを参照し、Delay ノードに定義されている間隔で新しい色、エミッシブの強度、およびスケールが設定されます。3 つのランダムな浮動小数値を Vector 4 に結合することで色が設定され、エミッシブの強度とスケールは、Random Float in Range ノードを使用してランダム化されます。
Event Tick の設定と使用には注意が必要です。このデモで行う簡単なテストとデバッグには適していますが、ランタイム時の継続的な使用には必ずしも最適ではありません。
例の結果
この例の結果として、ブループリントによって制御される 3 つのカスタム プリミティブ データ パラメータを持つマテリアルが完成し、それによりメッシュの色、エミッシブの強度、スケールを設定することができます。ランタイム時に値が設定され、ブループリントで定義されているように 0.5 秒おきにランダムに更新されます。
マテリアル インスタンス ダイナミクスの比較
カスタム プリミティブ データの設定と使用方法は、マテリアル インスタンス ダイナミクス と似ています。このセクションでは、それぞれに必要なマテリアルとブループリントの設定を比較し、似ているところと違うところをよりわかりやすく示します。
マテリアル インスタンス ダイナミクスを作成する場合、後にブループリントで必要になるのはパラメータの名前のみです。カスタム プリミティブ データ ワークフローでは、各パラメータの Use Custom Primitive Data オプションが有効になっている必要があり、また、後からブループリントで参照される一意の Primitive Data Index 値が割り当てられている必要もあります。
MID マテリアル パラメータ | カスタム プリミティブ マテリアル パラメータ |
次の画像は、ブループリントの設定についてマテリアル インスタンス ダイナミクスの場合とカスタム プリミティブ データの場合で比較したものです。
-
マテリアル インスタンス ダイナミクスのワークフロー:
マテリアルでのインスタンス化に関する追加情報については、「インスタンス化マテリアル」を参照してください。
-
カスタム プリミティブ データのワークフロー:
ワークフローは似ていますが、ブループリントでいくつかの追加ステップがある点が異なります。MID ワークフローには、Create Dynamic Material Instance ノードと、必要なパラメータのマテリアルにある文字列と一致する パラメータ名 を参照するいくつかの Set Parameter Value ノードが必要です。
レベル内でこれら両方の設定をランタイム時に比較すると、ビジュアルの面で同じであることがわかりますが、カスタム プリミティブ データには、メッシュ描画リファクタリングを使用してパフォーマンス上の節約を実現できるというメリットがあります。これについては次のセクションで説明します。
映像で、左側の 4 つの球体のクラスタはカスタム プリミティブ データを使用し、右側の 4 つの球体はマテリアル インスタンス ダイナミクスを使用しています。結果がビジュアル的にまったく同じであることに注意してください。
パフォーマンス
カスタム プリミティブ データ ワークフローには、カスタム データでのマテリアル設定を使用する際に、レベル内にある類似したジオメトリのドローコールを大幅に削減できるというメリットがあります。シーン プリミティブを自動的かつ動的にインスタンス化する Mesh Drawing (メッシュ描画) リファクタリングを使用して、ドローコールを削減します。
レベルの動的インスタンス化がどれほど機能しているかを確認するには、コンソール (`) を開いてコマンド「stat scenerendering
」を入力します。
このコマンドを使用すると、現在のシーン ビューの全般的なレンダリング統計情報が表示されるため、まずはレンダリング プロセスにおいて全般的にパフォーマンスの低い領域と、シーンのメッシュ ドローコールおよびライトの数のカウンターを確認することから始めます。
レベル ビューポートでの作業中に G キーを押してゲーム ビュー モードを切り替えるか、[Play-In-Editor (PIE)] または [Simulation (シミュレーション)] を選択して、より正確な結果を取得します。これらのオプションをいずれも使用しない場合、指向性ライトのアイコンなど、他のドローコールはエディタのみのジオメトリとなります。
このシーンの例では、フロア メッシュ、背景の Sky Sphere (天球) メッシュ、マテリアルでカスタム データを使用して複製したいくつかのメッシュから始めます。
シーン レンダリング統計情報には、このビューに登録されているドローコールの数 (現在、全部で 14 個) が表示されています。
エンジンによってドローコールとメッシュ描画ポリシーが自動的かつ動的に結合されるため、動的インスタンス化を無効にして、このシーンで現在どれくらい機能しているかを確認してみます。次のコマンドで無効にします。
r.MeshDrawCommand.DynamicInstancing 0
プリミティブのいくつかで「Mesh draw calls
(メッシュ ドローコール)」の数が増えていることに注意してください。
より劇的な違いを出すために、Custom Primitive Data を使用するメッシュをさらに複製します。この例ではさまざまなサイズの球体を 25 個用意します。
-
動的インスタンス化を無効にすると、「Mesh draw calls」が「94」 になります。マテリアル インスタンス ダイナミクスを使用すると、カスタム プリミティブ データのようにインスタンス化されないため、同様の結果が得られます。
-
動的インスタンス化を再び有効にすると、「Mesh draw calls」が「46」 になります。
マテリアルにカスタム データを保存して、レベル内で同様のジオメトリを使用すると、マテリアル インスタンス ダイナミクスなどの代替メソッドを使用する場合であっても、ドローコールの数に明確な違いを確認することができます。
追記
- Float の 32 の制限
- 今後のリリースで、これは [Project Setting (プロジェクト設定)] から構成可能な設定になる予定です。
- ユーザー定義のデフォルトおよびカスタム プリミティブ データ パラメータ値のオーバーライドに関するサポート
- 現在、マテリアルでカスタム プリミティブ データ パラメータを設定する場合、デフォルト値は常に「0」です。エディタでの作業時に初期値を設定する場合は、マテリアルが割り当てられているメッシュでブループリントのコンストラクション スクリプトを使用してこれを行うことが可能です。