3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

インスタンスにIDを与える

Last updated at Posted at 2020-06-05

UE4でのインスタンシング

SV_instanceidが取れなかった

これまでUE4ではSV_instanceidがVRの用途でしか使われておらず、マテリアル上からは取得できませんでした。
したがって、インスタンス毎の違いを出すには、PerInstanceRandomノードを使ったり、インスタンスの初期位置をインデックスに見立てるなどの回りくどい処理をする必要がありました。

CustomDataの登場

最近InstancedStaticMeshにインスタンス毎のカスタムデータが設定できるようになり、ここにIDを突っ込む事で、これまでややこしかった処理が簡単に書けるようになりました。
###なにが楽になったのか
RenderTargetとInstancedStaticMeshをつかってUAV的な事をやる場合に、読み込むデータの位置や、書き込み先の割り出しが容易になりました。
特にエンジン改造やC++のコードが必要ではないので、CSなどのプラグイン作成をするほどではない部分や、ナイアガラだと実装しづらい部分の隙間を埋めることが出来ます。

##実装例 リアルタイムヒストグラム実装
ここでは実際の実装例として、以下の動画にあるリアルタイムヒストグラムを解説します。

簡単なものなので、大まかに流れだけ説明します。 ###準備するもの ①InstancedStaticMeshをもったBPアクター ②①のInstancedStaticMeshにアサインするためのマテリアル ③SceneCapture2D ④256*1でFP16のRenderTarget ⑤結果を描画するためのポストマテリアル ###インスタンスにIDを振る ①のBPアクターにInstancedStaticMeshを追加します。 メッシュは1m*1mの正方形(/Engine/BasicShapes/Planeで構いません)をアサインし、マテリアルは②をアサインします。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/bee31796-103d-1f35-12ec-6de3ebd3183a.png) 追加InstancedStaticMeshComponentに、CustomDataを一つ追加します。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/d1074926-8773-5848-295c-2c42443aa624.png) BPアクターのConstrutionScriptにて、サンプリング数分(今回は100*100の1万個)のインスタンスを作成し、同時にCustomDataを書き込んでいきます。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/e850d5fc-e974-ffb3-0f1f-82afa6fc574c.png) ###インスタンス用マテリアルの実装 まず、②のマテリアルはUnLitで”加算”設定にし、出力のエミッシブには1を設定します。書き込み先であるRenderTargetの値をインクリメントさせて行くためです。 次に、割り当てられたID(0~9999)から、シーンの画像中で自身がサンプリングすべき位置(UV)を算出し、フェッチします。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/9d12806d-a2a1-06fc-627a-10b640b4783e.png) そして、その輝度(0~1.0)を256*100倍してWPOに渡します。これで書き込み先をどこにするか決定しています。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/c2b3b6f7-dcc9-abac-bd14-98eb9a85f3e7.png) ###RenderTargetへの書き込み ①のアクターを(-12800,0,0)に配置します。 ③のSceneCapture2DのモードをUse ShowOnlyListに設定し、ShowOnlyActorsに①のアクターだけを追加します。 ③のSceneCapture2Dの設定を正射影にし、OrthoWidthを25600に設定します。 ターゲットには④の1Dターゲットを指定します。 ここまでで、以下のような描画結果になります。左端(0,0)が一番暗い所、右端(255,0)が一番明るい所に対応しており、シーン中使われてる輝度が多い所ほど値が大きくなっています。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/15b00b46-7b45-1560-252c-9932502ee1b1.png) ###結果の表示 出来上がった1Dテクスチャをポストマテリアルでフェッチして、グラフ表示すれば、CPUへの書き戻しなしで、ヒストグラムを描画する事ができました。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/5d27588a-6853-2cd5-2417-242c723acf1d.png) ###まとめ 実戦投入するにはいくつか整理日する必要がありますが、実装自体は半日かからずサクッとお手軽にできました。 次は、DOFなどで使われてるような、任意の形状にボケるスキャッターベースのブラーなどを時間あれば同様の手法で実装してみたいと思います。
3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?