LoginSignup
11
6

More than 3 years have passed since last update.

UE4で平面メッシュをコンピュートシェーダで変形させサインカーブの波面を作る

Last updated at Posted at 2019-11-17

概要

UE4で頂点バッファをコンピュートシェーダで編集するサンプルプロジェクトを作りました。
エンジン改造はせず、プロジェクトプラグインとして実装しています。
Githubにあげています。
何かいけてないことがあれば何でもご指摘ください。

レイトレーシングについては現状では配慮できてません。

Githubレポジトリ

動機

メッシュの変形はパフォーマンスを考える必要がある部分ではGPU側で行いたいですが、UE4のマテリアルだとWorld Position Offset以外に方法がなく、適用範囲が限定されます。
エンジン改造せずにCSで行う最初の検証としてHello World的なものを作りました。
せっかくなので公開しました。

スクリーンショット

SinWaveGridDemoマップのプレー中
SinWaveDeformGridMesh.gif

実装の補足説明

GlobalShaderプラグインについてはじめての方は、前回僕の書いたものをまず見てもらう方が導入がスムーズだと思います。
前回書いた、CSでレンダーターゲットに描画する記事
そちらの方がソースコードが短く、読み解きやすいからです。

ベースとなっている知識については、下に参考にした資料をあげるのでそちらを見ていただいた方がいいと思います。
本記事は、下にあげる参考資料を読んで理解できる方を読者として想定しています。
また、本記事では、ソースコードを部分的にとりあげて解説するようなことはせず、ソースコードを読んでもらう前提で、参考になるような補足説明を書きます。

全体的な実装方針として、なるべく読みやすくなるように、また、CSでの頂点デフォームをするためのテンプレートにできるように、最小限の実装にすることを心がけました。

SinWaveGridMeshComponentというコンポーネントを実装しています。
SinWaveGridDemoマップに配置したSinWaveGridActorは、コンポーネントにパラメータを設定しているだけです。
親クラスのUDeformableMeshComponent::InitGridMeshSetting()でグリッドジオメトリの頂点配列とインデックス配列を作っています。
描画はFPrimitiveSceneProxyを継承したFSinWaveGridMeshSceneProxyに任せます。

メッシュ描画パイプラインに投入する各種バッファの実装はFStaticMeshVertexBuffersから必要な部分をコピペしてFDeformableMeshVertexBufferというクラスを作っています。
メッシュ描画パイプラインの各描画パスを独自に作るようなこともしておらず、素直にUE4のメッシュ描画パイプラインに乗せています。
バーテックスファクトリはFLocalVertexFactoryをそのまま使っています。

レンダースレッド側の処理はSinWaveGridMeshDeformer.cppにまとまっています。
コンピュートシェーダはSinWaveDeformGridMesh.usfとGridMeshTangent.usfの2つあります。
前者は頂点のZ座標をサインカーブになるように設定します。
後者は、その結果としての頂点位置から法線と接線(TangentZとTangentX)を計算する処理です。
TangentZとTangentXを計算する処理は、完全に今回の等方性のあるグリッドジオメトリを前提としており、任意のジオメトリで通用する処理ではありません。

結果は全く面白くもなんともないですが、これをベースにいろんなシェーダを書けば、例えば布表現や水面表現など、もっと面白い表現ができると思います。

参考資料

ながさんのブログ記事

https://nagakagachi.hatenablog.com/entry/2019/09/22/222604
最も参考にさせていただいた記事です。ながさん、ありがとうございます。

今回の実装方針についてはながさんのものとほぼ同じです。

UE4のドキュメント

https://docs.unrealengine.com/ja/Programming/Rendering/ShaderInPlugin/Overview/index.html
https://docs.unrealengine.com/ja/Programming/Rendering/MeshDrawingPipeline/index.html
Epicさん、いつもありがとうございます。

参考にしたUE4のソースコード

HairStrandsプラグイン
https://github.com/EpicGames/UnrealEngine/tree/4.24/Engine/Plugins/Experimental/HairStrands

4.24まではUE4ではCSで頂点バッファをいじるようなものはなかったと思いますが、4.24でHairStrandsプラグインが追加されました。
シミュレーションからレンダリングまでかなり広範囲の実装をしており、参考になります。

課題

そもそも検証としては、やってることが簡易すぎて、実装上の問題を見落としているかもしれません。
最小の実装とするためにFLocalVertexFactoryを流用し、FStaticMeshBuffersを真似しましたが、業務レベルでちゃんとやるならFRWBufferを使って専用のバッファを実装し、バーテックスファクトリも専用のものを実装すると思います。
また、ちゃんと使うなら、用途に応じて、パスをはさむタイミング、非同期コンピュートの検討、パフォーマンス測定、バッファフォーマットの検討などいろいろ考えねばなりませんね。

それはまた別の機会に書かせていただくかもしれません。

11
6
2

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
11
6