<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Compute Shader on ながむしメモ</title><link>https://nagakagachi.github.io/categories/compute-shader/</link><description>Recent content in Compute Shader on ながむしメモ</description><generator>Hugo</generator><language>ja-JP</language><lastBuildDate>Fri, 20 Mar 2020 06:00:00 +0900</lastBuildDate><atom:link href="https://nagakagachi.github.io/categories/compute-shader/index.xml" rel="self" type="application/rss+xml"/><item><title>UE4 ComputeShader Write, Material Read (GPGPU)</title><link>https://nagakagachi.github.io/entry/2020/03/20/060000/</link><pubDate>Fri, 20 Mar 2020 06:00:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/03/20/060000/</guid><description>&lt;p&gt;エンジンバージョン:4.24 (4.25がリリースされたら対応予定)&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#はじめに"&gt;はじめに&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#サンプルコード"&gt;サンプルコード&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#説明"&gt;説明&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#RWテクスチャ定義"&gt;RWテクスチャ定義&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#RWテクスチャのUAV生成"&gt;RWテクスチャのUAV生成&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#ComputeShaderによるRWテクスチャへの書き込み"&gt;ComputeShaderによるRWテクスチャへの書き込み&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#RWテクスチャのマテリアルでの利用"&gt;RWテクスチャのマテリアルでの利用&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#サンプルコードの概要"&gt;サンプルコードの概要&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;ComputeShaderで計算した結果を、RWテクスチャを利用してダイレクトにマテリアルで利用する。↓はサンプルコードの実行の様子。&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;ﾜｻﾜｻﾜｻ&lt;br&gt;&lt;br&gt;記事用のサンプルはもうこれでいいか（妥協&lt;a href="https://twitter.com/hashtag/UE4Study?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#UE4Study&lt;/a&gt; &lt;a href="https://t.co/qCDI2oPJHr"&gt;pic.twitter.com/qCDI2oPJHr&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/1240520264221224960?ref_src=twsrc%5Etfw"&gt;2020年3月19日&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt; &lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="はじめに"&gt;はじめに&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2019/09/22/222604"&gt;&amp;#x524D;&amp;#x56DE;&amp;#x306E;&amp;#x8A18;&amp;#x4E8B;&lt;/a&gt;ではComputeShaderでメッシュ情報を直接生成する方法を紹介した。前回記事の手法では頂点カラー等を利用することでComputeShaderからマテリアルへ追加情報を渡すことができる。しかし頂点データの一部を間借りすることから渡せる情報に制限がある。&lt;br /&gt;&#10;当記事ではComputeShaderが書き込みをしたRWテクスチャをそのままマテリアルで利用することで頂点データ利用に比べてより自由に情報を受け渡す方法を検証してうまくいったので公開。そもそもこんな面倒なことしなくても可能な方法があるかもしれないので注意。&lt;br /&gt;&#10;(GlobalShader利用, エンジン改造無し)&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="サンプルコード"&gt;サンプルコード&lt;/h3&gt;&#10;&lt;p&gt;uprojectファイルを右クリック→Generate &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Visual%20Studio"&gt;Visual Studio&lt;/a&gt; project files でプロジェクトコード生成.&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnagakagachi%2Fue4%2Fblob%2Fmaster%2Fproject%2Fsample%2FUavTextureSample.zip" title="nagakagachi/ue4" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://github.com/nagakagachi/ue4/blob/master/project/sample/UavTextureSample.zip"&gt;github.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="説明"&gt;説明&lt;/h3&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="RWテクスチャ定義"&gt;RWテクスチャ定義&lt;/h4&gt;&#10;&lt;p&gt;マテリアルで利用可能且つComputeShaderで書き込みが可能なUAVリソースとしてのテクスチャが必要であるため、UTextureRenderTarget2Dを継承したRWテクスチャを定義する。&lt;br /&gt;&#10;bCanCreateUAVにtrueを指定することでリソース自体がUAV利用可能な設定で作成される。ただしこの設定だけではUAVが作成されないため(メンバ変数uav_)、RWテクスチャとして利用するComputeShader処理側で必要なときに生成する(後述)。&lt;br /&gt;&#10;また、UAVの破棄はRenderThreadで処理する必要があるのでデスト&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%AF"&gt;ラク&lt;/a&gt;タでRenderThreadのコマンドとして発行している。&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synComment"&gt;// UavTextureSampleComponent.h&lt;/span&gt;&#10;UCLASS(BlueprintType)&#10;&lt;span class="synType"&gt;class&lt;/span&gt; UNglRWTextureRenderTarget2D : &lt;span class="synStatement"&gt;public&lt;/span&gt; UTextureRenderTarget2D&#10;{&#10;&#9;GENERATED_UCLASS_BODY()&#10;&lt;p&gt;&lt;span class="synStatement"&gt;public&lt;/span&gt;:&#10;&lt;span class="synType"&gt;virtual&lt;/span&gt; ~UNglRWTextureRenderTarget2D();&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;FUnorderedAccessViewRHIRef uav_;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;};&#10;&lt;/pre&gt;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synComment"&gt;// UavTextureSampleComponent.cpp&lt;/span&gt;&#10;UNglRWTextureRenderTarget2D::UNglRWTextureRenderTarget2D(&lt;span class="synType"&gt;const&lt;/span&gt; FObjectInitializer&amp;amp; ObjectInitializer)&#10;: Super(ObjectInitializer)&#10;{&#10;bNeedsTwoCopies = &lt;span class="synConstant"&gt;false&lt;/span&gt;;&#10;&lt;span class="synComment"&gt;// リソース生成時にUAV利用可能な設定で作成することを指示&lt;/span&gt;&#10;bCanCreateUAV = &lt;span class="synConstant"&gt;true&lt;/span&gt;;&#10;}&lt;/p&gt;&#10;&lt;p&gt;UNglRWTextureRenderTarget2D::~UNglRWTextureRenderTarget2D()&#10;{&#10;&lt;span class="synStatement"&gt;if&lt;/span&gt; (uav_.IsValid())&#10;{&#10;&lt;span class="synComment"&gt;// UAVの破棄&lt;/span&gt;&#10;&lt;span class="synComment"&gt;// 破棄は描画スレッドで実行する必要があるのでコマンドをキューに積む.&lt;/span&gt;&#10;&lt;span class="synType"&gt;auto&lt;/span&gt; rhi_resource = uav_;&#10;ENQUEUE_RENDER_COMMAND(UpdateResourceImmediate)(&#10;[rhi_resource](FRHICommandListImmediate&amp;amp; RHICmdList)&#10;{&#10;rhi_resource-&amp;gt;Release();&#10;}&#10;);&#10;}&#10;}&#10;&lt;/pre&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="RWテクスチャのUAV生成"&gt;RWテクスチャのUAV生成&lt;/h4&gt;&#10;&lt;p&gt;本来ならUTextureRenderTarget2Dの初期化フローの中で生成するのが理想だが、今回はUAV利用する側が生成することにした。&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synComment"&gt;// UavTextureSampleComponent.cpp 252行目&lt;/span&gt;&#10;&lt;span class="synStatement"&gt;if&lt;/span&gt; (!rw_tex-&amp;gt;uav_.IsValid())&#10;{&#10;&#9;rw_tex-&amp;gt;uav_ = RHICreateUnorderedAccessView(rw_tex-&amp;gt;Resource-&amp;gt;TextureRHI);&#10;}&#10;&lt;/pre&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="ComputeShaderによるRWテクスチャへの書き込み"&gt;ComputeShaderによるRWテクスチャへの書き込み&lt;/h4&gt;&#10;&lt;p&gt;生成したUAVはComputeShaderパラメータに設定することで利用可能。&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synComment"&gt;// UavTextureSampleComponent.cpp 271行目&lt;/span&gt;&#10;SetUAVParameter(RHICmdList, rhi_cs, cs-&amp;gt;rw_tex, rw_tex-&amp;gt;uav_);&#10;&lt;/pre&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="RWテクスチャのマテリアルでの利用"&gt;RWテクスチャのマテリアルでの利用&lt;/h4&gt;&#10;&lt;p&gt;UNglRWTextureRenderTarget2Dは通常のUTextureオブジェクトと同様にマテリアルパラメータに設定可能。これでComputeShaderで書き込みをしたRWテクスチャをそのままマテリアルで利用できる。&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/5c8a60351bcfe3ae030428d71a6de4334197e4b9e769ba08a822cd496fd85d1e.png" alt="f:id:nagakagachi:20200319232634p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item></channel></rss>