<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ComputeShader on ながむしメモ</title><link>https://nagakagachi.github.io/categories/computeshader/</link><description>Recent content in ComputeShader 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/computeshader/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><item><title>UE4 ComputeShaderでMeshの頂点バッファをリアルタイム書き換えする (GPGPU)</title><link>https://nagakagachi.github.io/entry/2019/09/22/222604/</link><pubDate>Sun, 22 Sep 2019 22:26:04 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2019/09/22/222604/</guid><description>&lt;p&gt;エンジンバージョン:4.22, 4.23&lt;/p&gt;&#10;&lt;p&gt;諸事情によりサンプルプロジェクト無し&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;のProceduralMeshのようなことをComputeShaderでできたら、大量の頂点をリアルタイムに操作できて面白いのではないかという思い付き。&lt;br /&gt;&#10;今回はたくさんの草をリアルタイムに生成する目的で実装してある程度うまくいったのでメモ。&lt;br /&gt;&#10;この方法を応用すれば頂点カラーとかに&lt;b&gt;InstanceID的なものやそのほか特殊な情報を埋め込んでおいてマテリアルBPで利用&lt;/b&gt;するといったこともできる。&lt;/p&gt;&lt;p&gt;この記事は&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/C%2B%2B"&gt;C++&lt;/a&gt;とGlobalShaderを利用したもので、且つエンジン改造はしない。&lt;br /&gt;&#10;また、自前で用意した頂点バッファをComputeShaderで書き換えて&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;のメッシュ描画に流す方法がメインであるため、実装したComputeShader自体については深く説明しない。&lt;/p&gt;&lt;p&gt;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/vYK3n3544V4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://www.youtube.com/watch?v=vYK3n3544V4"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;↑プレイヤーからの影響を草一本一本が受ける例。&lt;br /&gt;&#10;草の位置や基準方向などを構造化バッファで保持しているのでそれらをComputeShaderで更新すればこのようなことも可能。&lt;br /&gt;&#10;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/KTw7eWUym6k?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://www.youtube.com/watch?v=KTw7eWUym6k"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;↑さらにマテリアルBP側で頂点オフセットによる風揺れをつけた例。&lt;br /&gt;&#10;描画自体は&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;のメッシュ描画に乗っかっているのでStaticMesh等と同じようにマテリアルが使えるのが強みの一つ。&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="基本の考え"&gt;基本の考え&lt;/h3&gt;&#10;&lt;p&gt;自分で作成した頂点バッファやインデックスバッファを&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;のメッシュ描画に流し込む方法は意外と簡単で、FPrimitiveSceneProxy派生クラスでGetDynamicMeshElements()関数をoverrideして適切にバッファ情報を渡せば可能になる。&lt;br /&gt;&#10;そこでこれらのバッファをUnorderedAccess可能な設定で作成しておき、毎フレームComputeShaderで書き換えるようにすることで、形状をリアルタイムに変更しつつマテリアル等を含めた描画部分は&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;の仕組みをそのまま利用できると考えた。&lt;figure class="figure-image figure-image-fotolife" title="フローのイメージ"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/a7e0ed1dbb7467ca02ad9f19db3cd9c2f5042317917e76eeb0a6fe5fa284007d.png" alt="f:id:nagakagachi:20190922201851p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;フローのイメージ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="必要な要素の概要"&gt;必要な要素の概要&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;自作ComputeShader用GlobalShader&#10;&lt;ul&gt;&#10;&lt;li&gt;自作MeshProxyが生成した頂点バッファUAVやインデックスバッファUAVへ読み書きして草メッシュを作る&lt;/li&gt;&#10;&lt;li&gt;草メッシュの位置や向きは別途StructuredBufferで与える&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;自作MeshComponentクラス&#10;&lt;ul&gt;&#10;&lt;li&gt;対になる自作MeshProxyを生成してシステムに登録し、ゲーム側からの情報を通知する役割&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;自作MeshProxyクラス&#10;&lt;ul&gt;&#10;&lt;li&gt;自作MeshComponentの描画スレッド側における分身のような存在&lt;/li&gt;&#10;&lt;li&gt;UnorderedAccess可能な各種頂点バッファとインデックスバッファおよびそれらのUAVを作成する&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;メッシュ描画システムのメッシュ情報収集に適切に頂点バッファなどを設定する&lt;/li&gt;&#10;&lt;li&gt;ComputeShaderのDispatchコマンド発行もする&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="自作computeshader用globalshader"&gt;自作ComputeShader用GlobalShader&lt;/h3&gt;&#10;&lt;p&gt;自作MeshProxyの各バッファのUAVを設定して書き換えるComputeShaderのGlobalShader。&lt;br /&gt;&#10;GlobalShader自体については公式のドキュメントを参考。&lt;br /&gt;&#10;&lt;a href="https://docs.unrealengine.com/ja/Programming/Rendering/ShaderInPlugin/QuickStart/index.html"&gt;https://docs.unrealengine.com/ja/Programming/Rendering/ShaderInPlugin/QuickStart/index.html&lt;/a&gt;&lt;br /&gt;&#10;ComputeShaderをGlobalShaderとして作成してUAV他パラメータを設定する流れについては以下のブログが参考になる。&lt;br /&gt;&#10;&lt;a href="http://www.sciement.com/tech-blog/c/structured_buffer_compute_shader_ue4_part2/"&gt;[UE4][ComputeShader][HLSL][C++]Unreal Engine 4&amp;#x3067;(RW)StructuredBuffer&amp;#x3092;&amp;#x7528;&amp;#x3044;&amp;#x305F;ComputeShader&amp;#x3092;&amp;#x5229;&amp;#x7528;&amp;#x3059;&amp;#x308B;&amp;#xFF08;&amp;#x305D;&amp;#x306E;&amp;#xFF12;&amp;#xFF1A;C++&amp;#x5074;&amp;#x30B7;&amp;#x30A7;&amp;#x30FC;&amp;#x30C0;&amp;#x30AF;&amp;#x30E9;&amp;#x30B9;&amp;#xFF09; &amp;ndash; &amp;#x30B5;&amp;#x30A4;&amp;#x30A2;&amp;#x30E1;&amp;#x30F3;&amp;#x30C8;&amp;#x6280;&amp;#x8853;&amp;#x30E1;&amp;#x30E2;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;今回はComputeShaderのスレッド一つが草一本を担当することとし、スレッドIDと草一つに割り当てられた頂点数からスレッドが書き込む頂点バッファ内の位置を決めている。あまり特殊なことはしていないが、接線法線頂点バッファ等がPackedフォーマットになっている場合はUAVから読み取った値をUnpackしたり書き戻す際に再度Packしたりといった処理が必要な点に注意。&lt;figure class="figure-image figure-image-fotolife" title="ComputeShaderの処理イメージ"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/fc508a3445d4aa4c0034f49351815345ab6d54a45970a5e6adf04e1739dbab1b.png" alt="f:id:nagakagachi:20190922220711p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;ComputeShaderの処理イメージ&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="自作meshcomponentクラス"&gt;自作MeshComponentクラス&lt;/h3&gt;&#10;&lt;p&gt;UPrimitiveComponentを継承&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8"&gt;コンポーネント&lt;/a&gt;としてゲームスレッド側の情報を管理する。UProceduralMeshComponentを参考にした。&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8"&gt;コンポーネント&lt;/a&gt;の描画スレッド側の情報を管理するカスタムMeshProxyクラスを生成して保持し、適切に情報を渡したりするのが主な役目。&lt;br /&gt;&#10;適切なタイミングで自作MeshProxyへComputeShaderのDispatchコマンド生成をリク&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9"&gt;エス&lt;/a&gt;トをする。&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synType"&gt;virtual&lt;/span&gt; &lt;span class="synType"&gt;void&lt;/span&gt; UComputeMeshComponent::TickComponent(&lt;span class="synType"&gt;float&lt;/span&gt; DeltaTime, &lt;span class="synType"&gt;enum&lt;/span&gt; ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) &lt;span class="synType"&gt;override&lt;/span&gt;&#10;{&#10; &lt;span class="synComment"&gt;// SendRenderDynamicData_Concurrent の呼び出しをリクエスト&lt;/span&gt;&#10; MarkRenderDynamicDataDirty();&#10;}&#10;&lt;span class="synType"&gt;virtual&lt;/span&gt; &lt;span class="synType"&gt;void&lt;/span&gt; UComputeMeshComponent::SendRenderDynamicData_Concurrent() &lt;span class="synType"&gt;override&lt;/span&gt;&#10;{&#10; &lt;span class="synComment"&gt;// カスタムMeshProxyにComputeShaderのDispatchコマンド生成を要求&lt;/span&gt;&#10; カスタムMeshProxy-&amp;gt;EnqueueDispatchComputeShader();&#10;}&#10;&lt;/pre&gt;&#10;&lt;/div&gt;</description></item></channel></rss>