プリミティブのタイプのテクニカル ガイド

レンダリング プリミティブの新規の種類を作成するためのプログラマー用ガイド

Windows
MacOS
Linux

このページはアンリアル エンジン 3 のドキュメントから転載され現在見直しがされています。古い情報が含まれる場合もありますので予めご了承ください。

UPrimitiveComponents はレンダリングおよびコリジョンの対象となる Actor コンポーネントです。このページでは、 UPrimitiveComponent の種類を新規作成する方法を説明します。

Rendering

プリミティブとは、可視性の単位です。視錐体カリングおよびオクルージョン カリングの表示を、プリミティブのバウンディング ボックスを用いて行います。プリミティブのバウンディング ボリュームをバウンド メンバに書き出すために、USceneComponent::CalcBounds を実装する必要があります。

プリミティブは、メッシュ エレメント、線、スプライト、点としてレンダリングされます。プリミティブは、外見を作っているエレメントをシーン マネージャーに列挙します。

PrimitiveComponent から派生した独自のクラスを作成する場合は、対応する FPrimitiveSceneProxy も実装する必要があります。これはプリミティブ コンポーネントのレンダリング スレッドのコピーで、そのコンポーネントをレンダリングするために必要なすべてのデータが含まれていなければなりません。アタッチメント / デタッチメントの最中に、レンダリング スレッドのシーンへのプロキシの追加 / 削除が行われます。これは通常、プロキシが必要とするレンダリング リソースの初期化も行いたい場合です。

プリミティブ シーンのプロキシ

シーン上のレンダリング スレッド ワークは、ゲームスレッドの裏のフレームを宣言します。ゲームスレッドにより大幅に変更される可能性のあるプリミティブのプロパティは、レンダリングスレッド用に複製する必要があります。そうすることで、ゲームスレッドは次のフレームに対しても、同時にそれらを更新できます。PrimitiveComponent は、動的メンバーをミラーリングするプリミティブ シーン プロキシを作成しなければなりません。シーン プロキシを作成できるようにプリミティブの種類を設定するためにプリミティブが登録されると、シーン マネージャーが UPrimitiveComponent::CreateSceneProxy を呼び出します。

ミラーリングされたメンバーの 1 つが変更されると、 MarkRenderStateDirty を呼び出してシーン プロキシを新規作成しなければなりません。シーン プロキシがフレームの最後に再生成されます。

描画エレメント

シーン マネージャーは FPrimitiveSceneProxy::DrawDynamicElements を呼び出して、プリミティブのエレメントを列挙します。プリミティブは与えられた FPrimitiveDrawInterface 上で DrawMesh 、 DrawLine 、 DrawPoint 、 DrawSprite を呼び出し、呼び出し元に対してエレメントを列挙します。DrawDynamicElements は、ビュー、そしてフレームごとに複数回呼び出すことができます。結果はキャッシュされず、プリミティブのエレメントは複数のパスでレンダリングする必要があるかもしれません。DrawDynamicElements はレンダリング スレッド内で呼び出されるので、ゲームスレッドで書き出すことができる PrimitiveComponent のメンバーはすべて FPrimitiveSceneProxy でミラーされ、プリミティブの再アタッチにより更新されなければなりません。

メッシュ エレメントには、プリミティブがシーンにアタッチされた後も静的なままの最適化されたパスがあります。プリミティブがアタッチされると、プリミティブのスタティックメッシュ エレメントの列挙にFPrimitiveDrawInterface のようなインターフェースを使う、 FPrimitiveSceneProxy::DrawStaticElements をシーンマネージャーが呼び出します。スタティックメッシュ エレメントがキャッシュされ、最適化されたレンダリング パスを使用します。DrawDynamicElements とは異なり、DrawStaticElements はゲームスレッドの中で呼ばれます。

ビューのフレームをレンダリングする場合、シーン レンダリング コードが FPrimitiveSceneProxy::GetViewRelevance を呼び出して、プリミティブをビューにどのように関連付けるか決定します。この結果、ビューに対するプリミティブの関連性を説明するフラグ群である FPrimitiveViewRelevance 構造体が返されます。最も重要なフラグは bStaticRelevance and bDynamicRelevance です。これらは、 DrawStaticElements あるいは DrawDynamicElements が列挙したメッシュ エレメントをドローするかどうか判断します。プリミティブの透過、歪み、シーンカラー マテリアルの使用状況に応じて残りのフラグを設定することになります。GetViewRelevance は、レンダリング スレッドの中で呼び出されます。

ヒット プロキシを使って、プリミティブからクリック認識精度を分離することができます。ヒット プロキシはドローされたそれぞれのエレメントに関連づいており、エディタ内でユーザーがクリックしたものに関する追加情報を提供します。デフォルトのビヘイビアには、プリミティブのオーナーを向いている HActor を使用します。プリミティブの様々なエレメントに関する情報をもっと提供したい場合は、 自分のプリミティブが使用しているヒット プロキシを割り当てるために、FPrimitiveSceneProxy::CreateHitProxies を実装しなければなりません。ヒット プロキシは FPrimitiveDrawInterface::SetHitProxy と FStaticPrimitiveDrawInterface::SetHitProxy へパスされることがあります。CreateHitProxies は、ゲームスレッドの中で呼び出されます。

レンダリング スレッドから PrimitiveComponent へのアクセス

PrimitiveComponent は、プリミティブ シーン プロキシの 1 つが割り当てられ、レンダリング スレッドのコードを実行している限り、ガーベジコレクションが絶対に行われないように、レンダリング コマンド フェンスを使います。

ゲームプレイ中に PrimitiveComponent のメンバーが静的な場合、レンダリング スレッド内のプリミティブ シーンから直接そのメンバーにアクセスすることができます。

ゲームプレイ中に PrimitiveComponent のメンバーが動的な場合、プリミティブ シーン プロキシ内でミラーするか、もしくはアクセスをシリアル化することができます。グローバルな FlushRenderingCommands 関数を使ってアクセスをシリアル化することができます。FlushRenderingCommands は、レンダリング スレッドがアイドルになるのを待ちます。レンダリング コマンドが待機状態になるまでレンダリング スレッドはアクセスしないという前提で、共有のメンバーに書き出すことができます。

ライティング

レンダラーは、ディファード・シェーディング パスに動的ライトを適用します。

FLightCacheInterface を実装し、メッシュ エレメントの LCI メンバーに実装をパスすることで、メッシュ エレメントに静的な光源を提供することができます。FLightCacheInterface はオプションでライトマップとライト GUID からのマップを詳細なライト インタラクションの情報へ提供します。ライト インタラクションの情報には FLightInteraction が含まれていて、キャッシュされていない、または関連性がなかったり、ライトマップ化、頂点シャドウ マップ化、テクスチャ シャドウ マップ化されていることがあります。

静的光源処理を完了させるには、UPrimitiveComponent::GetStaticLightingInfo を実装する必要があります。プリミティブのメッシュとマッピングを列挙するために、静的光源システムが事前計算中にそれを呼び出します。

静的光源メッシュは、静的光源をオクルードあるいは反射するトライアングル群です。

静的光源マッピングは、静的光源メッシュ上の静的光源テクスチャもしくは頂点バッファのマッピングです。静的光源システムは、マッピングのためにライトマップとシャドウ マップを計算し、マッピング用に実装した Apply 関数へパスします。

Tags
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback