#概要
UE4でレンダーターゲットテクスチャをピクセルシェーダあるいはコンピュートシェーダで描画し、マテリアルで使用するサンプルプロジェクトを作りました。
エンジン改造はせず、プロジェクトプラグインとして実装しています。
Githubにあげています。
何かいけてないことがあれば何でもご指摘ください。
#Githubレポジトリ
https://github.com/monguri/UE4ShaderPluginSandbox
#動機
描画パスを追加してVSPSあるいはCSを動かし、その結果を他のパスで使う、ということをしたかったので、その最初の検証としてHello World的なものを作りました。
せっかくなので公開しました。
#実装の補足説明
ベースとなっている知識については、下に参考にした資料をあげるのでそちらを見ていただいた方がいいと思いますので、このプロジェクトに限定した説明を書きます。
RenderTextureActorをマップに配置してTickを回し、Tickの中でレンダースレッドのコマンドキューにコマンドを追加しています。
レンダリングに関する部分はRenderTextureRenderingに分離しています。
コマンドは2つあり、一方はVSとPSでTextureRenderTarget2Dに描画をしています。
もう一方はCSでCanvasRenderTarget2Dに描画をしています。
PSはテクスチャのRチャンネルを塗りつぶしてるだけ、CSもGチャンネルを塗りつぶしてるだけの簡単なものになっています。
TextureRenderTarget2Dの方はスフィアのスタティックメッシュのマテリアルに使い、CanvasRenderTarget2Dの方はキューブのスタティックメッシュのマテリアルに使っているので、プレー後はそれらが赤と緑に塗りつぶされます。
結果は全く面白くもなんともないですが、これをベースにいろんなシェーダを書けば面白い表現ができるかもしれません。
CSでTextureRenderTarget2DでなくCanvasRenderTarget2Dを使っているのは、bCanCreateUAV = trueになっているからです。
ソースを追っていくとわかりますが、例えばDX11の場合だとテクスチャ作成時にD3D11_BIND_UNORDERED_ACCESSが立つかどうかになるため、UAVとして使うには必要です。
CanvasRenderTarget2Dは4.23からbCanCreateUAV = trueが追加されており、これが何の意図によるものだったのかは未確認です。
ちなみに4.22でもbCanCreateUAV = trueを加えれば動作することを確認しています。
#参考資料
##サイアメントの瀬尾さんのブログ記事
http://www.sciement.com/tech-blog/c/structured_buffer_compute_shader_ue4_part1/
最も参考にさせていただいた記事です。瀬尾さん、ありがとうございます。
レンダーターゲットでなくstructured bufferを出力バッファにしているところは違いますが、やってることはほとんど同じです。
https://github.com/HSeo/ComputeShaderUE419Test
UE4は4.20以降に関連する描画周りの書き方が変わっていて、こちらは4.20以降はビルドが通らなかったり実行時にシェーダのファイルパスが見つからないエラーが出たりしますが、UE4のLensDistortionプラグインとか参考にすればちょっとの修正で対応できます。
##Teraman氏のサンプル
https://github.com/Temaran/UE4ShaderPluginDemo
CSでUAVに描画をしたあと、それをVSPSで別のテクスチャにコピーしてマテリアルで使用しています。
Teramanさん、ありがとうございます。
これも4.23で動くように書き直そうかと思いましたが自作を優先しました。
##UE4のドキュメント
https://docs.unrealengine.com/ja/Programming/Rendering/ShaderInPlugin/Overview/index.html
Epicさん、いつもありがとうございます。
2019/10/26追記
##ヒストリアさんの記事
http://historia.co.jp/archives/12659/
4.22以降でGlobalShaderの動くサンプルが公開されてるものがないなーと思い今回の公開に踏み切ったのですが、ヒストリアさんでVSPSについては公開されてる記事があることを後から知りました。
コードについても丁寧な解説があるので読むことをおすすめします。
##参考にしたUE4のソースコード
LensDistortionプラグイン
VectorField.cpp
DispatchComputeShaderとかで検索すればたくさん面白いソースが見つかります。
#課題
そもそも検証としては、やってることが簡易すぎて、実装上の問題を見落としているかもしれません。
また、ちゃんと使うなら、用途に応じて、パスをはさむタイミング、非同期コンピュートの検討、パフォーマンス測定、レンダーテクスチャ以外の出力バッファの検討、テクスチャフォーマットの検討などいろいろ考えねばなりませんね。
それはまた別の機会に書かせていただくかもしれません。