<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ながむしメモ</title><link>https://nagakagachi.github.io/</link><description>Recent content on ながむしメモ</description><generator>Hugo</generator><language>ja-JP</language><lastBuildDate>Sun, 04 Oct 2026 00:00:00 +0900</lastBuildDate><atom:link href="https://nagakagachi.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>はてなブログからGitHub Pagesへの移行を試してみた</title><link>https://nagakagachi.github.io/entry/2026/10/04/hatena-to-github-pages/</link><pubDate>Sun, 04 Oct 2026 00:00:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/10/04/hatena-to-github-pages/</guid><description>&lt;p&gt;はてなブログからGitHub Pagesへの移行を試してみた。&lt;/p&gt;&#10;&lt;p&gt;いろいろと自分で管理したほうが、今後は良いのかなと思い（GitHubですが）、思い立ったが吉日ということでやってみた。&lt;/p&gt;&#10;&lt;p&gt;はてなブログのエクスポート機能で記事のバックアップを取得するところだけ手動で行い、その後のメディアの抽出やリンクの置換、Markdownへの整形、GitHub Actions向けの整備などはCodexに対応してもらった。&lt;/p&gt;&#10;&lt;p&gt;やったことは、おおむね以下の流れ。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;はてなブログから記事をエクスポートし、原本をローカルに保存&lt;/li&gt;&#10;&lt;li&gt;記事内の画像を取得して保存し、数式はTeXから再描画する形に変換&lt;/li&gt;&#10;&lt;li&gt;記事を個別のMarkdownファイルに分離し、画像への参照をローカルの保存先へ置換&lt;/li&gt;&#10;&lt;li&gt;元のはてなブログ記事へのリンクを残し、移行記事と分かる表示を追加&lt;/li&gt;&#10;&lt;li&gt;Hugoで記事一覧やカテゴリ、記事タイトルの検索ページを生成する構成に整備&lt;/li&gt;&#10;&lt;li&gt;GitHub Actionsでビルド・検証し、GitHub Pagesへ公開&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;既存の公開記事53件を移し、下書きやエクスポートのバックアップはローカルに残している。動画などの外部サービスの埋め込みは、引き続き外部参照になっている。&lt;/p&gt;&#10;&lt;p&gt;今後どうなるかは分からないが、ひとまずここで何か進めていこうと思う。&lt;/p&gt;</description></item><item><title>InstantRDV UEプラグイン形式のデモ実装</title><link>https://nagakagachi.github.io/entry/2026/09/25/195105/</link><pubDate>Fri, 25 Sep 2026 19:51:05 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/09/25/195105/</guid><description>&lt;p&gt;D3D12レンダラで実装していた仕組みをUE5.8 CodePlugin としてリポジトリを公開しました ↓.&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnagakagachi%2Finstant-rdv-ue" title="GitHub - nagakagachi/instant-rdv-ue: instant raster derived voxel ue plugin" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://github.com/nagakagachi/instant-rdv-ue"&gt;github.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;p&gt;Instant Raster Derived Voxel (InstantRDV)&lt;/p&gt;&#10;&lt;p&gt;ということにしました.&lt;/p&gt;&#10;&lt;p&gt;&lt;div style="display:flex; gap:8px;"&gt;&lt;br /&gt;&#10; &lt;img src="images/7d3c91f4526786a81fbd3e7676fbdfff32462250764c7a0f34b58fe14aa09771.png" width="300"&gt;&lt;br /&gt;&#10; &lt;img src="images/1bc8cc5ac70125827f7e8ced81fc853fe957d36d3bab5f532e4989aca5ab408d.png" width="300"&gt;&lt;br /&gt;&#10;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;既存のラスタライズ描画パイプラインが作り出す情報を流用してVoxelレイトレシーンを構築する仕組みです.&lt;/p&gt;&#10;&lt;p&gt;非侵襲的にVoxelを構築できるので色々と面白いことができる土台になると考えています.&lt;/p&gt;&#10;&lt;p&gt;利用例としてPluginにはVoxelレイトレースGI, RdvGiを実装しています.&lt;/p&gt;&#10;&lt;p&gt;サンプルレベルを開くとRdvGiによる間接光計算のシーンが動きます.&lt;/p&gt;&#10;&lt;p&gt;詳しくはリポジトリReadmeやコードをご覧ください.&lt;/p&gt;&#10;&lt;p&gt;RDVのVoxelシーン構造はGDCプレゼンテーション Global Illumination in &amp;lsquo;Once Human&amp;rsquo; で紹介されている仕組みに類似しています.&lt;/p&gt;&#10;&lt;p&gt;RdvGiはProbeBasedでIrradianceVolumeを更新する方式で, GPCプレゼンテーション Realtime Global Illumination in Enshrouded のFrustum Probeを参考にしています.&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/Mr9syMFeEFI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="InstantRdv GI Demo UE Plugin"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://www.youtube.com/watch?v=Mr9syMFeEFI"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;</description></item><item><title>Global Illumination WIP 3</title><link>https://nagakagachi.github.io/entry/2026/06/10/231345/</link><pubDate>Wed, 10 Jun 2026 23:13:45 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/06/10/231345/</guid><description>&lt;p&gt;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/uE6fQsqlzQA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Portable Global Illumination WIP 3"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://youtu.be/uE6fQsqlzQA"&gt;youtu.be&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;p&gt;ディレクショナルライトなどのライト以外のエミッシブサーフェイスも光源になります&lt;/p&gt;&#10;&lt;p&gt;というデモ&lt;/p&gt;&#10;&lt;p&gt;高速化や安定化, いくつかのProbeアプローチを試しています.&lt;/p&gt;&#10;&lt;p&gt;動画はScreenProbeタイプの実装.&lt;/p&gt;&#10;&lt;p&gt;詳細はtwitter X へどうぞ&lt;br /&gt;&#10;&lt;a href="https://x.com/nagakagachi"&gt;https://x.com/nagakagachi&lt;/a&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2026/06/10/231345"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Global Illumination WIP 2</title><link>https://nagakagachi.github.io/entry/2026/05/03/125743/</link><pubDate>Sun, 03 May 2026 12:57:43 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/05/03/125743/</guid><description>&lt;p&gt;Irradianceまで繋いだので進捗.&lt;br /&gt;&#10;しかしこの方式はディティールレベルは高いが負荷を下げにくいので別の手法も試し中.&lt;br /&gt;&#10;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/cOgYk3GuRzI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Portable Global Illumination WIP 2"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://www.youtube.com/watch?v=cOgYk3GuRzI"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;p&gt;高頻度進捗はTwitterX&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="en" dir="ltr"&gt;Dynamic Object&lt;br&gt;Dynamic Geometry&lt;br&gt;Dynamic Material&lt;br&gt;Dynamic Light&lt;br&gt;&lt;br&gt;Global Illumination&lt;br&gt;&lt;br&gt;(ﾟ∀ﾟ) &lt;a href="https://t.co/KGMkqZqUXM"&gt;pic.twitter.com/KGMkqZqUXM&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/2050597459228033430?ref_src=twsrc%5Etfw"&gt;2026年5月2日&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt; &lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;(WIP)&lt;br&gt;World Aligned Probe Dynamic Diffuse GI&lt;br&gt;&lt;br&gt;Enshrouded資料のアイデアを使ったFrustum Probe Placementな動的Probe&lt;br&gt;&lt;br&gt;Light Leak/(Dark Probe) が目立つがそれなりに動作 &lt;a href="https://t.co/PdEasyIXXW"&gt;pic.twitter.com/PdEasyIXXW&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/2050527453286908208?ref_src=twsrc%5Etfw"&gt;2026年5月2日&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;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2026/05/03/125743"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Light Propagation Volumes (LPV) の radiance directional derivative によるLight Leak対策</title><link>https://nagakagachi.github.io/entry/2026/04/25/130447/</link><pubDate>Sat, 25 Apr 2026 13:04:47 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/04/25/130447/</guid><description>&lt;p&gt;Light Propagation Volumes in CryEngine 3 [1] で Radiance Volumeからのサンプリング時Leakを抑える手法として&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;6.3 Anisotropic upsampling of radiance volume&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;で言及されている direction-dependent upsampling of the resulting radiance volume がよくわからなかったので調べた結果です.&lt;/p&gt;&#10;&lt;p&gt;コードとしてはGI-LPV[2]のリポジトリの indirect_light.fp [3]で実際に記述されていたのが参考になりました.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="https://advances.realtimerendering.com/s2009/Light_Propagation_Volumes.pdf"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/851bf9af7fdcec512c704897f77875e2dc97a947496617e6606284c06eea9adb.png" width="853" height="589" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;&lt;a href="https://advances.realtimerendering.com/s2009/Light_Propagation_Volumes.pdf"&gt;https://advances.realtimerendering.com/s2009/Light_Propagation_Volumes.pdf&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;SH VolumeのSH係数を補間する際に裏側から漏れ出ていそうな成分をキャンセルするためのもの.&lt;/p&gt;&#10;&lt;p&gt;SH Volume からシェーディング点のSH係数をサンプリングした後, シェーディング法線方向に沿ったSH係数の方向微分も計算します.&lt;/p&gt;&#10;&lt;p&gt;(実際に前後の点でサンプリングしています)&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="math-inline"&gt;\(\nabla_{\mathbf{n}} \mathbf{c}(\mathbf{x})&#10; =&#10; \frac{&#10; \mathbf{c}\!\left(\mathbf{x} + \frac{\mathbf{n}}{2}\right)&#10; -&#10; \mathbf{c}\!\left(\mathbf{x} - \frac{\mathbf{n}}{2}\right)&#10; }{&#10; \lVert \mathbf{n} \rVert&#10; }\)&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;SH係数の方向微分のベクトルとシェーディング点のSH係数の内積を類似度をみなして,&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;類似度が高い&lt;/li&gt;&#10;&lt;li&gt;裏側→表側へのSH変化量がそのままシェーディング点のSHに影響している&lt;/li&gt;&#10;&lt;li&gt;裏側のSHが漏れ出ている疑惑が強い&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;ということで, その場合はシェーディング点のSHによる寄与を減らす(dampening) しています.&lt;/p&gt;&#10;&lt;p&gt;この手法はあくまでleakしていそうだったら減衰させているだけで, より良いSHのサンプリングをするというものではなさそうです.&lt;/p&gt;&#10;&lt;p&gt;この前段階で法線バイアス等で十分Leakを避けるためのサンプリング点補正をしたうえでの, 最終調整という位置づけが良いのかもしれないです.&lt;/p&gt;&#10;&lt;p&gt;LPV&lt;/p&gt;&#10;&lt;p&gt;[1] &lt;a href="https://advances.realtimerendering.com/s2009/Light_Propagation_Volumes.pdf"&gt;https://advances.realtimerendering.com/s2009/Light_Propagation_Volumes.pdf&lt;/a&gt;&lt;br /&gt;&#10;[2] &lt;a href="https://github.com/innovation-cat/GI-LPV/tree/master"&gt;GitHub - innovation-cat/GI-LPV: Implement global illumination with OCaml, using light propagation volumes . &amp;middot; GitHub&lt;/a&gt;&lt;br /&gt;&#10;[3] &lt;a href="https://github.com/innovation-cat/GI-LPV/blob/master/shader/indirect_light.fp"&gt;GI-LPV/shader/indirect_light.fp at master &amp;middot; innovation-cat/GI-LPV &amp;middot; GitHub&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Global Illumination WIP 1</title><link>https://nagakagachi.github.io/entry/2026/03/29/175632/</link><pubDate>Sun, 29 Mar 2026 17:56:32 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/03/29/175632/</guid><description>&lt;p&gt;そこそこ出来てきたので動画をアップロードしてブログにも&lt;/p&gt;&#10;&lt;p&gt;思想と仕組みはそのうちまとめたい&lt;/p&gt;&#10;&lt;p&gt;ポータビリティ重視&lt;/p&gt;&#10;&lt;p&gt;既存のラスタライズレンダリングパイプラインへの組み込み容易性を重視&lt;/p&gt;&#10;&lt;p&gt;ハードウェアレイトレーシング不使用&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/hCMn8B59UoI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Portable Global Illumination WIP 1"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://www.youtube.com/watch?v=hCMn8B59UoI"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;DirectX12ネイティブアプリで実装中&lt;/p&gt;&#10;&lt;p&gt;GIといいつつ現状はSkyVisibilityのみ&lt;/p&gt;&#10;&lt;p&gt;UE5でも単なるプラグインとして動作動作させられるので検討したいところ&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2026/03/29/175632"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Concurrent Binary Trees for Large-Scale Game Components 検証実装</title><link>https://nagakagachi.github.io/entry/2026/03/08/140815/</link><pubDate>Sun, 08 Mar 2026 14:08:15 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/03/08/140815/</guid><description>&lt;p&gt;Adaptive Software Tessellation with Concurrent Binary Trees&lt;/p&gt;&#10;&lt;p&gt;数年前に実装したものですが検索性が良くないのでこちらにも&lt;/p&gt;&#10;&lt;p&gt;一般メッシュに適用可能なGPU駆動ソフトウェアテッセレーションの手法を試してみました。&lt;/p&gt;&#10;&lt;p&gt;論文の主要処理はすべてComputeShaderになります。&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/nagakagachi/sample_project?tab=readme-ov-file#adaptive-software-tessellation-with-concurrent-binary-trees"&gt;GitHub - nagakagachi/sample_project &amp;middot; GitHub&lt;/a&gt;&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/a0f4e7a0e07c797977daca11a7bc4822bee579de46c1e9dd0c5bc71f97313358.png" width="1200" height="694" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;今回の手法の論文はこちら&lt;br /&gt;&#10;Concurrent Binary Trees for Large-Scale Game Components&lt;br /&gt;&#10;ANIS BENYOUB, Intel Corporation, France&lt;br /&gt;&#10;JONATHAN DUPUY, Intel Corporation, France&lt;br /&gt;&#10;&lt;a href="https://dl.acm.org/doi/10.1145/3675371"&gt;https://dl.acm.org/doi/10.1145/3675371&lt;/a&gt;&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/0143d7b89bb43375426dc4552154dc2ee16eb920499b50c9f114ee272a77fe06.png" width="903" height="663" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/f315f6ee4911441a80b3924a0cf2c352323039e3781b79f89d68a82e1fc5c1a4.png" width="723" height="315" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;著者の以前のTessellation論文にもConcurrentBinaryTree(CBT)を使ったものがありますが、&lt;br /&gt;&#10;そちらは二等辺直角三角形に限定して、分割三角形の親子構造をCBTにマッピングする手法です。&lt;br /&gt;&#10;Concurrent Binary Trees (with application to longest edge bisection)&lt;br /&gt;&#10;JONATHAN DUPUY, Unity Technologies&lt;br /&gt;&#10;&lt;a href="https://dl.acm.org/doi/10.1145/3406186"&gt;https://dl.acm.org/doi/10.1145/3406186&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;一方で今回の論文は任意のメッシュに対して実行可能で、CBTを分割三角形の高速なメモリアロケーションのために利用しています。&lt;/p&gt;&#10;&lt;p&gt;CBT(並行二分木)を利用する仕組み上、メモリ確保が二の冪乗に制限されるなど少し取り回しが悪い点などがありますが、&lt;/p&gt;&#10;&lt;p&gt;一般メッシュに適用できてリアルタイムに動かせそうなソフトウェアテッセレーション手法としてよい感じかと思います。&lt;/p&gt;&#10;&lt;p&gt;コードはディレクトリにまとまっています。&lt;/p&gt;&#10;&lt;p&gt;実行はmain.cppの NGL_TEST_SWTESSELLATION_ENABLE を 1 にしてビルドするとシーンにテスト用のオブジェクトが表示されます。&lt;/p&gt;</description></item><item><title>UEマテリアルネタ:LatticeBasedDynamicDeform</title><link>https://nagakagachi.github.io/entry/2026/02/04/002246/</link><pubDate>Wed, 04 Feb 2026 00:22:46 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/02/04/002246/</guid><description>&lt;p&gt;コンセプト実装メモ&lt;/p&gt;&#10;&lt;p&gt;material&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_0&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_0&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionAbs Name=&amp;#34;MaterialExpressionAbs_3&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionAbs&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_0.MaterialExpressionAbs_3&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionAbs_3&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionAbs&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_0.MaterialExpressionAbs_3&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;MaterialGraphNode_42.MaterialExpressionAdd_3&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=1136&#10; MaterialExpressionEditorY=-544&#10; MaterialExpressionGuid=618A1FEA4EC7BE62FCDD5E8775143A99&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionAbs&amp;#39;MaterialExpressionAbs_3&amp;#39;&amp;#34;&#10; NodePosX=1136&#10; NodePosY=-544&#10; NodeGuid=CE61B2744816A6DBBE259A8A85CF33D1&#10; CustomProperties Pin (PinId=156D96F34497F69979397E8818DDAA80,PinName=&amp;#34;Input&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_42 638E8D69403BED61E274A8B4B591B5B2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=A188A0A94A3ABCE76D74CBACF77286CB,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Root_0 891CD1634EE6E02E4C957587C39198A8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Knot Name=&amp;#34;MaterialGraphNode_Knot_0&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Knot&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_0&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionReroute Name=&amp;#34;MaterialExpressionReroute_12&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_0.MaterialExpressionReroute_12&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionReroute_12&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_0.MaterialExpressionReroute_12&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialGraphNode_2.MaterialExpressionMultiply_2&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=976&#10; MaterialExpressionEditorY=-208&#10; MaterialExpressionGuid=D01463B44F12A864E234EC9154BA4F4D&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialExpressionReroute_12&amp;#39;&amp;#34;&#10; NodePosX=976&#10; NodePosY=-208&#10; bCanRenameNode=False&#10; NodeGuid=07FAF5574724F26F6167ECB9CB797F61&#10; CustomProperties Pin (PinId=97EDD58C47AE5B073D3CDB8814F46B2F,PinName=&amp;#34;InputPin&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_2 608B93C641BAB0594CDAE980C0CE0A02,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=21AEB43349A80F4819E79EB40151FE29,PinName=&amp;#34;OutputPin&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Root_0 DD29B3E54B43BBF923E58ABB0F6F9D66,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_1&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_1&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionConstant3Vector Name=&amp;#34;MaterialExpressionConstant3Vector_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionConstant3Vector&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_1.MaterialExpressionConstant3Vector_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionConstant3Vector_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionConstant3Vector&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_1.MaterialExpressionConstant3Vector_0&amp;#39;&amp;#34;&#10; Constant=(R=0.459925,G=1.000000,B=0.787798,A=1.000000)&#10; MaterialExpressionEditorX=672&#10; MaterialExpressionEditorY=-640&#10; MaterialExpressionGuid=7758F61D4157B553ADEB50832122AC48&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionConstant3Vector&amp;#39;MaterialExpressionConstant3Vector_0&amp;#39;&amp;#34;&#10; NodePosX=672&#10; NodePosY=-640&#10; NodeGuid=390B70A44C94166617D31AAE48BE9615&#10; CustomProperties Pin (PinId=7204CBA74608D483362C0C9202E27153,PinName=&amp;#34;Constant&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;rgb&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0.459925,1.0,0.787798&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=597429E44A337F8EFF998AA7539751D0,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_42 70AB43564198A863B0FCD4B9F291912C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=71766138468B78919B60418D85F3C377,PinName=&amp;#34;Output2&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=6B7C31E142A541962D99C09701901DC5,PinName=&amp;#34;Output3&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;green&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=01F385CB49E1FF5FE7BC1087DD75BD33,PinName=&amp;#34;Output4&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;blue&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_2&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_2&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionMultiply Name=&amp;#34;MaterialExpressionMultiply_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_2.MaterialExpressionMultiply_2&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionMultiply_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_2.MaterialExpressionMultiply_2&amp;#39;&amp;#34;&#10; A=(Expression=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;MaterialGraphNode_Custom_0.MaterialExpressionCustom_2&amp;#39;&amp;#34;)&#10; B=(Expression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialGraphNode_12.MaterialExpressionMultiply_5&amp;#39;&amp;#34;)&#10; ConstB=10.000000&#10; MaterialExpressionEditorX=592&#10; MaterialExpressionEditorY=112&#10; MaterialExpressionGuid=801405D641B41ABE8B4088BC7144E91F&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialExpressionMultiply_2&amp;#39;&amp;#34;&#10; NodePosX=592&#10; NodePosY=112&#10; NodeGuid=767DE87C464CBBEF8CD726B7B8620BEA&#10; CustomProperties Pin (PinId=271BA5D84DF16892008A6D9BB82E3788,PinName=&amp;#34;A&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0.0&amp;#34;,LinkedTo=(MaterialGraphNode_Custom_0 AF4C1E69462CCBD59FD6CDAFD9A95BED,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=F66B95B44E6BA4EB1ECDB4877EB38891,PinName=&amp;#34;B&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;10.0&amp;#34;,LinkedTo=(MaterialGraphNode_12 79FF34B04F50FBE02A39B7A5E1418FD6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=608B93C641BAB0594CDAE980C0CE0A02,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_0 97EDD58C47AE5B073D3CDB8814F46B2F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Custom Name=&amp;#34;MaterialGraphNode_Custom_0&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Custom&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Custom_0&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionCustom Name=&amp;#34;MaterialExpressionCustom_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Custom_0.MaterialExpressionCustom_2&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionCustom_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Custom_0.MaterialExpressionCustom_2&amp;#39;&amp;#34;&#10; Code=&amp;#34;const int3 lattice_vtx_count = in_lattice_reso - 1;\r\n\r\nconst bool is_valid_lattice_id = all(0 &amp;lt;= in_lattice_id) &amp;amp;&amp;amp; all(in_lattice_id &amp;lt;= (lattice_vtx_count-1));\r\nconst float3 lattice_cell_size = in_lattice_size / lattice_vtx_count;\r\n\r\n\r\nfloat3 pos_deform = float3(0.0, 0.0, 0.0);\r\n\r\nfloat debug_weight = 0.0;\r\nfloat debug_vtx = 0.0;\r\n\r\nif(is_valid_lattice_id)\r\n{\r\n const float3 vtx_w0 = 1.0 - in_lattice_uvw;\r\n const float3 vtx_w1 = in_lattice_uvw;\r\n\r\n const int ay = in_lattice_reso.x;\r\n const int az = in_lattice_reso.x*in_lattice_reso.y;\r\n const int vtx_i0 = (in_lattice_id.x) + (in_lattice_id.y)*ay + (in_lattice_id.z)*az;\r\n const int vtx_i1 = (in_lattice_id.x+1) + (in_lattice_id.y)*ay + (in_lattice_id.z)*az;\r\n const int vtx_i2 = (in_lattice_id.x) + (in_lattice_id.y+1)*ay + (in_lattice_id.z)*az;\r\n const int vtx_i3 = (in_lattice_id.x+1) + (in_lattice_id.y+1)*ay + (in_lattice_id.z)*az;\r\n const int vtx_i4 = (in_lattice_id.x) + (in_lattice_id.y)*ay + (in_lattice_id.z+1)*az;\r\n const int vtx_i5 = (in_lattice_id.x+1) + (in_lattice_id.y)*ay + (in_lattice_id.z+1)*az;\r\n const int vtx_i6 = (in_lattice_id.x) + (in_lattice_id.y+1)*ay + (in_lattice_id.z+1)*az;\r\n const int vtx_i7 = (in_lattice_id.x+1) + (in_lattice_id.y+1)*ay + (in_lattice_id.z+1)*az;\r\n\r\n\r\n float4 vtx_accum = (float4)0.0;\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i0, 0, 0)) * (vtx_w0.x)*(vtx_w0.y)*(vtx_w0.z);\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i1, 0, 0)) * (vtx_w1.x)*(vtx_w0.y)*(vtx_w0.z);\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i2, 0, 0)) * (vtx_w0.x)*(vtx_w1.y)*(vtx_w0.z);\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i3, 0, 0)) * (vtx_w1.x)*(vtx_w1.y)*(vtx_w0.z);\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i4, 0, 0)) * (vtx_w0.x)*(vtx_w0.y)*(vtx_w1.z);\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i5, 0, 0)) * (vtx_w1.x)*(vtx_w0.y)*(vtx_w1.z);\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i6, 0, 0)) * (vtx_w0.x)*(vtx_w1.y)*(vtx_w1.z);\r\n vtx_accum += in_lattice_vtx_tex.Load(int3(vtx_i7, 0, 0)) * (vtx_w1.x)*(vtx_w1.y)*(vtx_w1.z);\r\n\r\n pos_deform = vtx_accum;\r\n}\r\n\r\nreturn pos_deform;\r\n\r\n&amp;#34;&#10; Inputs(0)=(InputName=&amp;#34;in_lattice_id&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;MaterialGraphNode_7.MaterialExpressionNamedRerouteDeclaration_0&amp;#39;&amp;#34;))&#10; Inputs(1)=(InputName=&amp;#34;in_lattice_uvw&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;MaterialGraphNode_4.MaterialExpressionNamedRerouteDeclaration_1&amp;#39;&amp;#34;))&#10; Inputs(2)=(InputName=&amp;#34;in_lattice_reso&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_1.MaterialExpressionReroute_1&amp;#39;&amp;#34;))&#10; Inputs(3)=(InputName=&amp;#34;in_lattice_size&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_2.MaterialExpressionReroute_2&amp;#39;&amp;#34;))&#10; Inputs(4)=(InputName=&amp;#34;in_lattice_vtx_tex&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionTextureObjectParameter&amp;#39;MaterialGraphNode_10.MaterialExpressionTextureObjectParameter_0&amp;#39;&amp;#34;))&#10; Inputs(5)=(InputName=&amp;#34;in_lattice_vtx_texel_size&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionTextureProperty&amp;#39;MaterialGraphNode_11.MaterialExpressionTextureProperty_0&amp;#39;&amp;#34;))&#10; AdditionalOutputs(0)=(OutputName=&amp;#34;out_debug_color&amp;#34;,OutputType=CMOT_Float3)&#10; ShowCode=True&#10; MaterialExpressionEditorX=-576&#10; MaterialExpressionEditorY=64&#10; MaterialExpressionGuid=EE1A98B74B3D84AC63EF4298EF5F9311&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; bShowOutputNameOnPin=True&#10; Outputs(0)=(OutputName=&amp;#34;return&amp;#34;)&#10; Outputs(1)=(OutputName=&amp;#34;out_debug_color&amp;#34;)&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;MaterialExpressionCustom_2&amp;#39;&amp;#34;&#10; NodePosX=-576&#10; NodePosY=64&#10; NodeGuid=D24EF2AB4923D520C4DB1D80201C0B53&#10; CustomProperties Pin (PinId=537C0DF74200871F85B7019702200A22,PinName=&amp;#34;in_lattice_id&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_7 A71B44654C44AB83FC9662A98E4C1D14,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=C82084184A1AFFBEACF88CAE3B47CAE8,PinName=&amp;#34;in_lattice_uvw&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_4 6D1FC9BF4DD7BF70843CF99CD39EEEE4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=06CA3F11492B4F9865F5A2BD2F6D6A10,PinName=&amp;#34;in_lattice_reso&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_1 ED297F8A4F01AB7FC8C022A40D66DEB5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=32785A6D43F60D54C376528074DA2F95,PinName=&amp;#34;in_lattice_size&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_2 EFD322694656CB36E3202EB49CB50989,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=F7F6DD344CEA67647D0E038419330B18,PinName=&amp;#34;in_lattice_vtx_tex&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_10 C7637FF44BC21CC478CB42828F2D078C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=56BCED2346461B390B07768867598603,PinName=&amp;#34;in_lattice_vtx_texel_size&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_11 D5CBAE54419805CAFE9F90BB4AAC62C6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=AF4C1E69462CCBD59FD6CDAFD9A95BED,PinName=&amp;#34;return&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_2 271BA5D84DF16892008A6D9BB82E3788,MaterialGraphNode_22 164AC73F4B86EEDB7E5ECE93AF2678D5,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=E9356CC64FAAA2B61070E49E7C2AEBF7,PinName=&amp;#34;out_debug_color&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_4&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_4&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionNamedRerouteDeclaration Name=&amp;#34;MaterialExpressionNamedRerouteDeclaration_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_4.MaterialExpressionNamedRerouteDeclaration_1&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionNamedRerouteDeclaration_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_4.MaterialExpressionNamedRerouteDeclaration_1&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;MaterialGraphNode_Custom_1.MaterialExpressionCustom_3&amp;#39;&amp;#34;,OutputIndex=2)&#10; Name=&amp;#34;LatticeUvw&amp;#34;&#10; NodeColor=(R=0.000000,G=0.882812,B=1.000000,A=1.000000)&#10; VariableGuid=6EBCE4B44E5D1815DB91AEBC9EACA936&#10; MaterialExpressionEditorX=-800&#10; MaterialExpressionEditorY=-432&#10; MaterialExpressionGuid=90CE568544767AB3B6162E81BFAC9497&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;MaterialExpressionNamedRerouteDeclaration_1&amp;#39;&amp;#34;&#10; NodePosX=-800&#10; NodePosY=-432&#10; bCanRenameNode=True&#10; NodeGuid=9B5B82D14363F84DC8267385212DC71F&#10; CustomProperties Pin (PinId=819FE751436F07FD79BEAB878B731865,PinName=&amp;#34;Input&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_1 B3319E1C4F16177D15683DA542AF5B44,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=6D1FC9BF4DD7BF70843CF99CD39EEEE4,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_0 C82084184A1AFFBEACF88CAE3B47CAE8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_5&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_5&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionVectorParameter Name=&amp;#34;MaterialExpressionVectorParameter_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionVectorParameter&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_5.MaterialExpressionVectorParameter_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionVectorParameter_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionVectorParameter&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_5.MaterialExpressionVectorParameter_0&amp;#39;&amp;#34;&#10; DefaultValue=(R=3.000000,G=3.000000,B=3.000000,A=0.000000)&#10; ParameterName=&amp;#34;InLatticeReso&amp;#34;&#10; ExpressionGUID=42684DE94E26A463B24ABA9F80E9A5C1&#10; MaterialExpressionEditorX=-2080&#10; MaterialExpressionEditorY=320&#10; MaterialExpressionGuid=268C06F448E8A9C8220CE8BFFC051F39&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionVectorParameter&amp;#39;MaterialExpressionVectorParameter_0&amp;#39;&amp;#34;&#10; NodePosX=-2080&#10; NodePosY=320&#10; bCanRenameNode=True&#10; NodeGuid=D1FA64064D1BB2747410048EF5120504&#10; CustomProperties Pin (PinId=AFF5CBDA4920A531CD2475B5B4CEEE9A,PinName=&amp;#34;Default Value&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;rgba&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;(R=3.000000,G=3.000000,B=3.000000,A=0.000000)&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=A5D1BA0E4D8E2550F34C8D813BE4FFEE,PinName=&amp;#34;RGB&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_1 EA0A48734D9BAD73736AA4B8638586AA,MaterialGraphNode_Custom_1 AE55E6F54091D60C2BB941B9F249EC86,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=669F18BA471B5950E44A4789CBD44613,PinName=&amp;#34;R&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=C56BFBD646DA50A72447C38B9F3EB1B2,PinName=&amp;#34;G&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;green&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=C25D92CD48B558820375DC8AD010FE73,PinName=&amp;#34;B&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;blue&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=CA9EFF21423EC8B508DFD3A931DA97A7,PinName=&amp;#34;A&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;alpha&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=9D5E092A47F6DF70673E019361A4B5A1,PinName=&amp;#34;RGBA&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;rgba&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_6&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_6&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionLocalPosition Name=&amp;#34;MaterialExpressionLocalPosition_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionLocalPosition&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_6.MaterialExpressionLocalPosition_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionLocalPosition_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionLocalPosition&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_6.MaterialExpressionLocalPosition_0&amp;#39;&amp;#34;&#10; IncludedOffsets=ExcludeOffsets&#10; MaterialExpressionEditorX=-2320&#10; MaterialExpressionEditorY=-752&#10; MaterialExpressionGuid=B5C2A8374BAA21ED3B77C6BC94596AEB&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionLocalPosition&amp;#39;MaterialExpressionLocalPosition_0&amp;#39;&amp;#34;&#10; NodePosX=-2320&#10; NodePosY=-752&#10; NodeGuid=7DD97F2D4062339703D63986B8441DEF&#10; CustomProperties Pin (PinId=C251D6E745A6863BA1DD9E88F4A6D054,PinName=&amp;#34;XYZ&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_8 865F735D451CD34C1B413192D301F967,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=B13A933F432DED087219E7A52D4A9110,PinName=&amp;#34;XY&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=D77E7AD54927D7B0F36E2C84801DC85E,PinName=&amp;#34;Z&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;blue&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_7&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_7&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionNamedRerouteDeclaration Name=&amp;#34;MaterialExpressionNamedRerouteDeclaration_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_7.MaterialExpressionNamedRerouteDeclaration_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionNamedRerouteDeclaration_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_7.MaterialExpressionNamedRerouteDeclaration_0&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;MaterialGraphNode_Custom_1.MaterialExpressionCustom_3&amp;#39;&amp;#34;,OutputIndex=1)&#10; Name=&amp;#34;LatticeId&amp;#34;&#10; NodeColor=(R=1.000000,G=0.000000,B=0.562500,A=1.000000)&#10; VariableGuid=D0D8F8B74A3BE48A8A101CBDE3248C49&#10; MaterialExpressionEditorX=-784&#10; MaterialExpressionEditorY=-512&#10; MaterialExpressionGuid=BFA4B8FE4A40BEDB515F8EB356CFBE21&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;MaterialExpressionNamedRerouteDeclaration_0&amp;#39;&amp;#34;&#10; NodePosX=-784&#10; NodePosY=-512&#10; bCanRenameNode=True&#10; NodeGuid=94BE1DD2437ABF0FE50C56861156A85E&#10; CustomProperties Pin (PinId=F74EF4844C75892D4D0451A90D3F522A,PinName=&amp;#34;Input&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_1 C9BF4A1D435878D81B60ABA7AEB0AFC3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=A71B44654C44AB83FC9662A98E4C1D14,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_0 537C0DF74200871F85B7019702200A22,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Knot Name=&amp;#34;MaterialGraphNode_Knot_1&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Knot&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_1&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionReroute Name=&amp;#34;MaterialExpressionReroute_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_1.MaterialExpressionReroute_1&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionReroute_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_1.MaterialExpressionReroute_1&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionVectorParameter&amp;#39;MaterialGraphNode_5.MaterialExpressionVectorParameter_0&amp;#39;&amp;#34;,Mask=1,MaskR=1,MaskG=1,MaskB=1)&#10; MaterialExpressionEditorX=-992&#10; MaterialExpressionEditorY=80&#10; MaterialExpressionGuid=62492AD243D0282174B4119BB2AD75D0&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialExpressionReroute_1&amp;#39;&amp;#34;&#10; NodePosX=-992&#10; NodePosY=80&#10; bCanRenameNode=False&#10; NodeGuid=5E1C6CFD45534F192B5A88A4CBF43948&#10; CustomProperties Pin (PinId=EA0A48734D9BAD73736AA4B8638586AA,PinName=&amp;#34;InputPin&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_5 A5D1BA0E4D8E2550F34C8D813BE4FFEE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=ED297F8A4F01AB7FC8C022A40D66DEB5,PinName=&amp;#34;OutputPin&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_0 06CA3F11492B4F9865F5A2BD2F6D6A10,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Knot Name=&amp;#34;MaterialGraphNode_Knot_2&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Knot&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_2&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionReroute Name=&amp;#34;MaterialExpressionReroute_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_2.MaterialExpressionReroute_2&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionReroute_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_2.MaterialExpressionReroute_2&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_6.MaterialExpressionReroute_8&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=-1600&#10; MaterialExpressionEditorY=32&#10; MaterialExpressionGuid=725E771D4589BAAFAF4FC89377F12C8A&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialExpressionReroute_2&amp;#39;&amp;#34;&#10; NodePosX=-1600&#10; NodePosY=32&#10; bCanRenameNode=False&#10; NodeGuid=EA21EA154B18A3A20F2AB48A6F8D6E96&#10; CustomProperties Pin (PinId=01C914364BC877462FDEA2B8D3472B4D,PinName=&amp;#34;InputPin&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_6 7D21ACD04B5BA1EA4EEB2395D46B47B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=EFD322694656CB36E3202EB49CB50989,PinName=&amp;#34;OutputPin&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_0 32785A6D43F60D54C376528074DA2F95,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Knot Name=&amp;#34;MaterialGraphNode_Knot_3&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Knot&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_3&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionReroute Name=&amp;#34;MaterialExpressionReroute_4&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_3.MaterialExpressionReroute_4&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionReroute_4&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_3.MaterialExpressionReroute_4&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;MaterialGraphNode_8.MaterialExpressionAdd_2&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=-1728&#10; MaterialExpressionEditorY=-688&#10; MaterialExpressionGuid=CECDE35C44567A90E7740EBBE9ADE0C9&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialExpressionReroute_4&amp;#39;&amp;#34;&#10; NodePosX=-1728&#10; NodePosY=-688&#10; bCanRenameNode=False&#10; NodeGuid=8139022A47A894DF6AB4A1ADBE7B08B0&#10; CustomProperties Pin (PinId=250241064EEA6A54807975B23A2271DC,PinName=&amp;#34;InputPin&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_8 979D16514042ED9A73356A9032066F70,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=CFEC7B144530E3C765A061BE6625BF30,PinName=&amp;#34;OutputPin&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_1 00880E43402379D7A7708B90CB6AFDED,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_8&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_8&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionAdd Name=&amp;#34;MaterialExpressionAdd_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_8.MaterialExpressionAdd_2&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionAdd_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_8.MaterialExpressionAdd_2&amp;#39;&amp;#34;&#10; A=(Expression=&amp;#34;/Script/Engine.MaterialExpressionLocalPosition&amp;#39;MaterialGraphNode_6.MaterialExpressionLocalPosition_0&amp;#39;&amp;#34;,Mask=1,MaskR=1,MaskG=1,MaskB=1)&#10; B=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_5.MaterialExpressionReroute_7&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=-1952&#10; MaterialExpressionEditorY=-736&#10; MaterialExpressionGuid=D1E9631F4F4977E08A1D24962FCB9E6E&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;MaterialExpressionAdd_2&amp;#39;&amp;#34;&#10; NodePosX=-1952&#10; NodePosY=-736&#10; NodeGuid=27D7A4314769680274FE9594C43EDEEA&#10; CustomProperties Pin (PinId=865F735D451CD34C1B413192D301F967,PinName=&amp;#34;A&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0.0&amp;#34;,LinkedTo=(MaterialGraphNode_6 C251D6E745A6863BA1DD9E88F4A6D054,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=407E79E346BF01D91835DD92651128C6,PinName=&amp;#34;B&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;1.0&amp;#34;,LinkedTo=(MaterialGraphNode_Knot_5 76630B6449047067CB85C7BA29A4C738,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=979D16514042ED9A73356A9032066F70,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_3 250241064EEA6A54807975B23A2271DC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Custom Name=&amp;#34;MaterialGraphNode_Custom_1&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Custom&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Custom_1&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionCustom Name=&amp;#34;MaterialExpressionCustom_3&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Custom_1.MaterialExpressionCustom_3&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionCustom_3&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Custom_1.MaterialExpressionCustom_3&amp;#39;&amp;#34;&#10; Code=&amp;#34;const int3 lattice_vtx_count = in_lattice_reso - 1;\r\nconst float3 lattice_cell_size = in_lattice_size / lattice_vtx_count;\r\n\r\nconst float3 lattice_cell_pos = in_local_position / lattice_cell_size;\r\n\r\nconst float3 lattice_cell_id = floor(lattice_cell_pos);\r\nout_lattice_cell_id = clamp(lattice_cell_id, 0, lattice_vtx_count-1);\r\n\r\nout_lattice_cell_uvw = saturate(lattice_cell_pos - out_lattice_cell_id);\r\n\r\nout_is_valid_lattice_cell \r\n= all(0 &amp;lt;= lattice_cell_id) &amp;amp;&amp;amp; all((lattice_vtx_count-1) &amp;gt;= lattice_cell_id);\r\n\r\nreturn 1;&amp;#34;&#10; Inputs(0)=(InputName=&amp;#34;in_local_position&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_3.MaterialExpressionReroute_4&amp;#39;&amp;#34;))&#10; Inputs(1)=(InputName=&amp;#34;in_lattice_reso&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionVectorParameter&amp;#39;MaterialGraphNode_5.MaterialExpressionVectorParameter_0&amp;#39;&amp;#34;,Mask=1,MaskR=1,MaskG=1,MaskB=1))&#10; Inputs(2)=(InputName=&amp;#34;in_lattice_size&amp;#34;,Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_6.MaterialExpressionReroute_8&amp;#39;&amp;#34;))&#10; AdditionalOutputs(0)=(OutputName=&amp;#34;out_lattice_cell_id&amp;#34;,OutputType=CMOT_Float3)&#10; AdditionalOutputs(1)=(OutputName=&amp;#34;out_lattice_cell_uvw&amp;#34;,OutputType=CMOT_Float3)&#10; AdditionalOutputs(2)=(OutputName=&amp;#34;out_is_valid_lattice_cell&amp;#34;)&#10; ShowCode=True&#10; MaterialExpressionEditorX=-1600&#10; MaterialExpressionEditorY=-496&#10; MaterialExpressionGuid=2C07B692463739E4F338098F5BBF9D07&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; bShowOutputNameOnPin=True&#10; Outputs(0)=(OutputName=&amp;#34;return&amp;#34;)&#10; Outputs(1)=(OutputName=&amp;#34;out_lattice_cell_id&amp;#34;)&#10; Outputs(2)=(OutputName=&amp;#34;out_lattice_cell_uvw&amp;#34;)&#10; Outputs(3)=(OutputName=&amp;#34;out_is_valid_lattice_cell&amp;#34;)&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;MaterialExpressionCustom_3&amp;#39;&amp;#34;&#10; NodePosX=-1600&#10; NodePosY=-496&#10; NodeGuid=B0F607A64466FD0ACBE208895195CEE8&#10; CustomProperties Pin (PinId=00880E43402379D7A7708B90CB6AFDED,PinName=&amp;#34;in_local_position&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_3 CFEC7B144530E3C765A061BE6625BF30,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=AE55E6F54091D60C2BB941B9F249EC86,PinName=&amp;#34;in_lattice_reso&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_5 A5D1BA0E4D8E2550F34C8D813BE4FFEE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=E529628745D778728B006BB8D8B4FAC8,PinName=&amp;#34;in_lattice_size&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_6 7D21ACD04B5BA1EA4EEB2395D46B47B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=82E750F44A4E4E8F42340EB09B25384E,PinName=&amp;#34;return&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=C9BF4A1D435878D81B60ABA7AEB0AFC3,PinName=&amp;#34;out_lattice_cell_id&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_7 F74EF4844C75892D4D0451A90D3F522A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=B3319E1C4F16177D15683DA542AF5B44,PinName=&amp;#34;out_lattice_cell_uvw&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_4 819FE751436F07FD79BEAB878B731865,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=0933F9CC4288B34990B4FD856868550E,PinName=&amp;#34;out_is_valid_lattice_cell&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_9 F97FA4AB4FE68FDE0C76B79068A959E2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_9&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_9&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionNamedRerouteDeclaration Name=&amp;#34;MaterialExpressionNamedRerouteDeclaration_4&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_9.MaterialExpressionNamedRerouteDeclaration_4&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionNamedRerouteDeclaration_4&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_9.MaterialExpressionNamedRerouteDeclaration_4&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;MaterialGraphNode_Custom_1.MaterialExpressionCustom_3&amp;#39;&amp;#34;,OutputIndex=3)&#10; Name=&amp;#34;LatticeCellValidity&amp;#34;&#10; NodeColor=(R=1.000000,G=0.000000,B=0.281250,A=1.000000)&#10; VariableGuid=4160AC3145B0E314BEDF13867F54FAF0&#10; MaterialExpressionEditorX=-800&#10; MaterialExpressionEditorY=-352&#10; MaterialExpressionGuid=DB42E62846B06A341CE3049D71734A0A&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionNamedRerouteDeclaration&amp;#39;MaterialExpressionNamedRerouteDeclaration_4&amp;#39;&amp;#34;&#10; NodePosX=-800&#10; NodePosY=-352&#10; bCanRenameNode=True&#10; NodeGuid=0297E90645D5E53F58892986DEEF2170&#10; CustomProperties Pin (PinId=F97FA4AB4FE68FDE0C76B79068A959E2,PinName=&amp;#34;Input&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_1 0933F9CC4288B34990B4FD856868550E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=72C30F454FDD0820FCA300BDE36AD634,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_10&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_10&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionTextureObjectParameter Name=&amp;#34;MaterialExpressionTextureObjectParameter_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionTextureObjectParameter&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_10.MaterialExpressionTextureObjectParameter_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionTextureObjectParameter_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionTextureObjectParameter&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_10.MaterialExpressionTextureObjectParameter_0&amp;#39;&amp;#34;&#10; ParameterName=&amp;#34;InLatticeVtxDeformTex&amp;#34;&#10; ExpressionGUID=19AFC82A4D800F52ADC9129F627256F7&#10; Texture=&amp;#34;/Script/Engine.Texture2D&amp;#39;/BaseMaterial/Textures/Default/T_BlackLinearColor.T_BlackLinearColor&amp;#39;&amp;#34;&#10; SamplerType=SAMPLERTYPE_LinearColor&#10; MaterialExpressionEditorX=-2080&#10; MaterialExpressionEditorY=576&#10; MaterialExpressionGuid=E7E47E3649051757A462C39D17D9868A&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionTextureObjectParameter&amp;#39;MaterialExpressionTextureObjectParameter_0&amp;#39;&amp;#34;&#10; NodePosX=-2080&#10; NodePosY=576&#10; AdvancedPinDisplay=Hidden&#10; bCanRenameNode=True&#10; NodeGuid=E86CD3F348235DE6CC2252945054150B&#10; CustomProperties Pin (PinId=B5CCFC4846D86017627DEE9FA796D56B,PinName=&amp;#34;UVs&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;byte&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=581290474007CFD4BF95BB8E11839CAF,PinName=&amp;#34;Apply View MipBias&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=95743ADF4830E3324125DBA4CAD74A5D,PinName=&amp;#34;MipValueMode&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;byte&amp;#34;,PinType.PinSubCategoryObject=&amp;#34;/Script/CoreUObject.Enum&amp;#39;/Script/Engine.ETextureMipValueMode&amp;#39;&amp;#34;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;None (use computed mip level)&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=D79D5AEF46AC41D467FEF9A3E60936D9,PinName=&amp;#34;Sampler Source&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;byte&amp;#34;,PinType.PinSubCategoryObject=&amp;#34;/Script/CoreUObject.Enum&amp;#39;/Script/Engine.ESamplerSourceMode&amp;#39;&amp;#34;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;From texture asset&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=7DC20F44499BA2EE6DA5FFA2C2DCD807,PinName=&amp;#34;Sampler Type&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;byte&amp;#34;,PinType.PinSubCategoryObject=&amp;#34;/Script/CoreUObject.Enum&amp;#39;/Script/Engine.EMaterialSamplerType&amp;#39;&amp;#34;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;Linear Color&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=C7637FF44BC21CC478CB42828F2D078C,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_0 F7F6DD344CEA67647D0E038419330B18,MaterialGraphNode_11 7966C3204FC01139EE7059A6B12DC683,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_11&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_11&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionTextureProperty Name=&amp;#34;MaterialExpressionTextureProperty_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionTextureProperty&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_11.MaterialExpressionTextureProperty_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionTextureProperty_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionTextureProperty&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_11.MaterialExpressionTextureProperty_0&amp;#39;&amp;#34;&#10; TextureObject=(Expression=&amp;#34;/Script/Engine.MaterialExpressionTextureObjectParameter&amp;#39;MaterialGraphNode_10.MaterialExpressionTextureObjectParameter_0&amp;#39;&amp;#34;)&#10; Property=TMTM_TexelSize&#10; MaterialExpressionEditorX=-1808&#10; MaterialExpressionEditorY=640&#10; MaterialExpressionGuid=155ABB60499C2795A7CA8EAA0CA254C6&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionTextureProperty&amp;#39;MaterialExpressionTextureProperty_0&amp;#39;&amp;#34;&#10; NodePosX=-1808&#10; NodePosY=640&#10; AdvancedPinDisplay=Hidden&#10; NodeGuid=DAB535CE4059097E649D8B8B5EBACEC7&#10; CustomProperties Pin (PinId=7966C3204FC01139EE7059A6B12DC683,PinName=&amp;#34;Tex&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_10 C7637FF44BC21CC478CB42828F2D078C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=3EC87907425E4BA9E7384CA5A8713D55,PinName=&amp;#34;Texture Property&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;byte&amp;#34;,PinType.PinSubCategoryObject=&amp;#34;/Script/CoreUObject.Enum&amp;#39;/Script/Engine.EMaterialExposedTextureProperty&amp;#39;&amp;#34;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;Texel Size&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=True,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=D5CBAE54419805CAFE9F90BB4AAC62C6,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_0 56BCED2346461B390B07768867598603,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Knot Name=&amp;#34;MaterialGraphNode_Knot_4&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Knot&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_4&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionReroute Name=&amp;#34;MaterialExpressionReroute_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_4.MaterialExpressionReroute_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionReroute_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_4.MaterialExpressionReroute_0&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_6.MaterialExpressionReroute_8&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=400&#10; MaterialExpressionEditorY=32&#10; MaterialExpressionGuid=530E690D4723B52C253785AF50725183&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialExpressionReroute_0&amp;#39;&amp;#34;&#10; NodePosX=400&#10; NodePosY=32&#10; bCanRenameNode=False&#10; NodeGuid=8B14D59D4210496CA49215A7DE06A221&#10; CustomProperties Pin (PinId=7FF15AC5487DF460523606AC5AFDB3A3,PinName=&amp;#34;InputPin&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_6 7D21ACD04B5BA1EA4EEB2395D46B47B7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=B4C786FA423545272EED9F81D9CA4158,PinName=&amp;#34;OutputPin&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_12 F6D0D03348C10280D64782B3B56B869D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_12&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_12&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionMultiply Name=&amp;#34;MaterialExpressionMultiply_5&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_12.MaterialExpressionMultiply_5&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionMultiply_5&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_12.MaterialExpressionMultiply_5&amp;#39;&amp;#34;&#10; A=(Expression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialGraphNode_Knot_4.MaterialExpressionReroute_0&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=448&#10; MaterialExpressionGuid=C1532F524DCEA642A09CE59F8B68FC10&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialExpressionMultiply_5&amp;#39;&amp;#34;&#10; NodePosX=448&#10; NodeGuid=E2AA2EAC4DE80A713F880388EF59E9ED&#10; CustomProperties Pin (PinId=F6D0D03348C10280D64782B3B56B869D,PinName=&amp;#34;A&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0.0&amp;#34;,LinkedTo=(MaterialGraphNode_Knot_4 B4C786FA423545272EED9F81D9CA4158,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=9A76640D4C91345EDDBF269D221991EA,PinName=&amp;#34;B&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;1.0&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=79FF34B04F50FBE02A39B7A5E1418FD6,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_2 F66B95B44E6BA4EB1ECDB4877EB38891,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_20&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_20&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionObjectLocalBounds Name=&amp;#34;MaterialExpressionObjectLocalBounds_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionObjectLocalBounds&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_20.MaterialExpressionObjectLocalBounds_1&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionObjectLocalBounds_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionObjectLocalBounds&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_20.MaterialExpressionObjectLocalBounds_1&amp;#39;&amp;#34;&#10; MaterialExpressionEditorX=-2896&#10; MaterialExpressionEditorY=-400&#10; MaterialExpressionGuid=16FE6BE64A5907BE128D82927E8C0E26&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionObjectLocalBounds&amp;#39;MaterialExpressionObjectLocalBounds_1&amp;#39;&amp;#34;&#10; NodePosX=-2896&#10; NodePosY=-400&#10; NodeGuid=A83B96964689869E2F43E6B2E1DDC469&#10; CustomProperties Pin (PinId=D051141441791C56748386AA51B7DB50,PinName=&amp;#34;Half Extents&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=1A7158654665DCD66D1E67AA7E6765FD,PinName=&amp;#34;Extents&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_6 B5AC9C18412A5B0929AC31915B44FA22,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=1FB4774A453A7438DD9370BD2229240A,PinName=&amp;#34;Min&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_21 92C51A614FF32259F5EE80B5B5135584,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=12A107AB42A69EBBB4BEB4BDBEAE6158,PinName=&amp;#34;Max&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;mask&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_21&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_21&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionMultiply Name=&amp;#34;MaterialExpressionMultiply_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_21.MaterialExpressionMultiply_1&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionMultiply_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_21.MaterialExpressionMultiply_1&amp;#39;&amp;#34;&#10; A=(Expression=&amp;#34;/Script/Engine.MaterialExpressionObjectLocalBounds&amp;#39;MaterialGraphNode_20.MaterialExpressionObjectLocalBounds_1&amp;#39;&amp;#34;,OutputIndex=2,Mask=1,MaskR=1,MaskG=1,MaskB=1)&#10; ConstB=-1.000000&#10; MaterialExpressionEditorX=-2608&#10; MaterialExpressionEditorY=-400&#10; MaterialExpressionGuid=7115882C4E167A3B32466692AD5A235C&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialExpressionMultiply_1&amp;#39;&amp;#34;&#10; NodePosX=-2608&#10; NodePosY=-400&#10; NodeGuid=5EA995794E9F07C0A7B9779094F924CA&#10; CustomProperties Pin (PinId=92C51A614FF32259F5EE80B5B5135584,PinName=&amp;#34;A&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0.0&amp;#34;,LinkedTo=(MaterialGraphNode_20 1FB4774A453A7438DD9370BD2229240A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=932252A743CDE5AF9EBF81B612255375,PinName=&amp;#34;B&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;-1.0&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=A5A3459742561109E4DB2A8F5258C81B,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_5 628144524721EC4D1D6837934C24D8FE,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Knot Name=&amp;#34;MaterialGraphNode_Knot_5&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Knot&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_5&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionReroute Name=&amp;#34;MaterialExpressionReroute_7&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_5.MaterialExpressionReroute_7&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionReroute_7&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_5.MaterialExpressionReroute_7&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialGraphNode_21.MaterialExpressionMultiply_1&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=-2144&#10; MaterialExpressionEditorY=-432&#10; MaterialExpressionGuid=74E084E14E298DB72739508020DC0AF8&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialExpressionReroute_7&amp;#39;&amp;#34;&#10; NodePosX=-2144&#10; NodePosY=-432&#10; bCanRenameNode=False&#10; NodeGuid=33910155476C69547E3B808C02E5EF4B&#10; CustomProperties Pin (PinId=628144524721EC4D1D6837934C24D8FE,PinName=&amp;#34;InputPin&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_21 A5A3459742561109E4DB2A8F5258C81B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=76630B6449047067CB85C7BA29A4C738,PinName=&amp;#34;OutputPin&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_8 407E79E346BF01D91835DD92651128C6,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Knot Name=&amp;#34;MaterialGraphNode_Knot_6&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Knot&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_6&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionReroute Name=&amp;#34;MaterialExpressionReroute_8&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_6.MaterialExpressionReroute_8&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionReroute_8&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Knot_6.MaterialExpressionReroute_8&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionObjectLocalBounds&amp;#39;MaterialGraphNode_20.MaterialExpressionObjectLocalBounds_1&amp;#39;&amp;#34;,OutputIndex=1,Mask=1,MaskR=1,MaskG=1,MaskB=1)&#10; MaterialExpressionEditorX=-2080&#10; MaterialExpressionEditorY=-80&#10; MaterialExpressionGuid=90AB20E04F19EAD0E0F37FA28D8BA540&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionReroute&amp;#39;MaterialExpressionReroute_8&amp;#39;&amp;#34;&#10; NodePosX=-2080&#10; NodePosY=-80&#10; bCanRenameNode=False&#10; NodeGuid=60A4BA424B5FBFCF9A67F8B2F80D525D&#10; CustomProperties Pin (PinId=B5AC9C18412A5B0929AC31915B44FA22,PinName=&amp;#34;InputPin&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_20 1A7158654665DCD66D1E67AA7E6765FD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=7D21ACD04B5BA1EA4EEB2395D46B47B7,PinName=&amp;#34;OutputPin&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;wildcard&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Knot_2 01C914364BC877462FDEA2B8D3472B4D,MaterialGraphNode_Custom_1 E529628745D778728B006BB8D8B4FAC8,MaterialGraphNode_Knot_4 7FF15AC5487DF460523606AC5AFDB3A3,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_22&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_22&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionVertexInterpolator Name=&amp;#34;MaterialExpressionVertexInterpolator_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionVertexInterpolator&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_22.MaterialExpressionVertexInterpolator_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionVertexInterpolator_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionVertexInterpolator&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_22.MaterialExpressionVertexInterpolator_0&amp;#39;&amp;#34;&#10; Input=(Expression=&amp;#34;/Script/Engine.MaterialExpressionCustom&amp;#39;MaterialGraphNode_Custom_0.MaterialExpressionCustom_2&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=688&#10; MaterialExpressionEditorY=-432&#10; MaterialExpressionGuid=C4C86E794A476F30AD62FCAA259179DA&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionVertexInterpolator&amp;#39;MaterialExpressionVertexInterpolator_0&amp;#39;&amp;#34;&#10; NodePosX=688&#10; NodePosY=-432&#10; NodeGuid=C4C82F85453D44AC837E199BDB3134B8&#10; CustomProperties Pin (PinId=164AC73F4B86EEDB7E5ECE93AF2678D5,PinName=&amp;#34;VS&amp;#34;,PinType.PinCategory=&amp;#34;required&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_Custom_0 AF4C1E69462CCBD59FD6CDAFD9A95BED,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=C10995E94398941AA6EAF29648593535,PinName=&amp;#34;PS&amp;#34;,Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_43 42DC685D432EA481873DBBB414F36184,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_42&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_42&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionAdd Name=&amp;#34;MaterialExpressionAdd_3&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_42.MaterialExpressionAdd_3&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionAdd_3&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_42.MaterialExpressionAdd_3&amp;#39;&amp;#34;&#10; A=(Expression=&amp;#34;/Script/Engine.MaterialExpressionConstant3Vector&amp;#39;MaterialGraphNode_1.MaterialExpressionConstant3Vector_0&amp;#39;&amp;#34;,Mask=1,MaskR=1,MaskG=1,MaskB=1)&#10; B=(Expression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialGraphNode_43.MaterialExpressionMultiply_0&amp;#39;&amp;#34;)&#10; MaterialExpressionEditorX=1024&#10; MaterialExpressionEditorY=-544&#10; MaterialExpressionGuid=72A8C8FE4443A88A72B3579D529AE1B9&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionAdd&amp;#39;MaterialExpressionAdd_3&amp;#39;&amp;#34;&#10; NodePosX=1024&#10; NodePosY=-544&#10; NodeGuid=72C9F37240956CAD8CE1E4AC5E4465D3&#10; CustomProperties Pin (PinId=70AB43564198A863B0FCD4B9F291912C,PinName=&amp;#34;A&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0.0&amp;#34;,LinkedTo=(MaterialGraphNode_1 597429E44A337F8EFF998AA7539751D0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=6AE0647042ADD7552D1D6BA4A42B0F76,PinName=&amp;#34;B&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;1.0&amp;#34;,LinkedTo=(MaterialGraphNode_43 243E82F74CF983BE8A996299DA54D423,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=638E8D69403BED61E274A8B4B591B5B2,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_0 156D96F34497F69979397E8818DDAA80,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&amp;#34;MaterialGraphNode_43&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_43&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionMultiply Name=&amp;#34;MaterialExpressionMultiply_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_43.MaterialExpressionMultiply_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionMultiply_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_43.MaterialExpressionMultiply_0&amp;#39;&amp;#34;&#10; A=(Expression=&amp;#34;/Script/Engine.MaterialExpressionVertexInterpolator&amp;#39;MaterialGraphNode_22.MaterialExpressionVertexInterpolator_0&amp;#39;&amp;#34;)&#10; ConstB=4.000000&#10; MaterialExpressionEditorX=896&#10; MaterialExpressionEditorY=-448&#10; MaterialExpressionGuid=91EAE26B4DC685CFE1FCBAAFADA19F37&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpression=&amp;#34;/Script/Engine.MaterialExpressionMultiply&amp;#39;MaterialExpressionMultiply_0&amp;#39;&amp;#34;&#10; NodePosX=896&#10; NodePosY=-448&#10; NodeGuid=24CB389746259EA32100D5BD4251841F&#10; CustomProperties Pin (PinId=42DC685D432EA481873DBBB414F36184,PinName=&amp;#34;A&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;0.0&amp;#34;,LinkedTo=(MaterialGraphNode_22 C10995E94398941AA6EAF29648593535,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=F2CEFE6C4E40FDE7C8F68EA69B782BC5,PinName=&amp;#34;B&amp;#34;,PinType.PinCategory=&amp;#34;optional&amp;#34;,PinType.PinSubCategory=&amp;#34;red&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue=&amp;#34;4.0&amp;#34;,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties Pin (PinId=243E82F74CF983BE8A996299DA54D423,PinName=&amp;#34;Output&amp;#34;,PinFriendlyName=NSLOCTEXT(&amp;#34;MaterialGraphNode&amp;#34;, &amp;#34;Space&amp;#34;, &amp;#34; &amp;#34;),Direction=&amp;#34;EGPD_Output&amp;#34;,PinType.PinCategory=&amp;#34;&amp;#34;,PinType.PinSubCategory=&amp;#34;&amp;#34;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_42 6AE0647042ADD7552D1D6BA4A42B0F76,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Comment Name=&amp;#34;MaterialGraphNode_Comment_0&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Comment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_0&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionComment Name=&amp;#34;MaterialExpressionComment_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_0.MaterialExpressionComment_0&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionComment_0&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_0.MaterialExpressionComment_0&amp;#39;&amp;#34;&#10; SizeX=752&#10; SizeY=256&#10; Text=&amp;#34;バウンディングMin位置基準のローカル頂点座標&amp;#34;&#10; CommentColor=(R=0.150000,G=0.150000,B=0.150000,A=0.500000)&#10; MaterialExpressionEditorX=-2432&#10; MaterialExpressionEditorY=-816&#10; MaterialExpressionGuid=0EBC033440E9F4ABF76695A0D74D7320&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpressionComment=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;MaterialExpressionComment_0&amp;#39;&amp;#34;&#10; CommentColor=(R=0.150000,G=0.150000,B=0.150000,A=0.500000)&#10; bCommentBubbleVisible_InDetailsPanel=False&#10; NodePosX=-2432&#10; NodePosY=-816&#10; NodeWidth=752&#10; NodeHeight=256&#10; bCommentBubblePinned=False&#10; bCommentBubbleVisible=False&#10; NodeComment=&amp;#34;バウンディングMin位置基準のローカル頂点座標&amp;#34;&#10; NodeGuid=11F243C04D08D30F3502E382BE3A65CF&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Comment Name=&amp;#34;MaterialGraphNode_Comment_1&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Comment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_1&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionComment Name=&amp;#34;MaterialExpressionComment_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_1.MaterialExpressionComment_1&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionComment_1&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_1.MaterialExpressionComment_1&amp;#39;&amp;#34;&#10; SizeX=624&#10; SizeY=432&#10; Text=&amp;#34;Boundingサイズぴったりの頂点がＬａｔｔｉｃｅに含まれないためBoundingのサイズを若干バイアス&amp;#34;&#10; CommentColor=(R=0.150000,G=0.150000,B=0.150000,A=0.500000)&#10; MaterialExpressionEditorX=-2992&#10; MaterialExpressionEditorY=-528&#10; MaterialExpressionGuid=0AFC249F4128B6A353DFD98BB97A1C5B&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpressionComment=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;MaterialExpressionComment_1&amp;#39;&amp;#34;&#10; CommentColor=(R=0.150000,G=0.150000,B=0.150000,A=0.500000)&#10; bCommentBubbleVisible_InDetailsPanel=False&#10; NodePosX=-2992&#10; NodePosY=-528&#10; NodeWidth=624&#10; NodeHeight=432&#10; bCommentBubblePinned=False&#10; bCommentBubbleVisible=False&#10; NodeComment=&amp;#34;Boundingサイズぴったりの頂点がＬａｔｔｉｃｅに含まれないためBoundingのサイズを若干バイアス&amp;#34;&#10; NodeGuid=2384E8E640C68B2C42D1DCB392B8DCB8&#10;End Object&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode_Comment Name=&amp;#34;MaterialGraphNode_Comment_2&amp;#34; ExportPath=&amp;#34;/Script/UnrealEd.MaterialGraphNode_Comment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_2&amp;#39;&amp;#34;&#10; Begin Object Class=/Script/Engine.MaterialExpressionComment Name=&amp;#34;MaterialExpressionComment_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_2.MaterialExpressionComment_2&amp;#39;&amp;#34;&#10; End Object&#10; Begin Object Name=&amp;#34;MaterialExpressionComment_2&amp;#34; ExportPath=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;/Engine/Transient.M_DynamicLatticeDeform:MaterialGraph_0.MaterialGraphNode_Comment_2.MaterialExpressionComment_2&amp;#39;&amp;#34;&#10; SizeX=403&#10; SizeY=300&#10; Text=&amp;#34;変位を適当にスケール&amp;#34;&#10; CommentColor=(R=0.150000,G=0.150000,B=0.150000,A=0.500000)&#10; MaterialExpressionEditorX=336&#10; MaterialExpressionEditorY=-64&#10; MaterialExpressionGuid=2C8BE47F4C25F4036AD03E9F262198ED&#10; Material=&amp;#34;/Script/UnrealEd.PreviewMaterial&amp;#39;/Engine/Transient.M_DynamicLatticeDeform&amp;#39;&amp;#34;&#10; End Object&#10; MaterialExpressionComment=&amp;#34;/Script/Engine.MaterialExpressionComment&amp;#39;MaterialExpressionComment_2&amp;#39;&amp;#34;&#10; CommentColor=(R=0.150000,G=0.150000,B=0.150000,A=0.500000)&#10; bCommentBubbleVisible_InDetailsPanel=False&#10; NodePosX=336&#10; NodePosY=-64&#10; NodeWidth=403&#10; NodeHeight=300&#10; bCommentBubblePinned=False&#10; bCommentBubbleVisible=False&#10; NodeComment=&amp;#34;変位を適当にスケール&amp;#34;&#10; NodeGuid=6C8309484C008F0F7DBFFAA45B57778E&#10;End Object&#10;&lt;/pre&gt;&lt;figure class="figure-image figure-image-fotolife" title="Member"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/e80ba81570bcf0f1c555eda9417c941a39560f144e6c04ca69bd11f2837d2068.png" width="467" height="715" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;Member&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="figure-image figure-image-fotolife" title="Initial Vtx Setup"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/93f358ca526114871a288e19c5feeb57e3b82e88f5db4019a45ac806d588c847.png" width="877" height="665" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;Initial Vtx Setup&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="figure-image figure-image-fotolife" title="TransformVtxNormalizeToWorld"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/a98093ef6903ca902f7678ddba9101a42c08a74c496151c803b78222c9d4bcf6.png" width="1200" height="514" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;TransformVtxNormalizeToWorld&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="figure-image figure-image-fotolife" title="TransformVtxWorldToNormalize"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/74e2cfa4be4c3c2e062577c5d19467ffcdda6f9205a97d68683c12893ec096b9.png" width="1200" height="450" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;TransformVtxWorldToNormalize&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="figure-image figure-image-fotolife" title="VtxIndexToCellPosition"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/19e380f23ecd474bff340626a8c358a0cecd8569f0470bc315b2fb6d1a7e93de.png" width="1200" height="294" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;VtxIndexToCellPosition&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="figure-image figure-image-fotolife" title="UpdateLatticeVtxTexture"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/4044f288fc4766a3b8f9e944daadd7c896878fab057ad91ea79b43b37fe2e339.png" width="1200" height="515" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;UpdateLatticeVtxTexture&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;BP&lt;/p&gt;</description></item><item><title>UEマテリアルネタ帳</title><link>https://nagakagachi.github.io/entry/2026/01/28/234656/</link><pubDate>Wed, 28 Jan 2026 23:46:56 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2026/01/28/234656/</guid><description>&lt;p&gt;雑多なネタを書いてあとで探しやすくするためのページ.&lt;/p&gt;&#10;&lt;p&gt;役に立ったらイイネや紹介してね☆（ゝω・）vｷｬﾋﾟ&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#Simplex頂点に任意の乱数を利用できるSimplex-Noise"&gt;Simplex頂点に任意の乱数を利用できるSimplex Noise&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#入力ベクトルの主要軸と第二主要軸を抽出する"&gt;入力ベクトルの主要軸と第二主要軸を抽出する&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Simplex頂点に任意の乱数を利用できるSimplex-Noise"&gt;Simplex頂点に任意の乱数を利用できるSimplex Noise&lt;/h3&gt;&#10;&lt;p&gt;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fnagakagachi.hatenablog.com%2Fentry%2F2023%2F07%2F26%2F135233" title="Simplex頂点に任意の乱数を利用できるSimplex Noise Custom Node[UE][UE5] - ながむしメモ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2023/07/26/135233"&gt;nagakagachi.hatenablog.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="入力ベクトルの主要軸と第二主要軸を抽出する"&gt;入力ベクトルの主要軸と第二主要軸を抽出する&lt;/h3&gt;&#10;&lt;p&gt;ベクトルの&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8"&gt;コンポーネント&lt;/a&gt;について絶対値が大きい順で第一位(Dominant), 第二位(Secondary)の軸の情報を抽出する.&lt;br /&gt;&#10;軸インデックス:x=0, y=1, z=2&lt;br /&gt;&#10;と&lt;br /&gt;&#10;軸マスクベクトル (1, 0, 0), (0, 1, 0), (0, 0, 1)&lt;br /&gt;&#10;を返す.&lt;br /&gt;&#10;もっとシンプルな記述ができそうなので後でアップデートするかも.&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/2f7988364730b8938c8767f1068a1d61ce37261a3bab66557ad5ed82ea7fbfab.png" width="1200" height="717" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synType"&gt;const&lt;/span&gt; float3 abs_dir = &lt;span class="synIdentifier"&gt;abs&lt;/span&gt;(in_dir);&#10;&lt;p&gt;&lt;span class="synType"&gt;const&lt;/span&gt; int3 comp0 = abs_dir.xyz &amp;gt; abs_dir.yzx;&#10;&lt;span class="synType"&gt;const&lt;/span&gt; int3 comp1 = abs_dir.xyz &amp;gt; abs_dir.zxy;&#10;&lt;span class="synType"&gt;const&lt;/span&gt; int3 &lt;span class="synType"&gt;rank&lt;/span&gt; = comp0+comp1;&lt;/p&gt;</description></item><item><title>曲線メモ</title><link>https://nagakagachi.github.io/entry/2025/05/10/171443/</link><pubDate>Sat, 10 May 2025 17:14:43 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2025/05/10/171443/</guid><description>&lt;p&gt;n番煎じであっても自分でメモすることが&amp;hellip;大事&amp;hellip;!&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Cubic-Hermite-Spline"&gt;Cubic Hermite Spline&lt;/h3&gt;&#10;&lt;p&gt;いわゆるエルミート曲線&lt;/p&gt;&#10;&lt;p&gt;3次式&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y(t) = a t^3 + b t^2 + c t + d\)&lt;/span&gt;&lt;br /&gt;&#10;とその&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C6%B3%B4%D8%BF%F4"&gt;導関数&lt;/a&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y′(t) = 3 a t^2 + 2 b t + c\)&lt;/span&gt;&lt;br /&gt;&#10;を考え, &lt;/p&gt;&lt;p&gt;2つの端点&lt;span class="math-inline"&gt;\(t_0\)&lt;/span&gt;, &lt;span class="math-inline"&gt;\(t_1\)&lt;/span&gt;で以下の4つの条件を満たすような係数&lt;span class="math-inline"&gt;\(a,b,c,d\)&lt;/span&gt;を求める.&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y(t_0) = y_0\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y(t_1) = y_1\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y'(t_0) = d_0\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y'(t_1) = d_1\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;4つの未知数と4つの方程式なので解ける.&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(a = 2 y_0 - 2 y_1 + d_0 + d_1\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(b = -3 y_0 + 3 y_1 - 2 d_0 - d_1\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(c = d_0\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(d = y_0\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;係数&lt;span class="math-inline"&gt;\(a,b,c,d\)&lt;/span&gt;による元の3次式は, 端点を通り且つ端点での接線が条件に一致するような曲線になる→ Cubic Hermite Curve&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y(t) = (2 y_0 - 2 y_1 + d_0 + d_1) t^3 + (-3 y_0 + 3 y_1 - 2 d_0 - d_1) t^2 + d_0 t + y_0\)&lt;/span&gt;&lt;/p&gt;&#10;&lt;p&gt;バリエーションによっては接線ではなく更に外側の2点を利用するものがある.&lt;/p&gt;&#10;&lt;p&gt;また, 元の関数の定義域xを正規化された定義域t [0,1]へ変換して利用する場合には, x-&gt;tの変換によって接線の勾配が変化するため考慮する必要がある.&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(y(x) , x_0 &amp;lt;= x &amp;lt;= x_1\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(t = x / (x_1 - x_0)\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(dt = dx/(x_1 - x_0)\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(dy/dx = dy/(dt * (x_1 - x_0))\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(dy/dt = (x_1 - x_0) * dy/dx\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synType"&gt;auto&lt;/span&gt; CubicHermite = [](&lt;span class="synType"&gt;float&lt;/span&gt; t, &lt;span class="synType"&gt;float&lt;/span&gt; y0, &lt;span class="synType"&gt;float&lt;/span&gt; y1, &lt;span class="synType"&gt;float&lt;/span&gt; d0, &lt;span class="synType"&gt;float&lt;/span&gt; d1)&#10;{&#10;&#9;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; k_a = &lt;span class="synConstant"&gt;2.0&lt;/span&gt; * y0 - &lt;span class="synConstant"&gt;2.0&lt;/span&gt; * y1 + d0 + d1;&#10;&#9;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; k_b = -&lt;span class="synConstant"&gt;3.0&lt;/span&gt; * y0 + &lt;span class="synConstant"&gt;3.0&lt;/span&gt; * y1 - &lt;span class="synConstant"&gt;2.0&lt;/span&gt; * d0 - d1;&#10;&#9;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; k_c = d0;&#10;&#9;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; k_d = y0;&#10;&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;synStatement&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; k_a*(t*t*t) + k_b*(t*t) + k_c*(t) + k_d;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;};&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; y0 = &lt;span class="synConstant"&gt;0.0f&lt;/span&gt;;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; y1 = &lt;span class="synConstant"&gt;1.0f&lt;/span&gt;;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; d0 = &lt;span class="synConstant"&gt;1.0f&lt;/span&gt;;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; d1 = &lt;span class="synConstant"&gt;1.0f&lt;/span&gt;;&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; hv0 = &lt;span class="synIdentifier"&gt;CubicHermite&lt;/span&gt;(&lt;span class="synConstant"&gt;0.0f&lt;/span&gt;, y0, y1, d0 ,d1); &lt;span class="synComment"&gt;// 0.0&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; hv1 = &lt;span class="synIdentifier"&gt;CubicHermite&lt;/span&gt;(&lt;span class="synConstant"&gt;0.5f&lt;/span&gt;, y0, y1, d0 ,d1); &lt;span class="synComment"&gt;// 0.5&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; hv2 = &lt;span class="synIdentifier"&gt;CubicHermite&lt;/span&gt;(&lt;span class="synConstant"&gt;0.8f&lt;/span&gt;, y0, y1, d0 ,d1); &lt;span class="synComment"&gt;// 0.8&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; hv3 = &lt;span class="synIdentifier"&gt;CubicHermite&lt;/span&gt;(&lt;span class="synConstant"&gt;1.0f&lt;/span&gt;, y0, y1, d0 ,d1); &lt;span class="synComment"&gt;// 1.0&lt;/span&gt;&#10;&lt;/pre&gt;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>Unreal Engine Meetup Connect - Vol.4 - TA編 資料</title><link>https://nagakagachi.github.io/entry/2025/04/14/210146/</link><pubDate>Mon, 14 Apr 2025 21:01:46 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2025/04/14/210146/</guid><description>&lt;p&gt;昨年10月のUEイベント登壇資料です.&lt;br/&gt;&lt;br /&gt;&#10;TA編に紛れ込んだ&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C5%DA%B6%F6"&gt;土偶&lt;/a&gt;のSceneViewExtensionやRenderGraphの妙な資料です.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;iframe src="https://www.docswell.com/slide/ZL1JL3/embed" allowfullscreen="true" class="docswell-iframe" width="620" height="349" style="border: 1px solid #ccc; display: block; margin: 0px auto; padding: 0px; aspect-ratio: 620/349;"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://www.docswell.com/s/leon-gameworks/ZL1JL3-2024-10-20-225343"&gt;www.docswell.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;イベント自体やほかの登壇者のみなさんの資料はこちら.&lt;br/&gt;&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fleon-gameworks.connpass.com%2Fevent%2F328282%2Fpresentation%2F" title="Unreal Engine Meetup Connect - Vol.4 - TA編 - 資料一覧 - connpass" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://leon-gameworks.connpass.com/event/328282/presentation/"&gt;leon-gameworks.connpass.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2025/04/14/210146"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>セルシェーディング顔陰用SDFテクスチャ合成の仕組み (SDF Based Transition Blending for Shadow Threshold Map)</title><link>https://nagakagachi.github.io/entry/2024/03/02/140704/</link><pubDate>Sat, 02 Mar 2024 14:07:04 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2024/03/02/140704/</guid><description>&lt;p&gt;&lt;span style="font-size: 80%;"&gt;誤ってページ削除してしまいましたが2024年の記事です&lt;/span&gt;&lt;/p&gt;&#10;&lt;p&gt;セルルックキャ&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E9%A5%AF"&gt;ラク&lt;/a&gt;ターの顔の陰制御に用いられるShadow Threshold Mapを生成する仕組みについて.&lt;br /&gt;連番二値画像からSDFを利用してテクスチャ合成する基本部分の説明を試みます.&lt;/p&gt;&#10;&lt;p&gt;(Face Thresholdテクスチャ, Shadow Thresholdテクスチャ, SDFテクスチャ などとも)&lt;/p&gt;&#10;&lt;blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"&gt;&#10;&lt;p dir="ltr" lang="ja"&gt;SDFによる補間で Shadow Threshold Map を連番画像から自動生成するツール&lt;br /&gt;&lt;br /&gt;を&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GitHub"&gt;GitHub&lt;/a&gt;のSDFツールの中にUPしました.&lt;br /&gt;&lt;br /&gt;EUW_GenerateShadowThresholdMap がツール自体.&lt;br /&gt;現状は全画像が等間隔な&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%EF%E7%C3%CD"&gt;閾値&lt;/a&gt;になります.&lt;br /&gt;&lt;br /&gt;合成方法の説明などドキュメントは後で(∩´∀｀)∩&lt;a href="https://t.co/6GdbEja9o3"&gt;https://t.co/6GdbEja9o3&lt;/a&gt;&lt;a href="https://twitter.com/hashtag/UE5?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#UE5&lt;/a&gt; &lt;a href="https://t.co/52QUQek23i"&gt;pic.twitter.com/52QUQek23i&lt;/a&gt;&lt;/p&gt;&#10;— なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/1732041139325489588?ref_src=twsrc%5Etfw"&gt;2023年12月5日&lt;/a&gt;&lt;/blockquote&gt;&#10;&lt;p&gt;&#10;&lt;script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;&#10;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="概要"&gt;概要&lt;/h3&gt;&#10;&lt;p&gt;&lt;img src="images/e964cbb37d67738f7ee3261802f9013a60c997ee916df1f2ee6395aa10604695.png" width="1200" height="298" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /&gt;&lt;br /&gt;&lt;img src="images/5056f97907159cb92c7d91829eed6fb23e038cde4f12f324881a86553ff5e153.png" width="1200" height="959" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /&gt;&lt;/p&gt;&#10;&lt;p&gt;UE5上のツールとしては以下のSDF関連ツールに含まれています.&lt;br /&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D6%A5%E9%A5%C3%A5%AF%A5%DC%A5%C3%A5%AF%A5%B9"&gt;ブラックボックス&lt;/a&gt;無しでBPとマテリアルとして実装しているので詳細はそちらをご確認ください.&lt;br /&gt;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnagakagachi%2FNagaSdfTextureToolForUE" title="GitHub - nagakagachi/NagaSdfTextureToolForUE: Tools for generating SDF from textures in Unreal Engine" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://github.com/nagakagachi/NagaSdfTextureToolForUE"&gt;github.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;br /&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="アルゴリズム"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0"&gt;アルゴリズム&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;ここでは最もシンプルと思われる&lt;strong&gt;C0連続&lt;/strong&gt;な合成を考えます.&lt;br /&gt;連番二値画像間の遷移速度をよりなめらかにしたい場合はC1連続となるように合成するのが良いかもしれません.&lt;/p&gt;&#10;&lt;p&gt;連番の連続する2枚ずつを処理していきます.&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="処理対象の連続するペア"&gt;処理対象の連続するペア&lt;/h4&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="連番のi番目とi+1番目の例"&gt;&lt;img src="images/943980dea4019b8066142c39379518461f9726283449391830ebf67775aa9661.png" alt="" width="1200" height="334" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /&gt;&#10;&lt;figcaption&gt;連番のi番目とi+1番目の例&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="SDF生成"&gt;SDF生成&lt;/h4&gt;&#10;&lt;p&gt;二値画像のSDFを計算.&lt;br&gt;&#10;内部側の距離も必要なのでSigned Distance Fieldである必要があります.&lt;/p&gt;</description></item><item><title>【UE5】Niagara SimulationStageでNormalMapからHeightMapを復元する(Poisson方程式)</title><link>https://nagakagachi.github.io/entry/2023/12/16/161144/</link><pubDate>Sat, 16 Dec 2023 16:11:44 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2023/12/16/161144/</guid><description>&lt;p&gt;&lt;span&gt;&lt;style&gt;&#10;img{&#10;display: inline-block;&#10;box-sizing: border-box;&#10;border: solid 1px #333;&#10;}&#10;&lt;/style&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Unreal%20Engine"&gt;Unreal Engine&lt;/a&gt; Advent Calendar 2023 の16日の記事です. &lt;a href="https://qiita.com/advent-calendar/2023/ue"&gt;Unreal Engine (UE)&amp;#x306E;&amp;#x30AB;&amp;#x30EC;&amp;#x30F3;&amp;#x30C0;&amp;#x30FC; | Advent Calendar 2023 - Qiita&lt;/a&gt;&lt;/p&gt;&lt;p&gt;最近HoudiniでNormalMapからHeightMapを復元するというものを見かけ,&lt;br /&gt;&#10;Poisson方程式を解くのであればSimulationStageで実装することができるのではと考えました.&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;というわけで、&lt;a href="https://twitter.com/TearsOfJake?ref_src=twsrc%5Etfw"&gt;@TearsOfJake&lt;/a&gt; さんのアド&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D0%A5%A4%A5%B9"&gt;バイス&lt;/a&gt;を元に、 &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%DD%A5%A2%A5%BD%A5%F3%CA%FD%C4%F8%BC%B0"&gt;ポアソン方程式&lt;/a&gt;を用いたノーマルマップからハイトマップの復元。昨日の勾配のみの復元に比べて圧倒的に安定している。 &lt;br&gt;左：入力メッシュ &lt;br&gt;中：入力メッシュから求めたノーマルマップ&lt;br&gt;右：ノーマルマップから復元した高さ情報 &lt;a href="https://t.co/NiNyVvvrbS"&gt;pic.twitter.com/NiNyVvvrbS&lt;/a&gt;&lt;/p&gt;&amp;mdash; &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Akira"&gt;Akira&lt;/a&gt; Saito (@a_saito) &lt;a href="https://twitter.com/a_saito/status/1721076487150084376?ref_src=twsrc%5Etfw"&gt;2023年11月5日&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;&lt;br /&gt;&#10;&lt;p&gt;この記事では「NormalMapからHeightMapを復元する」という問題をSimulationStageで実装する方法を紹介します.&lt;br /&gt;&#10;サンプルプロジェクトは以下のGoogleDriveになります (動作確認バージョン UE5.3).&lt;br /&gt;&#10;&lt;a href="https://drive.google.com/file/d/13X7s09O3bYuvWyIRp3HkDaNOcjrpnOdy/view?usp=sharing"&gt;ReconstructHeightMapFromNormal.zip - Google &amp;#x30C9;&amp;#x30E9;&amp;#x30A4;&amp;#x30D6;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/811419472fa7cff90fd29f512ec692d5e3a1ed029c96a017cf78f1c960ef9310.png" width="1200" height="657" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Niagara-SimulationStage"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Niagara"&gt;Niagara&lt;/a&gt; SimulationStage&lt;/h3&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Niagara"&gt;Niagara&lt;/a&gt; SimulationStage はComputeShader的な&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPGPU"&gt;GPGPU&lt;/a&gt;処理を&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Niagara"&gt;Niagara&lt;/a&gt;モジュールとして作成できる仕組みです.&lt;br /&gt;&#10;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Epic%20Games"&gt;Epic Games&lt;/a&gt;公式の&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Niagara"&gt;Niagara&lt;/a&gt; Fluids等でも多用されています(本当にSimulationStageでほとんどの処理が作られています まじかよ).&lt;/p&gt;&lt;p&gt;SimulationStage は2D/3Dのグリッド構造に対する&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPGPU"&gt;GPGPU&lt;/a&gt;処理を比較的簡単に作ることができるように設計されています.&lt;br /&gt;&#10;これには数値シミュレーションで必要とされる反復実行なども含まれています.&lt;br /&gt;&#10;目的のタスクを適切な形に変形してSimulationStageで実装することで, &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;による高速な実行が可能になります.&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/f98da2e455903354e0d62a7fb3506e1d0408098ff6cc774991c5c248069f90f1.png" width="1200" height="816" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="NormalMapからHeightMapを復元する問題"&gt;NormalMapからHeightMapを復元する問題&lt;/h3&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Poisson方程式"&gt;Poisson方程式&lt;/h3&gt;&#10;&lt;p&gt;ある関数の二階の空間&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C8%F9%CA%AC"&gt;微分&lt;/a&gt;と別の関数との関係式をPoisson方程式といいます.&lt;br /&gt;&#10;Poisson方程式は離散化によって連立一次方程式へ変形することができ, 連立一次方程式を解く方法は様々に研究されています.&lt;br /&gt;&#10;対象の問題をPoisson方程式, ひいては連立一次方程式の形にすることができれば, Solverや解法を利用して解くことができます.&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(\Delta \phi =-\dfrac{\rho}{\epsilon_0}\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="Poisson方程式への変形"&gt;Poisson方程式への変形&lt;/h4&gt;&#10;&lt;p&gt;今回は NormalMapとHeightMapの関係をPoisson方程式で表現して離散化, 連立一次方程式として解くことにします.&lt;/p&gt;&#10;&lt;p&gt;NormalMapのxy成分はHeightMapの空間&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C8%F9%CA%AC"&gt;微分&lt;/a&gt;(勾配)から求められます.&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(N_x(x,y)= -\dfrac { \partial H(x,y)}{\partial x}\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(N_y(x,y)= -\dfrac { \partial H(x,y)}{\partial y}\)&lt;/span&gt;&lt;br /&gt;&#10;さらにそれぞれ x, y で&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%D0%C8%F9%CA%AC"&gt;偏微分&lt;/a&gt;します.&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(\dfrac {\partial N_x(x,y)}{\partial x}= -\dfrac { \partial^2 H(x,y)}{\partial x^2}\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(\dfrac {\partial N_y(x,y)}{\partial y}= -\dfrac { \partial^2 H(x,y)}{\partial y^2}\)&lt;/span&gt;&lt;br /&gt;&#10;ここで上の式はPoisson方程式の形になっています.&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="差分方程式"&gt;差分方程式&lt;/h5&gt;&#10;&lt;p&gt;このPoisson方程式を離散化すると以下のようになります.&lt;br /&gt;&#10;(&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C5%EC%B3%A4%C2%E7%B3%D8"&gt;東海大学&lt;/a&gt;理学部遠藤研究室さんのページ等がわかりやすいです. -&gt; &lt;a href="https://teamcoil.sp.u-tokai.ac.jp/lectures/EL1/Poisson/index.html"&gt;&amp;#x96FB;&amp;#x78C1;&amp;#x5834;(SP)&lt;/a&gt; )&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(\frac {N_x(x+h,y) - N_x(x-h,y)}{2h}= -\frac {H(x+h,y)+H(x-h,y) - 2H(x,y)}{h^2}\)&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(\frac {N_x(x,y+h) - N_x(x,y-h)}{2h}= -\frac {H(x,y+h)+H(x,y-h) - 2H(x,y)}{h^2}\)&lt;/span&gt;&lt;br /&gt;&#10;(左辺は中心差分)&lt;/p&gt;&lt;p&gt;2つの式を足して左辺のNormalMap, 右辺にHeightMapに関わる項をまとめて整理します.&lt;br /&gt;&#10;またテクセルでの&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C8%F9%CA%AC"&gt;微分&lt;/a&gt;(差分)のため &lt;span class="math-inline"&gt;\(h = 1\)&lt;/span&gt; とします.&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(- \frac {N_x(x+1,y) - N_x(x-1,y) + N_x(x,y+1) - N_x(x,y-1)}{2} \\= H(x+1,y)+H(x-1,y) + H(x,y+1)+H(x,y-1) - 4H(x,y)\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;上の式の左辺は入力NormalMapとして与えられる既知の値, 右辺は求めたいHeightMapのいくつかの地点の値に係数をかけたものの和です.&lt;br /&gt;&#10;よってこれは左辺を定数&lt;span class="math-inline"&gt;\(b\)&lt;/span&gt;, 未知のHeightMapを&lt;span class="math-inline"&gt;\(x\)&lt;/span&gt;, 近傍HeightMap値への係数を行列&lt;span class="math-inline"&gt;\(A\)&lt;/span&gt;とした連立一次方程式ということになります.&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(b = Ax\)&lt;/span&gt;&lt;/p&gt;&#10;&lt;p&gt;連立一次方程式を解くために更に変形していきます.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="Jacobi法"&gt;Jacobi法&lt;/h5&gt;&#10;&lt;p&gt;見通しをよくするために左辺は記号で置き換えておきます.&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(-N_{d} = H(x+1,y)+H(x-1,y) + H(x,y+1)+H(x,y-1) - 4H(x,y)\)&lt;/span&gt; &lt;br /&gt;&#10;(ここで &lt;span class="math-inline"&gt;\(N_{d} =\frac {N_x(x+1,y) - N_x(x-1,y) + N_x(x,y+1) - N_x(x,y-1)}{2}\)&lt;/span&gt; )&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(H(x,y)\)&lt;/span&gt; に関する形に変形します.&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(H(x,y) = \frac{(H(x+1,y)+H(x-1,y)+H(x,y+1)+H(x,y-1)) + N_{d} }{4}\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;この式を反復的に計算することで &lt;span class="math-inline"&gt;\(H(x,y)\)&lt;/span&gt; を解に近づけていく方法をJacobi法といいます.&lt;br /&gt;&#10;プログラム的に考えると&lt;strong&gt;HeightMapの各テクセルについて上下左右の近傍値とNormalMapの値を使って更新&lt;/strong&gt;しているといえます.&lt;br /&gt;&#10;現在のHeightMapから次のHeightMapの各テクセルを並列に計算できるため&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPGPU"&gt;GPGPU&lt;/a&gt;とも相性が良いです.&lt;br /&gt;&#10;次はJacobi法によるHeightMapの計算を&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Niagara"&gt;Niagara&lt;/a&gt; SimulationStageで実装します.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Simplex頂点に任意の乱数を利用できるSimplex Noise Custom Node[UE][UE5]</title><link>https://nagakagachi.github.io/entry/2023/07/26/135233/</link><pubDate>Wed, 26 Jul 2023 13:52:33 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2023/07/26/135233/</guid><description>&lt;p&gt;題名の通りです.&lt;/p&gt;&#10;&lt;p&gt;個人的な興味により Simplex Noiseの頂点毎の乱数計算 を差し替えられるCustomNodeを作成したので公開.&lt;/p&gt;&#10;&lt;p&gt;Simplex Noise には以下のShadertoyを参考にしています. thanks!&lt;br /&gt;&#10;&lt;a href="https://www.shadertoy.com/view/XsX3zB"&gt;https://www.shadertoy.com/view/XsX3zB&lt;/a&gt;&lt;br /&gt;&#10;(XsX3zB)&lt;/p&gt;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/6341e8500430eef917d544f8bbfdce4695c1a4c941362eaa86570ca9392d3d32.png" width="1200" height="896" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&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;ul&gt;&#10;&lt;li&gt;&lt;a href="#前処理CustomNode"&gt;前処理CustomNode&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#乱数CustomNode-3D座標から3D乱数出力ができるものに置き換え可能"&gt;乱数CustomNode (3D座標から3D乱数出力ができるものに置き換え可能)&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#後処理CustomNode"&gt;後処理CustomNode&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;ul&gt;&#10;&lt;li&gt;&lt;a href="#マテリアルコピペ用"&gt;マテリアルコピペ用&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="前置き"&gt;前置き&lt;/h3&gt;&#10;&lt;p&gt;CustomNodeは3段階(コア部分は2段階)で,&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;前処理&#10;&lt;ul&gt;&#10;&lt;li&gt;Simplexの頂点情報他を出力&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;乱数ノード&#10;&lt;ul&gt;&#10;&lt;li&gt;(ここが任意に差し替え可)&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;後処理&#10;&lt;ul&gt;&#10;&lt;li&gt;Simplex頂点の乱数からノイズ出力&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;という構成です.&lt;/p&gt;&#10;&lt;p&gt;使用例としては以下のようになります.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="使用例"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/1a45015452350cb2918ce03f7060bd4fc083c8bcfcac3def2bc52f7e6b2fcb22.png" width="1200" height="454" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;使用例&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="コピペ用テキスト"&gt;コピペ用テキスト&lt;/h3&gt;&#10;&lt;p&gt;マテリアルエディタにうまくコピペできない等の問題がありましたら&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Twitter"&gt;Twitter&lt;/a&gt;等でお知らせください.&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="前処理CustomNode"&gt;前処理CustomNode&lt;/h4&gt;&#10;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/e250ef305152f57f40e7c94ccbcb91414348dc489a18cd1ec49f4181f0ad3e60.png" width="381" height="386" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;pre class="code lang-hlsl" data-lang="hlsl" data-unlink&gt;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&lt;span class="synConstant"&gt;&amp;quot;MaterialGraphNode_109&amp;quot;&lt;/span&gt;&#10; Begin Object Class=/Script/Engine.MaterialExpressionCustom Name=&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionCustom_0&amp;quot;&lt;/span&gt;&#10; End Object&#10; Begin Object Name=&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionCustom_0&amp;quot;&lt;/span&gt;&#10; Code=&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;/*&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; 3D SimplexNoise の前段処理&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;[Reference materials]&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;https://www.shadertoy.com/view/XsX3zB&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; input:&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; // ノイズ計算座標.&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; in_pos&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; output:&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; // Simplex(3DではTetrahedron)の頂点座標&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_vtx_pos0&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_vtx_pos1&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_vtx_pos2&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_vtx_pos3&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; &lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; // Simplexの頂点へのベクトル. 後段でのGradientNoise計算用.&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_d0&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_d1&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_d2&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; out_simplex_d3&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;*/&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;const float F3 = 0.33333;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;const float G3 = 0.16667;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;// Skew&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 s = floor(in_pos + dot(in_pos, F3));&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 x = in_pos - s + dot(s, G3);&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;//&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 e = step(0.0, x - x.yzx);&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 i1 = e * (1.0 - e.zxy);&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 i2 = 1.0 - e.zxy*(1.0-e);&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;//&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 x1 = x - i1 + G3;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 x2 = x - i2 + 2.0 * G3;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float3 x3 = x - 1.0 + 3.0*G3;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_vtx_pos0 = s;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_vtx_pos1 = s + i1;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_vtx_pos2 = s + i2;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_vtx_pos3 = s + 1;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_d0 = x;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_d1 = x1;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_d2 = x2;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;out_simplex_d3 = x3;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;return 1;&amp;quot;&lt;/span&gt;&#10; Description=&lt;span class="synConstant"&gt;&amp;quot;Custom_SimplexNoise3to1_Setup&amp;quot;&lt;/span&gt;&#10; &lt;span class="synIdentifier"&gt;Inputs&lt;/span&gt;(&lt;span class="synConstant"&gt;0&lt;/span&gt;)=(InputName=&lt;span class="synConstant"&gt;&amp;quot;in_pos&amp;quot;&lt;/span&gt;,Input=(Expression=/Script/Engine.MaterialExpressionAdd'&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionAdd_5&amp;quot;&lt;/span&gt;'))&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;0&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos0&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos1&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;2&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos2&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;3&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos3&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;4&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d0&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;5&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d1&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;6&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d2&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; &lt;span class="synIdentifier"&gt;AdditionalOutputs&lt;/span&gt;(&lt;span class="synConstant"&gt;7&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d3&amp;quot;&lt;/span&gt;,OutputType=CMOT_Float3)&#10; MaterialExpressionEditorX=-&lt;span class="synConstant"&gt;2048&lt;/span&gt;&#10; MaterialExpressionEditorY=&lt;span class="synConstant"&gt;2512&lt;/span&gt;&#10; MaterialExpressionGuid=4244B9A4494561E6D73F14B3D48C4E67&#10; Material=/Script/UnrealEd.PreviewMaterial'&lt;span class="synConstant"&gt;&amp;quot;/Engine/Transient.M_InnerLayerPm2&amp;quot;&lt;/span&gt;'&#10; bShowOutputNameOnPin=True&#10; bCollapsed=True&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;0&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;return&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos0&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;2&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos1&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;3&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos2&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;4&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos3&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;5&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d0&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;6&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d1&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;7&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d2&amp;quot;&lt;/span&gt;)&#10; &lt;span class="synIdentifier"&gt;Outputs&lt;/span&gt;(&lt;span class="synConstant"&gt;8&lt;/span&gt;)=(OutputName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d3&amp;quot;&lt;/span&gt;)&#10; End Object&#10; MaterialExpression=/Script/Engine.MaterialExpressionCustom'&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionCustom_0&amp;quot;&lt;/span&gt;'&#10; NodePosX=-&lt;span class="synConstant"&gt;2048&lt;/span&gt;&#10; NodePosY=&lt;span class="synConstant"&gt;2512&lt;/span&gt;&#10; NodeGuid=694DDEB64074FA334F4FD9A71A7FD483&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=14B3EA4E44D4A873700D33A55F7AE5AD,PinName=&lt;span class="synConstant"&gt;&amp;quot;in_pos&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_103 &lt;span class="synConstant"&gt;5246F&lt;/span&gt;4EE4F841D0B87A775BDC4A8D155,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=B819619E4D1A27419AB524893B6ECD84,PinName=&lt;span class="synConstant"&gt;&amp;quot;return&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=9EE1744F4571B813B1BBDE890386E4B4,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos0&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_111 9D0A05744027353F9E7118A2194B1162,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=1E152C9B4E3FDD460C71EBBD7728B4F5,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos1&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_113 &lt;span class="synConstant"&gt;8126F&lt;/span&gt;F97480C0E2317A4F7A582DAD0A3,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=EDB6385B40CB4F839646B784E3E9D173,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos2&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_112 164ABAAD466D2377D81D0CA5A60C9B3C,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=72873D064EE5FD985F001AA3892D9F49,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_vtx_pos3&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_114 7D8DCA5C4A5DE0ACA7BD0C82724D301A,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=7746174D4FB60AF7C5C5F095B5CA2773,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d0&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_110 DB76CCAB48E57973572CEC889D1AD7A3,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=00AD30144201B89E1E00758A88479315,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d1&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_110 &lt;span class="synConstant"&gt;62F&lt;/span&gt;D7FB84275385A5AE2688318A0242F,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=A101A4114BE2E007A7A9DE8B88751614,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d2&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_110 68133C4D4BE01D7D4C180184CC5A24C8,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=CF20B6B54351C38C12EB46B59994524D,PinName=&lt;span class="synConstant"&gt;&amp;quot;out_simplex_d3&amp;quot;&lt;/span&gt;,Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=&lt;span class="synConstant"&gt;None&lt;/span&gt;,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(MaterialGraphNode_110 1419241C4116FF68392D659CFBE3035C,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;&lt;/pre&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="乱数CustomNode-3D座標から3D乱数出力ができるものに置き換え可能"&gt;乱数CustomNode (3D座標から3D乱数出力ができるものに置き換え可能)&lt;/h4&gt;&#10;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/090f0c3bf42a233eab6c57b069cad5278d65b33a3b41b6e077285f7b51e60b76.png" width="305" height="160" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;</description></item><item><title>UE5.2でC++プロジェクトのビルド時間が増加した問題の対処 [UE][UE5.2]</title><link>https://nagakagachi.github.io/entry/2023/06/10/221712/</link><pubDate>Sat, 10 Jun 2023 22:17:12 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2023/06/10/221712/</guid><description>&lt;p&gt;UE5.1からUE5.2へアップデートしてから, &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/C%2B%2B"&gt;C++&lt;/a&gt;プロジェクトのビルド時間が5倍以上に増えて困った.&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9"&gt;ソースコード&lt;/a&gt;を色々書き換えて調べたところ,&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;GlobalShader派生クラスへの&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/SRV"&gt;SRV&lt;/a&gt;, UAV設定関数をフラットに記述する数が大きく影響&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;というところまでわかったのでメモ.&lt;/p&gt;&#10;&lt;p&gt;私と同じ沼にハマったひとの役にたてば幸い.&lt;/p&gt;&#10;&lt;p&gt;具体的には以下のUtil関数が該当&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;RenderCore/Public/ShaderParameterUtils.h&#10;SetSRVParameter()&#10;SetUAVParameter()&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&#10;&lt;p&gt;これらを一つの関数内で直接大量に(フラットに)記述するとビルド時間が大きく増加する模様.&lt;br /&gt;&#10;対策としては &lt;strong&gt;Shader単位等で関数化してそれを呼び出すような記述&lt;/strong&gt; とするとUE5.1以前と同じくらいのビルド時間だった.&lt;/p&gt;&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;// ビルド時間が増えるパターン 100個くらい並んでました.&#10;void MainFunc()&#10;{&#10; // 全てのShaderに対するSetSRV/SetUAVをフラットに記述.&#10; SetSRVParameter(ShaderA, SRV);&#10; SetSRVParameter(ShaderA, SRV);&#10; SetUAVParameter(ShaderA, UAV);&#10; SetUAVParameter(ShaderA, UAV);&#10; ...&#10; SetSRVParameter(ShaderZ, SRV);&#10; SetSRVParameter(ShaderZ, SRV);&#10; SetUAVParameter(ShaderZ, UAV);&#10; SetUAVParameter(ShaderZ, UAV);&#10;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&#10;&lt;p&gt;エンジン側の&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9"&gt;ソースコード&lt;/a&gt;を見るとシェーダ毎等で関数に分けていたため,&lt;br /&gt;&#10;そのように書き直したところビルド時間が以前と同じくらいになった.&lt;br /&gt;&#10;&lt;br /&gt;&lt;/p&gt;&#10;&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;// ビルド時間が増えないパターン.&#10;void SetParamShaderA()&#10;{&#10; SetSRVParameter(ShaderA, SRV);&#10; SetSRVParameter(ShaderA, SRV);&#10; SetUAVParameter(ShaderA, UAV);&#10; SetUAVParameter(ShaderA, UAV);&#10; ...&#10;}&#10;...&#10;void SetParamShaderZ()&#10;{&#10; SetSRVParameter(ShaderZ, SRV);&#10; SetSRVParameter(ShaderZ, SRV);&#10; SetUAVParameter(ShaderZ, UAV);&#10; SetUAVParameter(ShaderZ, UAV);&#10; ...&#10;}&#10;void MainFunc()&#10;{&#10; // Shader毎のSRV/UAV設定メソッドを記述.&#10; SetParamShaderA(...);&#10; ...&#10; SetParamShaderZ(...);&#10;}&lt;/pre&gt;&#10;&lt;p&gt;私のプロジェクトでは前者の場合 8分前後 かかっていたものが, 後者に修正したところ 1分前後 に短縮された.&lt;/p&gt;</description></item><item><title>TextureArrayに対して実行可能なDrawMaterialToRenderTargetプラグイン[UE][Plugin]</title><link>https://nagakagachi.github.io/entry/2023/01/16/080000/</link><pubDate>Mon, 16 Jan 2023 08:00:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2023/01/16/080000/</guid><description>&lt;p&gt;&lt;strong&gt;TextureRenderTarget2DArray&lt;/strong&gt; のSlice(配列の要素)を指定して &lt;strong&gt;DrawMaterialToRenderTarget&lt;/strong&gt; ができるUE&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;の公開.&lt;br /&gt;&#10;&lt;br /&gt;&#10;&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;ul&gt;&#10;&lt;li&gt;&lt;a href="#リポジトリの-NglTextureRt2dArrayUtil-をコピー"&gt;リポジトリの NglTextureRt2dArrayUtil をコピー&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#プラグインが読み込まれているか確認"&gt;プラグインが読み込まれているか確認&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;li&gt;&lt;a href="#最後"&gt;最後&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="これは何"&gt;これは何&lt;/h3&gt;&#10;&lt;p&gt;テクスチャ配列アセットの要素に対してマテリアル描画を実行できる&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;.&lt;br /&gt;&#10;UE標準のDrawMaterialToRenderTargetノードとほぼ同じで, TextureRenderTarget2DArrayとその何番目にDrawするかを指定できる.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="NglDrawMaterialToRenderTargetArraySliceノード"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/861d07799c56448bb066d90ed87790effc1e299a781ac42624bdfe1dd3f81712.png" width="635" height="420" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;NglDrawMaterialToRenderTargetArraySliceノード&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;内部で一時テクスチャの生成やコピーをする必要があったため, ゲーム中にリアルタイム利用するような用途向きではない点に注意.&lt;/p&gt;&#10;&lt;p&gt;エンジン改造無しで実装するためにこうなったが今後修正できるかもしれない(未定),&lt;/p&gt;&#10;&lt;p&gt;動作確認 UE5.1 &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Win64"&gt;Win64&lt;/a&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="リポジトリの-NglTextureRt2dArrayUtil-をコピー"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA"&gt;リポジトリ&lt;/a&gt;の NglTextureRt2dArrayUtil をコピー&lt;/h4&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/nagakagachi/ue_plugin/tree/main/distribution/NglTextureRt2dArrayUtil"&gt;ue_plugin/distribution/NglTextureRt2dArrayUtil at main &amp;middot; nagakagachi/ue_plugin &amp;middot; GitHub&lt;/a&gt;&lt;/p&gt;&lt;p&gt;自身のプロジェクトに Plugins &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リを作成し, その中に上記&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Github"&gt;Github&lt;/a&gt;の NglTextureRt2dArrayUtil &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リをコピーペーストする.&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/f2424a228885ead7b7aa13c3f7b15aff3414d42250c07db4f65015972a02007c.png" width="284" height="182" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/aca77d72e4d09e756c968b2805d1fc316bf69650a72292833f697b2076ba3d37.png" width="441" height="139" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="プラグインが読み込まれているか確認"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;が読み込まれているか確認&lt;/h4&gt;&#10;&lt;p&gt;プロジェクトを開いて 編集/&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt; のウィンドウを開き, NglTextureRt2dArrayUtil&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;が有効になっていればOK.&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/ba9a6d5dba272364ffaae21e9df37cab1595109385dec3a3c3cadd94fcc95860.png" width="882" height="460" loading="lazy" 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;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="サンプル"&gt;サンプル&lt;/h3&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;コンテンツのEditorUtilityWidget &lt;strong&gt;EUW_DrawToRenderTargetArraySample&lt;/strong&gt; を右クリック-&gt;エディターユーティリティウィジットを実行 で簡易サンプルが起動する&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/94f3c62a9e079ff9cbfadb7f2c79695b165aa870b0900170b20f7224f224d621.png" width="993" height="434" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/238bdee6dd0bf8828805c6c141ecc387c6ae3dff2355047f6878dd6bbbabdf64.png" width="1001" height="474" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;ウィンドウ左側にマテリアルと描画先Array要素番号(Slice Index)を指定.&lt;/li&gt;&#10;&lt;li&gt;ウィンドウ右側に書き込み先のTextureRTArrayアセットを指定。&lt;/li&gt;&#10;&lt;li&gt;Runボタン を押すとArray指定要素にマテリアル描画が実行される.&lt;/li&gt;&#10;&lt;/ol&gt;&lt;p&gt;下図は&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Widget"&gt;Widget&lt;/a&gt;でSlice 0番に対して実行して, エディタでTextureRTArrayの Slice 0 を表示して結果を確認している様子.&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/aaba9895685d049e9eb1dd70e574973e2883642033bf736247f8afe0a99a26ea.png" width="1200" height="646" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;出来上がったTextureRtArrayをテクスチャ配列アセットに変換するなどご自由に.&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;役にたった場合は&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Github"&gt;Github&lt;/a&gt;のStarや使ったよというメッセージを貰えると嬉しいです!&lt;/p&gt;&#10;&lt;p&gt;そもそも作った理由はエディタでマテリアルを使って自由に色々なテクスチャ配列を作りたかったため.&lt;/p&gt;&#10;&lt;p&gt;面白い使い方やもっと良い機能案があればご連絡ください.&lt;/p&gt;&#10;&lt;br /&gt;&#10;&lt;p&gt;以上&amp;hellip;&lt;/p&gt;</description></item><item><title>DepthPrepass有効時のCoplanar PolygonによるGPU負荷増大 [UE][Rendering]</title><link>https://nagakagachi.github.io/entry/2022/12/31/080000/</link><pubDate>Sat, 31 Dec 2022 08:00:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2022/12/31/080000/</guid><description>&lt;p&gt;DepthPrepass&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0"&gt;レンダリング&lt;/a&gt;に関連して, &lt;br /&gt;モデルやレベルの作りによって&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;負荷が増大してしまう特殊な状況について説明します.&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="問題"&gt;問題&lt;/h3&gt;&#10;&lt;p&gt;同一平面で重なり合うポリゴン(&lt;em&gt;Coplanar Polygon&lt;/em&gt;)は, 重なりの数だけBasePass PixelShaderが実行される可能性があります.&lt;br /&gt;&lt;u&gt;これにより本来DepthPrepass環境で除去される不要なBasePass負荷が追加で発生します.&lt;/u&gt;&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;&lt;span style="font-size: 50%;"&gt;同一平面で重なり合うポリゴン を &lt;u&gt;Coplanar Polygon&lt;/u&gt; と呼んでいます.&lt;br /&gt;Lamina Faces や Z-Fighting状態のポリゴン というような表現もあると思います.&lt;br /&gt;もっと良い呼び名があれば教えてください!&lt;/span&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;&lt;br /&gt;以下のサンプルシーンは&lt;u&gt;Opaque&lt;/u&gt;で適当ワールドノイズマテリアルのCubeをいくつか配置した状態です.&lt;br /&gt;よくOverDraw負荷が問題となる半透明が無いシーンなので安心と思いきや, 表示モードを「シェーダ複雑度」へ切り替えてみると.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="サンプルシーン"&gt;&lt;img src="images/c272dc256ecc74375b4877e418f9aece697a71c86bd6127d341d415a59f7952a.png" width="1200" height="819" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt; &lt;img src="images/a677d850b9bfe572bc8a5c7266cf9e69dddd2dcab9c69a6e33f03b69da90597a.png" width="1200" height="814" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt;&#10;&lt;figcaption&gt;サンプルシーン&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;&lt;u&gt;何故か高負荷を示す真っ白な部分があります&lt;/u&gt;.&lt;/p&gt;&#10;&lt;p&gt;RenderDocでキャプチャして 「&lt;u&gt;Quad Over Draw (Pass)&lt;/u&gt;」でOverDrawを確認します.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="RenderDoc Quad Over Draw (Pass)"&gt;&lt;img src="images/5581b84e591e4b8ad0c9549404a169faf37c5f1d03c470168dc9ee1e23b48d5a.png" width="1020" height="666" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /&gt;&#10;&lt;figcaption&gt;RenderDoc Quad Over Draw (Pass)&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;RenderDoc上でも確かに右側の配置でBasePassのOverDrawが発生しているようです.&lt;/p&gt;&#10;&lt;p&gt;BasePassではDeferredの場合はGBuffer書き込み, Forwardであれば複雑なLighting計算が実行されるため,本来実行されないはずのOpaqueでのBasePass OverDrawは&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;負荷に大きな影響を与えます.&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;この問題の原因は深度が完全に一致するポリゴンが複数重なっている点と, DepthPrepass有りBasePassの仕組みの関係によるものです.&lt;/p&gt;&#10;&lt;p&gt;まずシーンの配置ですが, 左側の配置と同じ3つのCubeをポリゴンが重なるように配置しています &lt;a href="#f-9dd25646" id="fn-9dd25646" name="fn-9dd25646" title="1モデル内のポリゴン同士でも, レベルに配置した別モデルのポリゴン同士でも関係なくこの問題は発生します."&gt;*1&lt;/a&gt;.&lt;br /&gt;&lt;img src="images/86f7777de4998b3ffd7e612339bc77651597f293595d2c33f3f21683589a12c9.png" width="1200" height="817" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt; &lt;img src="images/c48411fd5c3bc351c2e59974c39d4469d52a31f9e23dbb2a29b1f67fa3b605fb.png" width="1200" height="813" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt;&lt;/p&gt;&#10;&lt;p&gt;このような状況では, DepthPrepass有効時のBasePassは重なり合ったポリゴンそれぞれについて全て実行されてしまい, 高負荷なBasePassが何度も実行されることにより&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;負荷を増大させます.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="BasePassが複数回実行される理由"&gt;BasePassが複数回実行される理由&lt;/h3&gt;&#10;&lt;p&gt;本来のDepthPrepass手法は, DepthPreapssで先に生成したDepthBufferを頼りに, 各Meshの可視&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D4%A5%AF%A5%BB%A5%EB"&gt;ピクセル&lt;/a&gt;のマテリアルBasePass PixelShaderだけを最小限実行することで高速化するためのものです.&lt;br /&gt;例として背景, 円柱, 板で構成されたシーンのDepthPrepass有りBasePassの挙動を以下に示します.&lt;br /&gt;右側図の緑色部分がDepthTestを通過してBasePassのPixelShaderが実行された&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D4%A5%AF%A5%BB%A5%EB"&gt;ピクセル&lt;/a&gt;になります.&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;DepthPrepassでDepthBufferが完成&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;img src="images/59936b850442a7a395812d241e30d7fbdf9a56980124ad6698d1b70727d32ba8.png" width="1070" height="714" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;円柱モデルBasePass描画&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;img src="images/0a300dab9c592601ce13587e02a2a295ec8497277f6896b50f330d7bd3997ca2.png" width="1068" height="711" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt; &lt;img src="images/a43c6b573e3814646727af503df327c0499aa2723e377fab7ca90b0df466c219.png" width="1069" height="713" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;背景モデルBasePass描画&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;img src="images/a51f5fb7597a3719fb354d1e0cada8730dccd901c7346a72f6e4c0744198105a.png" width="1070" height="714" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt; &lt;img src="images/803ab8d758963f5b703032bfb6984ce851646438c5a167151baefa3f2d22dc78.png" width="1069" height="712" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;板モデルBasePass描画&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;img src="images/536d0d26f787eb50b831f285ab440bd31a185067995c2c3b24adf697416e7c76.png" width="1071" height="712" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt; &lt;img src="images/3269379750a785f5ea7673a9ba4273e00a4526ccb8514482654abfa5c4fce4ff.png" width="1070" height="712" loading="lazy" title="" class="hatena-fotolife" style="width: 250px;" itemprop="image" /&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;各モデルのBasePassが, 最終的に画面に見えている部分でだけ働いているのがわかると思います.&lt;br&gt;&#10;このようにBasePassが無駄に実行されないようにして高速化するというのがDepthPrepassの目的となります.&lt;/p&gt;&#10;&lt;p&gt;これを実現するためにBasePassは&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;DepthWrite=OFF 且つ DepthTest=GreaterEqual&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;という設定をされます &lt;a href="#f-9b586fdf" id="fn-9b586fdf" name="fn-9b586fdf" title="GreaterEqualなのはReverseZ環境でのことで, StandardZの場合はLessEqualです."&gt;*2&lt;/a&gt;.&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;&lt;span style="font-size: 80%;"&gt;指摘がありましたので追記-&amp;gt; Maskedを含めたマテリアルをDepthPrePassを利用してEarlyZ有効で効率的に描画するために Equal なDepthTestで描画する場合があります. 本件のシーンではOpaqueを対象とし且つRenderDocキャプチャ等も確認したところGreaterEqualであったためこのように記述しています(UE5.3).&lt;/span&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;この設定によって, 各モデルのBasePass描画では&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;DepthPrepassで確定した深度値に対して&lt;br /&gt;&lt;u&gt;&lt;strong&gt;同じか&lt;/strong&gt;&lt;/u&gt;それより近い場合にのみ描画する&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;という挙動をすることになります.&lt;/p&gt;&#10;&lt;p&gt;この &lt;u&gt;&lt;strong&gt;同じかそれより近い&lt;/strong&gt;&lt;/u&gt; という点と, 深度が完全に一致してしまう Coplanar Polygon の関係によって今回のような問題が起きています.&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>UE5 Geometry Script を利用した頂点単位リアルタイムアニメーション</title><link>https://nagakagachi.github.io/entry/2022/10/02/194137/</link><pubDate>Sun, 02 Oct 2022 19:41:37 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2022/10/02/194137/</guid><description>&lt;p&gt;Geometry Scriptの利用の一環で&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;入力メッシュの頂点インデックスをUV1に埋め込み、外部テクスチャに頂点座標をベイク&lt;/li&gt;&#10;&lt;li&gt;上記で生成したメッシュとテクスチャを利用してマテリアルで頂点単位バネアニメーション&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;というものを試してみました&lt;/p&gt;&#10;&lt;p&gt;&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;realtime fake secondary motion (WIP.&lt;br&gt;position, rotation, and scale operations in editor mode.&lt;br&gt;&lt;br&gt;Editorモードでの位置とスケールの操作プレビュー対応まで.&lt;br&gt;&lt;br&gt;あとプルプルしすぎていたので更に調整.&lt;a href="https://twitter.com/hashtag/UE5?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#UE5&lt;/a&gt; &lt;a href="https://t.co/xgzYPtIGpw"&gt;pic.twitter.com/xgzYPtIGpw&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/1561311962805719040?ref_src=twsrc%5Etfw"&gt;2022年8月21日&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;レベルに配置されている BP_ControllerInEditorTick を動かすとプルプルします.&lt;br /&gt;&#10;Playを実行すると物理で動くモデルがプルプルします.&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnagakagachi%2Fue4%2Ftree%2Fmaster%2Fproject%2Fsample%2FPerVtxAnimSample" title="ue4/project/sample/PerVtxAnimSample at master · nagakagachi/ue4" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://github.com/nagakagachi/ue4/tree/master/project/sample/PerVtxAnimSample"&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;ul&gt;&#10;&lt;li&gt;BP_GenerateMeshForPerVertexAnim&#10;&lt;ul&gt;&#10;&lt;li&gt;入力StaticMeshアセットから以下のようなアセットを生成する&#10;&lt;ul&gt;&#10;&lt;li&gt;UV1に頂点インデックスを埋め込んだStaticMesh&lt;/li&gt;&#10;&lt;li&gt;頂点インデックスに対応したテクセルにローカル頂点座標をベイクしたテクスチャ&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;BP_PerVertexAnimationTest&#10;&lt;ul&gt;&#10;&lt;li&gt;上記で生成したMeshとテクスチャを利用して頂点単位バネシミュレーションをマテリアル(&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;)で計算する&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;BP_ControllerInEditorTick&#10;&lt;ul&gt;&#10;&lt;li&gt;Editorモードのマニピュレータ操作でバネシミュをプレビューするためのコントローラ&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&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="プロジェクトで-Geometry-Script-プラグインを有効化"&gt;プロジェクトで Geometry Script &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;を有効化&lt;/h4&gt;&#10;&lt;p&gt;編集/&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;エディタから Geometry Script の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%A7%A5%C3%A5%AF%A5%DC%A5%C3%A5%AF%A5%B9"&gt;チェックボックス&lt;/a&gt;をONにする&lt;br /&gt;&#10;必要ならEditorの再起動をする&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/6180d11068fdae02c349a7e467eed72ac958f509a59859185abd883f9cd767a9.png" width="1200" height="297" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="PerVtxAnimWithGeometryScriptを取り込み"&gt;PerVtxAnimWithGeometryScriptを取り込み&lt;/h4&gt;&#10;&lt;p&gt;Window&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%AF%A5%B9%A5%D7%A5%ED%A1%BC%A5%E9"&gt;エクスプローラ&lt;/a&gt;上などからプロジェクトのContentフォルダにサンプルの&lt;br /&gt;&#10;PerVtxAnimWithGeometryScriptフォルダ&lt;br /&gt;&#10;をコピー&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="生成用サンプルアクター-をレベルに配置"&gt;生成用サンプルアクター をレベルに配置&lt;/h4&gt;&#10;&lt;p&gt;BP_GenerateMeshForPerVertexAnim をレベルに配置&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/30f9d9a8b24a648be093b5061ca7a42e20b81b7b61e41ca6d7e617866b48fbdc.png" width="1200" height="843" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="生成用サンプルアクターにアセットを設定"&gt;生成用サンプルアクターにアセットを設定&lt;/h4&gt;&#10;&lt;p&gt;BP_GenerateMeshForPerVertexAnimアクターに変換元Mesh, 出力先Mesh &amp; RenderTargetを設定&lt;br /&gt;&#10;Sm Src Mesh に変換元のStaticMeshを設定, 図は同梱しているウシモデル(Spot)を設定している様子&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Tex"&gt;Tex&lt;/a&gt; Bake Position Target にベイク情報を出力するRenderTargetを設定&lt;br /&gt;&#10;Sm Bake Target に変換結果のMeshを出力するStaticMeshを設定&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/a199ba136831e36a6a91fb45f179cc246799957a3bf072481fc714f27b8f6212.png" width="1200" height="671" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="アセット生成"&gt;アセット生成&lt;/h4&gt;&#10;&lt;p&gt;Geometry Scritpが駆動して Sm Bake Target と &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Tex"&gt;Tex&lt;/a&gt; Bake Position Target のアセットに生成物が保存される&lt;br /&gt;&#10;Geometry Scritpはアクターのパラメータ変更等で駆動するため, 位置の変更や Enable Regenerate Mesh のONOFF等でトリガーされる&lt;/p&gt;&lt;p&gt;Sm Bake Target にはUV1に頂点インデックスを埋め込んだStaticMeshが出力される&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Tex"&gt;Tex&lt;/a&gt; Bake Position Target には頂点インデックスに対応するテクセルに頂点座標がベイクされたテクスチャが出力される&lt;br /&gt;&#10;これらのアセットを利用してリアルタイムに頂点単位アニメーションを実現する&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/1ba5eec862176e4d55fcef6e798612f79ba89b294c3feb723d08cebe0540e1f8.png" width="448" height="326" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/438e48343ffd19bd28e794c25208bb01781560b964ac51fb8e019b669698fcc4.png" width="794" height="672" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="ランタイムサンプルアクターをレベルに配置"&gt;ランタイムサンプルアクターをレベルに配置&lt;/h4&gt;&#10;&lt;p&gt;BP_PerVertexAnimationTest は 上記アクターで生成されたメッシュとテクスチャを利用するサンプル&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/fc8bde70344bbc575f4f192547e6b9ddd8181b2cd78f0636d8a0dc0e82c46944.png" width="1200" height="864" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="ランタイムサンプルアクターにアセットを設定"&gt;ランタイムサンプルアクターにアセットを設定&lt;/h4&gt;&#10;&lt;p&gt;BP_PerVertexAnimationTest で生成されたメッシュとテクスチャをそれぞれ&lt;br /&gt;&#10;Mesh Vtx Attr Baked と &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Tex"&gt;Tex&lt;/a&gt; Vtx Attr 0 に設定&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/740c759d4da7216bb8b008e247a4e476ea1a58c0e17efb105f46bf7273ba15ae.png" width="1200" height="663" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>InstantNeRFで任意画像から3D再構成をするまでの流れメモ</title><link>https://nagakagachi.github.io/entry/2022/08/06/184349/</link><pubDate>Sat, 06 Aug 2022 18:43:49 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2022/08/06/184349/</guid><description>&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/NVIDIA"&gt;NVIDIA&lt;/a&gt; InstantNeRF (InstantNGP) の環境セットアップと,&lt;br /&gt;&#10;自身で用意した画像群を使った3D再構成をするフローのメモ.&lt;/p&gt;&lt;p&gt;基本的に公式&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA"&gt;リポジトリ&lt;/a&gt;のセットアップ手順そのまま.&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2FNVlabs%2Finstant-ngp" title="GitHub - NVlabs/instant-ngp: Instant neural graphics primitives: lightning fast NeRF and more" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://github.com/NVlabs/instant-ngp"&gt;github.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#セットアップ"&gt;セットアップ&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#実行環境"&gt;実行環境&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Requirementsのセットアップ"&gt;Requirementsのセットアップ&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#CUDA"&gt;CUDA&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#CMAKE"&gt;CMAKE&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Python"&gt;Python&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Python-Modules"&gt;Python Modules&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#OptiX"&gt;OptiX&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#InstantNgpのビルド"&gt;InstantNgpのビルド&lt;/a&gt;&lt;ul&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;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#3D再構成の準備"&gt;3D再構成の準備&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#COLMAP"&gt;COLMAP&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#ダウンロード"&gt;ダウンロード&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#環境変数Pathへの追加"&gt;環境変数Pathへの追加&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#3D再構成"&gt;3D再構成&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#画像ファイルの準備"&gt;画像ファイルの準備&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#COLMAPによる画像群カメラ姿勢推定"&gt;COLMAPによる画像群カメラ姿勢推定&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#InstantNeRFを実行"&gt;InstantNeRFを実行&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&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="実行環境"&gt;実行環境&lt;/h4&gt;&#10;&lt;p&gt;WIndows10 64bit&lt;/p&gt;&#10;&lt;p&gt;RTX 3070&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="Requirementsのセットアップ"&gt;Requirementsのセットアップ&lt;/h4&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="CUDA"&gt;CUDA&lt;/h5&gt;&#10;&lt;p&gt;"v10.2 or higher"&lt;br /&gt;&#10;11.7 をインストール.&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdeveloper.nvidia.com%2Fcuda-toolkit" title="CUDA Toolkit - Free Tools and Training" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://developer.nvidia.com/cuda-toolkit"&gt;developer.nvidia.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;</description></item><item><title>3要素ソートのメモ (3element pattern sort)</title><link>https://nagakagachi.github.io/entry/2022/05/23/212804/</link><pubDate>Mon, 23 May 2022 21:28:04 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2022/05/23/212804/</guid><description>&lt;p&gt;3要素をパターンでソート.&lt;/p&gt;&#10;&lt;p&gt;安定ソートではないことに注意.&lt;/p&gt;&#10;&lt;p&gt;&lt;span style="font-size: 80%"&gt;久しぶりの記事がこれですよ&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synComment"&gt;// パターン.&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;int&lt;/span&gt; k_sort_pattern_3[&lt;span class="synConstant"&gt;8&lt;/span&gt;][&lt;span class="synConstant"&gt;3&lt;/span&gt;]&#10;{&#10; {&lt;span class="synConstant"&gt;2&lt;/span&gt;, &lt;span class="synConstant"&gt;1&lt;/span&gt;, &lt;span class="synConstant"&gt;0&lt;/span&gt;}, &lt;span class="synComment"&gt;// 000-&amp;gt; 0&lt;/span&gt;&#10; {&lt;span class="synConstant"&gt;0&lt;/span&gt;, &lt;span class="synConstant"&gt;2&lt;/span&gt;, &lt;span class="synConstant"&gt;1&lt;/span&gt;}, &lt;span class="synComment"&gt;// 001-&amp;gt; 1&lt;/span&gt;&#10; {&lt;span class="synConstant"&gt;1&lt;/span&gt;, &lt;span class="synConstant"&gt;0&lt;/span&gt;, &lt;span class="synConstant"&gt;2&lt;/span&gt;}, &lt;span class="synComment"&gt;// 010-&amp;gt; 2&lt;/span&gt;&#10; {&lt;span class="synConstant"&gt;0&lt;/span&gt; ,&lt;span class="synConstant"&gt;1&lt;/span&gt;, &lt;span class="synConstant"&gt;2&lt;/span&gt;}, &lt;span class="synComment"&gt;// 011-&amp;gt; 3&lt;/span&gt;&#10; {&lt;span class="synConstant"&gt;2&lt;/span&gt;, &lt;span class="synConstant"&gt;1&lt;/span&gt;, &lt;span class="synConstant"&gt;0&lt;/span&gt;}, &lt;span class="synComment"&gt;// 100-&amp;gt; 4&lt;/span&gt;&#10; {&lt;span class="synConstant"&gt;2&lt;/span&gt;, &lt;span class="synConstant"&gt;0&lt;/span&gt;, &lt;span class="synConstant"&gt;1&lt;/span&gt;}, &lt;span class="synComment"&gt;// 101-&amp;gt; 5&lt;/span&gt;&#10; {&lt;span class="synConstant"&gt;1&lt;/span&gt;, &lt;span class="synConstant"&gt;2&lt;/span&gt;, &lt;span class="synConstant"&gt;0&lt;/span&gt;}, &lt;span class="synComment"&gt;// 110-&amp;gt; 6&lt;/span&gt;&#10; {&lt;span class="synConstant"&gt;0&lt;/span&gt; ,&lt;span class="synConstant"&gt;1&lt;/span&gt;, &lt;span class="synConstant"&gt;2&lt;/span&gt;}, &lt;span class="synComment"&gt;// 111-&amp;gt; 7&lt;/span&gt;&#10;};&#10;&lt;span class="synComment"&gt;// 3要素からパターンID計算.&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;auto&lt;/span&gt; get_sort_pattern_3 = [](&lt;span class="synType"&gt;const&lt;/span&gt; &lt;span class="synType"&gt;float&lt;/span&gt; (&amp;amp;ar)[&lt;span class="synConstant"&gt;3&lt;/span&gt;])&#10;{&#10; &lt;span class="synStatement"&gt;return&lt;/span&gt; ((ar[&lt;span class="synConstant"&gt;0&lt;/span&gt;] &amp;lt;= ar[&lt;span class="synConstant"&gt;1&lt;/span&gt;]) ? &lt;span class="synConstant"&gt;1&lt;/span&gt; : &lt;span class="synConstant"&gt;0&lt;/span&gt;) + ((ar[&lt;span class="synConstant"&gt;1&lt;/span&gt;] &amp;lt;= ar[&lt;span class="synConstant"&gt;2&lt;/span&gt;]) ? &lt;span class="synConstant"&gt;2&lt;/span&gt; : &lt;span class="synConstant"&gt;0&lt;/span&gt;) + ((ar[&lt;span class="synConstant"&gt;2&lt;/span&gt;] &amp;lt;= ar[&lt;span class="synConstant"&gt;0&lt;/span&gt;]) ? &lt;span class="synConstant"&gt;4&lt;/span&gt; : &lt;span class="synConstant"&gt;0&lt;/span&gt;);&#10;};&#10;&lt;p&gt;&lt;span class="synComment"&gt;// ソート対象の3要素配列.&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;float&lt;/span&gt; src[&lt;span class="synConstant"&gt;3&lt;/span&gt;] = { -&lt;span class="synConstant"&gt;3.0f&lt;/span&gt;,&lt;span class="synConstant"&gt;3.0f&lt;/span&gt;,-&lt;span class="synConstant"&gt;2.3f&lt;/span&gt; };&#10;&lt;span class="synComment"&gt;// パターンID取得.&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;int&lt;/span&gt; sort_pattern = &lt;span class="synIdentifier"&gt;get_sort_pattern_3&lt;/span&gt;(src);&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="synComment"&gt;// パターンでソート順に取り出し.&lt;/span&gt;&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;float&lt;/span&gt; sort_v0 = src[k_sort_pattern_3[sort_pattern][&lt;span class="synConstant"&gt;0&lt;/span&gt;]];&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;float&lt;/span&gt; sort_v1 = src[k_sort_pattern_3[sort_pattern][&lt;span class="synConstant"&gt;1&lt;/span&gt;]];&#10;&lt;span class="synType"&gt;constexpr&lt;/span&gt; &lt;span class="synType"&gt;float&lt;/span&gt; sort_v2 = src[k_sort_pattern_3[sort_pattern][&lt;span class="synConstant"&gt;2&lt;/span&gt;]];&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="synComment"&gt;// チェック.&lt;/span&gt;&#10;&lt;span class="synStatement"&gt;static_assert&lt;/span&gt;(sort_v0 &amp;lt;= sort_v1 &amp;amp;&amp;amp; sort_v1 &amp;lt;= sort_v2);&#10;&lt;/pre&gt;&lt;/p&gt;</description></item><item><title> TextureSampleGradのCustomNode</title><link>https://nagakagachi.github.io/entry/2021/12/31/193043/</link><pubDate>Fri, 31 Dec 2021 19:30:43 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/12/31/193043/</guid><description>&lt;p&gt;UEのマテリアルでTextureからSampleGradでサンプリングするメモ.&lt;/p&gt;&#10;&lt;p&gt;これが2021年最後の記事. 良いお年を!&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#CustomNodeの内容"&gt;CustomNodeの内容&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#CustomNodeコピペ用"&gt;CustomNodeコピペ用&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;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;ノードとしてSampleGradが提供されていないようなので、CustomNodeでSampleGrad関数を直接呼ぶこととする.&lt;/p&gt;&#10;&lt;p&gt;(提供されているようならこの記事は見なかったことにしてください.)&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="CustomNodeの内容"&gt;CustomNodeの内容&lt;/h3&gt;&#10;&lt;p&gt;TextureとUV, &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/ddx"&gt;ddx&lt;/a&gt;, ddy を引数にとって内部で TextureSampleGrad関数を利用する.&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synComment"&gt;/*&lt;/span&gt;&#10;&lt;span class="synComment"&gt; Input&lt;/span&gt;&#10;&lt;span class="synComment"&gt; InTexture ( and InTextureSampler)&lt;/span&gt;&#10;&lt;span class="synComment"&gt; InUv&lt;/span&gt;&#10;&lt;span class="synComment"&gt; InDdx&lt;/span&gt;&#10;&lt;span class="synComment"&gt; InDdy&lt;/span&gt;&#10;&lt;span class="synComment"&gt; &lt;/span&gt;&#10;&lt;span class="synComment"&gt; Output&lt;/span&gt;&#10;&lt;span class="synComment"&gt; float4&lt;/span&gt;&#10;&lt;span class="synComment"&gt;*/&lt;/span&gt;&#10;&lt;p&gt;float4 tex = &lt;span class="synIdentifier"&gt;Texture2DSampleGrad&lt;/span&gt;(InTexture, InTextureSampler, InUv, InDdx, InDdy);&#10;&lt;span class="synStatement"&gt;return&lt;/span&gt; tex;&#10;&lt;/pre&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="CustomNodeコピペ用"&gt;CustomNodeコピペ用&lt;/h3&gt;&#10;&lt;p&gt;コピペで利用したい場合は以下のテキストをマテリアルエディタに貼り付ければCustomNodeが生成される.&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&#10;Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=&lt;span class="synConstant"&gt;&amp;quot;MaterialGraphNode_21&amp;quot;&lt;/span&gt;&#10; Begin Object Class=/Script/Engine.MaterialExpressionCustom Name=&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionCustom_2&amp;quot;&lt;/span&gt;&#10; End Object&#10; Begin Object Name=&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionCustom_2&amp;quot;&lt;/span&gt;&#10; Code=&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;/*&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; Input&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; InTexture ( and InTextureSampler)&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; InUv&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; InDdx&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; InDdy&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; &lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; Output&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt; float4&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;*/&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;float4 tex = Texture2DSampleGrad(InTexture, InTextureSampler, InUv, InDdx, InDdy);&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;return tex;&lt;/span&gt;&lt;span class="synSpecial"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;&#10; OutputType=CMOT_Float4&#10; &lt;span class="synIdentifier"&gt;Inputs&lt;/span&gt;(&lt;span class="synConstant"&gt;0&lt;/span&gt;)=(InputName=&lt;span class="synConstant"&gt;&amp;quot;InTexture&amp;quot;&lt;/span&gt;,Input=(Expression=MaterialExpressionTextureObjectParameter'&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionTextureObjectParameter_1&amp;quot;&lt;/span&gt;'))&#10; &lt;span class="synIdentifier"&gt;Inputs&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;)=(InputName=&lt;span class="synConstant"&gt;&amp;quot;InUv&amp;quot;&lt;/span&gt;,Input=(Expression=MaterialExpressionReroute'&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionReroute_0&amp;quot;&lt;/span&gt;'))&#10; &lt;span class="synIdentifier"&gt;Inputs&lt;/span&gt;(&lt;span class="synConstant"&gt;2&lt;/span&gt;)=(InputName=&lt;span class="synConstant"&gt;&amp;quot;InDdx&amp;quot;&lt;/span&gt;,Input=(Expression=MaterialExpressionDDX'&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionDDX_0&amp;quot;&lt;/span&gt;'))&#10; &lt;span class="synIdentifier"&gt;Inputs&lt;/span&gt;(&lt;span class="synConstant"&gt;3&lt;/span&gt;)=(InputName=&lt;span class="synConstant"&gt;&amp;quot;InDdy&amp;quot;&lt;/span&gt;,Input=(Expression=MaterialExpressionDDY'&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionDDY_0&amp;quot;&lt;/span&gt;'))&#10; MaterialExpressionEditorX=-&lt;span class="synConstant"&gt;352&lt;/span&gt;&#10; MaterialExpressionEditorY=&lt;span class="synConstant"&gt;240&lt;/span&gt;&#10; MaterialExpressionGuid=A6C202464ABAD8F6E9734E9B54C6742D&#10; Material=PreviewMaterial'&lt;span class="synConstant"&gt;&amp;quot;/Engine/Transient.M_TexturePreview&amp;quot;&lt;/span&gt;'&#10; End Object&#10; MaterialExpression=MaterialExpressionCustom'&lt;span class="synConstant"&gt;&amp;quot;MaterialExpressionCustom_2&amp;quot;&lt;/span&gt;'&#10; NodePosX=-&lt;span class="synConstant"&gt;352&lt;/span&gt;&#10; NodePosY=&lt;span class="synConstant"&gt;240&lt;/span&gt;&#10; ErrorType=&lt;span class="synConstant"&gt;1&lt;/span&gt;&#10; ErrorMsg=&lt;span class="synConstant"&gt;&amp;quot;Custom material Custom missing input 1 (InTexture)&amp;quot;&lt;/span&gt;&#10; NodeGuid=98660A2E479B2DED7843C29DD7E144AB&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=&lt;span class="synConstant"&gt;3F&lt;/span&gt;B004F94791B89E090EB9B99B713C0F,PinName=&lt;span class="synConstant"&gt;&amp;quot;InTexture&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,LinkedTo=(MaterialGraphNode_83 FF18694A45E6BEAA46EA3F8C083A2CBC,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=3E114E314D9BAB61118B329013A0C05A,PinName=&lt;span class="synConstant"&gt;&amp;quot;InUv&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,LinkedTo=(MaterialGraphNode_Knot_7 &lt;span class="synConstant"&gt;18F&lt;/span&gt;E939F4A97C00C67CC16A085BED853,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=B5C056784D5BAD800E83398A08AD56B8,PinName=&lt;span class="synConstant"&gt;&amp;quot;InDdx&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,LinkedTo=(MaterialGraphNode_85 80EC1CDF4B3A1C9667D72EB37399E8C0,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=905889CC49E11D9C88DB2792EF254574,PinName=&lt;span class="synConstant"&gt;&amp;quot;InDdy&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,LinkedTo=(MaterialGraphNode_86 BBAD4B0443CF6057D92E17A5A0BB730A,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10; CustomProperties &lt;span class="synIdentifier"&gt;Pin &lt;/span&gt;(PinId=8EFEA7514110CC30D32E41B0B1689991,PinName=&lt;span class="synConstant"&gt;&amp;quot;Output&amp;quot;&lt;/span&gt;,PinFriendlyName=&lt;span class="synIdentifier"&gt;NSLOCTEXT&lt;/span&gt;(&lt;span class="synConstant"&gt;&amp;quot;MaterialGraphNode&amp;quot;&lt;/span&gt;, &lt;span class="synConstant"&gt;&amp;quot;Space&amp;quot;&lt;/span&gt;, &lt;span class="synConstant"&gt;&amp;quot; &amp;quot;&lt;/span&gt;),Direction=&lt;span class="synConstant"&gt;&amp;quot;EGPD_Output&amp;quot;&lt;/span&gt;,PinType.PinCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategory=&lt;span class="synConstant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;,PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,LinkedTo=(MaterialGraphNode_Root_0 1653EE4D4D08EED8A95A3CA74981CFA2,),PersistentGuid=&lt;span class="synPreProc"&gt;0&lt;/span&gt;&lt;span class="synConstant"&gt;0000000000000000000000000000000&lt;/span&gt;,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)&#10;End Object&#10;&lt;/pre&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="利用例"&gt;利用例&lt;/h3&gt;&#10;&lt;p&gt;TextureObjectとUV, &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/ddx"&gt;ddx&lt;/a&gt;, ddy をCustomNodeに入力する.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="当記事のCustomNodeの利用例"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/2e3423d49d6483a9c5d2b66d4970c02ffe9d900ccf2d17fd49f8834aaa349200.png" alt="f:id:nagakagachi:20211231190816p:plain" width="1181" height="819" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;当記事のCustomNodeの利用例&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;</description></item><item><title>RGB信号の輝度について</title><link>https://nagakagachi.github.io/entry/2021/12/14/234241/</link><pubDate>Tue, 14 Dec 2021 23:42:41 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/12/14/234241/</guid><description>&lt;p&gt;そういえば と思って調べたこと.&lt;/p&gt;&#10;&lt;p&gt;RGBの3次元ベクトルから輝度を計算するときに出てくるあの係数.&lt;/p&gt;&#10;&lt;p&gt;&lt;span style="font-size: 80%"&gt;sRGB色空間の場合&lt;/span&gt;&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(Luminance = &#10;dot(&#10;\begin{pmatrix}&#10;R_{sRGB}\\G_{sRGB}\\B_{sRGB}\\ &#10;\end{pmatrix}&#10;, &#10;&lt;p&gt;\begin{pmatrix}&#10;0.2126\0.7152\0.0722\&#10;\end{pmatrix}&#10;))&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="math-inline"&gt;\(\begin{pmatrix}&#10;0.2126\\0.7152\\0.0722\\ &#10;\end{pmatrix}\)&lt;/span&gt;&lt;br /&gt;&#10;↑これ&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;これはRGB値をその色空間(↑の場合はsRGB)からXYZ色空間へ変換する変換行列のY座標に関する成分.&lt;/p&gt;&#10;&lt;p&gt;XYZ色空間のYは輝度と定義されているため, XYZ色空間のY座標のみ計算しているということなんですね.&lt;/p&gt;&#10;&lt;br /&gt;&#10;&lt;p&gt;&lt;span class="math-inline"&gt;\(\begin{align}&#10;\begin{pmatrix}&#10;X\\Y\\Z\\ &#10;\end{pmatrix} &amp;amp;=&#10;\begin{pmatrix}&#10;0.4123908&amp;amp;0.35758434&amp;amp;0.18048079\\&#10;0.21263901&amp;amp;0.71516868&amp;amp;0.07219232\\&#10;0.01933082&amp;amp;0.11919478&amp;amp;0.95053215\\&#10;\end{pmatrix}&#10;\begin{pmatrix}&#10;R_{sRGB}\\G_{sRGB}\\B_{sRGB}\\ &#10;\end{pmatrix} \\&#10;&amp;amp;=&#10;\begin{pmatrix}&#10;0.4123908R_{sRGB}+0.35758434G_{sRGB}+0.18048079B_{sRGB}\\&#10;0.21263901R_{sRGB}+0.71516868G_{sRGB}+0.07219232B_{sRGB}\\&#10;0.01933082R_{sRGB}+0.11919478G_{sRGB}+0.95053215B_{sRGB}\\&#10;\end{pmatrix}&#10;\end{align}\)&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;↑の式では四捨五入していないので最初の式と少し違うけれど、Yはそういうこと.&lt;/p&gt;&#10;&lt;p&gt;別の色空間のRGBなら別の係数になるのも当然. 注意重点.&lt;/p&gt;&#10;&lt;br /&gt;&#10;&lt;p&gt;色空間の変換行列がたくさん乗っているページ.&lt;br /&gt;&#10;本当に正しい値かはチェックが必要だけれどとても参考になる.&lt;br /&gt;&#10;&lt;a href="http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html"&gt;Welcome to Bruce Lindbloom&amp;#39;s Web Site&lt;/a&gt;&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/3d073a5da154adc22095bc6688eaf4a54a2a82f9d0500666ae0e84a67e7ad2d0.png" alt="f:id:nagakagachi:20211215001404p:plain" width="854" height="325" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;&lt;a href="http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html"&gt;http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2021/12/14/234241"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>縮小バッファによる半透明パーティクル描画についてのメモ</title><link>https://nagakagachi.github.io/entry/2021/12/12/193138/</link><pubDate>Sun, 12 Dec 2021 19:31:38 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/12/12/193138/</guid><description>&lt;p&gt;縮小バッファに描いたものを合成するというフローについて.&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="#Lost-Planet"&gt;Lost Planet&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#METAL-GEAR-SOLID-4"&gt;METAL GEAR SOLID 4&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Tales-of-ARISE"&gt;Tales of ARISE&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="別バッファ半透明描画と直接描画の結果一致の確認"&gt;別バッファ半透明描画と直接描画の結果一致の確認&lt;/h3&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/METAL%20GEAR%20SOLID%204"&gt;METAL GEAR SOLID 4&lt;/a&gt;の記事などで紹介されている方法の確認をあらためて&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;半透明用バッファを(0,0,0,1)でクリア&lt;/li&gt;&#10;&lt;li&gt;半透明描画&#10;&lt;ul&gt;&#10;&lt;li&gt;アルファブレンドの場合&#10;&lt;ul&gt;&#10;&lt;li&gt;RGB : Dst*(1-SrcAlpha) + Src*SrcAlpha&lt;/li&gt;&#10;&lt;li&gt;Alpha: DstAlpha * (1 - SrcAlpha)&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;加算ブレンドの場合&#10;&lt;ul&gt;&#10;&lt;li&gt;RGB : Dst + Src*SrcAlpha&lt;/li&gt;&#10;&lt;li&gt;Alpha: DstAlpha&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;半透明バッファを最終合成&#10;&lt;ul&gt;&#10;&lt;li&gt;RGB : Dst * SrcAlpha + Src&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;3回の半透明描画の例で計算確認&lt;/p&gt;&#10;&lt;p&gt;c[i]はアルファ乗算済みRGB&lt;/p&gt;&#10;&lt;p&gt;a[i]は対応する出力アルファ値{ 半透明アルファ値 : アルファブレンド, 0.0 : 加算合成 }&lt;/p&gt;&#10;&lt;p&gt;としてアルファブレンドと加算合成が任意に混在するものとする&lt;/p&gt;&#10;&lt;pre class="code lang-cpp" data-lang="cpp" data-unlink&gt;&lt;span class="synComment"&gt;// c0に直接3回の合成(c1, c2, c3 の順)&lt;/span&gt;&#10;cd=c3+(c2+(c1+&lt;span class="synIdentifier"&gt;c0&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a1))(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a2))(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a3)&#10;ad=(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a0)(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a1)(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a2)(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a3)&#10;&#10;&#10;&lt;span class="synComment"&gt;// ---------------------------------------------&lt;/span&gt;&#10;&#10;&lt;span class="synComment"&gt;// cs_, as_へ3回の半透明を合成してから最後にc0と合成&lt;/span&gt;&#10;&lt;span class="synComment"&gt;// 疑似コードの通り初期値として c0=0, a0=1 とすると c1,c2,c3 の合成は&lt;/span&gt;&#10;c_temp=c3+(c2+&lt;span class="synIdentifier"&gt;c1&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a2))(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a3)&#10;a_temp=(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a1)(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a2)(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a3)&#10;&#10;&lt;span class="synComment"&gt;// c_tempをc0へ合成&lt;/span&gt;&#10;cd=c0*a_temp+c_temp&#10;=&lt;span class="synIdentifier"&gt;c0&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a1)(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a2)(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a3)+( c3+(c2+&lt;span class="synIdentifier"&gt;c1&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a2))(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a3) )&#10;=c3+(c2+(c1+&lt;span class="synIdentifier"&gt;c0&lt;/span&gt;(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a1))(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a2))(&lt;span class="synConstant"&gt;1&lt;/span&gt;-a3)&#10;&lt;/pre&gt;&#10;&lt;p&gt;c0直接合成とc_tmpを介した合成で式が一致した&lt;/p&gt;&#10;&lt;p&gt;アルファブレンドと加算合成が任意の数と順序で混在していても, 別バッファ半透明の結果は直接描画半透明と一致する(ﾟ∀ﾟ)&lt;/p&gt;&#10;&lt;p&gt;(だいぶ前の記事を整理)&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;cs=c3+(c2+(c1+c0(1-a1))(1-a2))(1-a3)&lt;br&gt;as=(1-a0)(1-a1)(1-a2)(1-a3)&lt;br&gt;&lt;br&gt;c0=0, a0=1とすると&lt;br&gt;cs_=c3+(c2+c1(1-a2))(1-a3)&lt;br&gt;as_=(1-a1)(1-a2)(1-a3)&lt;br&gt;&lt;br&gt;cdへの合成&lt;br&gt;c=cd*as_+cs_&lt;br&gt;=cd(1-a1)(1-a2)(1-a3)+( c3+(c2+c1(1-a2))(1-a3) )&lt;br&gt;=c3+(c2+(c1+cd(1-a1))(1-a2))(1-a3)&lt;br&gt;&lt;br&gt;で最初の式でc0=cdとした場合と一致&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/1468969836424609795?ref_src=twsrc%5Etfw"&gt;2021年12月9日&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt; &lt;br /&gt;&#10;&lt;br /&gt;&#10;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title> UE4マテリアルによるDistanceField生成(Jump Floodingアルゴリズム)</title><link>https://nagakagachi.github.io/entry/2021/11/07/231935/</link><pubDate>Sun, 07 Nov 2021 23:19:35 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/11/07/231935/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;2023/12/16更新&lt;br /&gt;&#10;SDF生成ツールをUE5向けに公開しました.&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;SDFテクスチャをテクスチャ2Dから生成するUE5上のツール. &lt;br&gt;別の作業のために生えてきた. Jump Floodingを&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;(マテリアル)で実行.&lt;br&gt;&lt;br&gt;入力テクスチャは黒かそうでないかで外部/内部扱いしたSDF計算. 出力は RチャンネルにUV距離, Gチャンネルに内部フラグ. MIT License &lt;a href="https://twitter.com/hashtag/UE5?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#UE5&lt;/a&gt; &lt;a href="https://t.co/6GdbEja9o3"&gt;https://t.co/6GdbEja9o3&lt;/a&gt; &lt;a href="https://t.co/ogWdxzP5Xm"&gt;pic.twitter.com/ogWdxzP5Xm&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/1730982828358390040?ref_src=twsrc%5Etfw"&gt;2023年12月2日&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;/blockquote&gt;&#10;&lt;p&gt;サンプルプロジェクト有 (&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.27).&lt;/p&gt;&lt;p&gt;Jump Flooding &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0"&gt;アルゴリズム&lt;/a&gt;によるDistanceField生成をUEマテリアルで実装したメモ.&lt;br /&gt;&#10;ついでに Editor Utility &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Widget"&gt;Widget&lt;/a&gt; でSeedテクスチャの生成とDistanceFieldの生成をトリガーするテスト.&lt;/p&gt;&lt;p&gt;Jump Flooding Algorithm (&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;)の詳細については各種資料参照.&lt;br /&gt;&#10;&lt;a href="https://www.comp.nus.edu.sg/~tants/jfa/i3d06.pdf"&gt;https://www.comp.nus.edu.sg/~tants/jfa/i3d06.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://en.wikipedia.org/wiki/Jump_flooding_algorithm"&gt;Jump flooding algorithm - Wikipedia&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://observablehq.com/@rreusser/gpu-voronoi-diagrams-using-the-jump-flooding-algorithm"&gt;GPU Voronoi Diagrams using the Jump Flooding Algorithm / Ricky Reusser | Observable&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#サンプルプロジェクト"&gt;サンプルプロジェクト&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#DistanceFieldテクスチャ生成手順"&gt;DistanceFieldテクスチャ生成手順&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#アセット説明"&gt;アセット説明&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Jump-Flooding-ステップ"&gt;Jump Flooding ステップ&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#その他"&gt;その他&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="サンプルプロジェクト"&gt;サンプルプロジェクト&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1FEnmbDwYRBIwaszz5AE0AYxZszL3f-ga/view?usp=sharing"&gt;DistanceFIeldByJFA00.zip - Google &amp;#x30C9;&amp;#x30E9;&amp;#x30A4;&amp;#x30D6;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;プロジェクトの[ThirdPersonBP/DF]に関連BPやマテリアル等がある.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="関連コンテンツフォルダ"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/01ee4bded480ce2abd6147c04de23b1413901b2a887326cf8354440d16665e4b.png" width="1200" height="683" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;関連コンテンツフォルダ&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="DistanceFieldテクスチャ生成手順"&gt;DistanceFieldテクスチャ生成手順&lt;/h4&gt;&#10;&lt;p&gt;&lt;strong&gt;EUW_JfaTestアセット&lt;/strong&gt; を右クリック-&gt;Run Editor Utility &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Widget"&gt;Widget&lt;/a&gt; で&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Widget"&gt;Widget&lt;/a&gt;を表示する.&lt;br /&gt;&#10;&lt;strong&gt;Generate Seed Texture ボタン&lt;/strong&gt; を押すとマテリアルによってSeedテクスチャが更新される.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="Generate SeedTexture"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/82eb92868758e2a8f2520e7a7580d5e0ee3378cbcf69ee53fcd3a5849db86ecc.png" width="1015" height="627" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;Generate SeedTexture&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Run &lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt; ボタン&lt;/strong&gt; を押すとSeedテクスチャを元にDistanceFieldテクスチャが生成される.&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="DistanceField生成"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/754ad1b9f0b4e013903449f9f98036a615c7b432b20a868ef78f5bbfd07613fa.png" width="932" height="615" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;Generate DistanceField&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="アセット説明"&gt;アセット説明&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;RT_Seed&#10;&lt;ul&gt;&#10;&lt;li&gt;DistanceFieldの元になるSeedテクスチャ. 黒テクセルは無効で, それ以外の色のテクセルがSeedとして評価される.&lt;/li&gt;&#10;&lt;li&gt;どんなテクスチャでもよいが,今回はマテリアルM_DistanceSeedでその場で生成している.&lt;/li&gt;&#10;&lt;li&gt;サイズはデフォルト512x512だが変更可能. ただし動作確認しているのは2の冪のみ.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;RT_Jfa0&#10;&lt;ul&gt;&#10;&lt;li&gt;DistanceFieldの出力先テクスチャ.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;M_DistanceSeed&#10;&lt;ul&gt;&#10;&lt;li&gt;Seedテクスチャの生成用マテリアル. 適当な計算で適当な位置に黒(0,0,0)ではないSeedを書き込む.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;MF_JumpFlood&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;のメイン処理をCustomNodeで記述したMaterialFunction. M_JumpFlood_SetupとM_JumpFlood_Itrはこれを呼び出す.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;M_JumpFlood_Setup&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;の初回パス用マテリアル. Seedテクスチャを元に黒(0,0,0)ではないテクセルをSeedとして&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;の初回パスを実行する.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;M_JumpFlood_Itr&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;の反復パス用マテリアル. 基本的には初回パスと同じだが,&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;入力が前回の&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;パスの結果テクスチャになる.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;M_JumpFlood_Copy&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;結果テクスチャを元に出力先テクスチャRT_Jfa0 へ出力するマテリアル.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;EUW_JfaTest&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;処理のMaterialDrawなどをする&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Widget"&gt;Widget&lt;/a&gt;. 今回の&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;関連の処理はほぼここに書いてある.&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;のワークテクスチャ(PingPong用に2枚)を内部で生成して利用する.&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/JFA"&gt;JFA&lt;/a&gt;自体はテクスチャサイズXに対して (log2(X)-1)回のマテリアルDrawで完了する.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title> MainViewのViewportSizeとカメラ位置,カメラ姿勢の取得</title><link>https://nagakagachi.github.io/entry/2021/11/06/201354/</link><pubDate>Sat, 06 Nov 2021 20:13:54 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/11/06/201354/</guid><description>&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.27で確認&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C++" data-lang="C++"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;// Get Current View Info (EditorMode, PlayMode).&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;auto&lt;/span&gt; GetCurrentViewportInfo &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; [](&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; UWorld&lt;span style="color:#ff7b72;font-weight:bold"&gt;*&lt;/span&gt; world, FVector2D&lt;span style="color:#ff7b72;font-weight:bold"&gt;&amp;amp;&lt;/span&gt; out_viewport_size, FVector&lt;span style="color:#ff7b72;font-weight:bold"&gt;&amp;amp;&lt;/span&gt; out_view_location, FQuat&lt;span style="color:#ff7b72;font-weight:bold"&gt;&amp;amp;&lt;/span&gt; out_view_quat)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;if&lt;/span&gt; (&lt;span style="color:#ff7b72;font-weight:bold"&gt;!&lt;/span&gt;world)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;return&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-weight:bold;font-style:italic"&gt;#if WITH_EDITOR&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;if&lt;/span&gt; (world&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;WorldType &lt;span style="color:#ff7b72;font-weight:bold"&gt;==&lt;/span&gt; EWorldType&lt;span style="color:#ff7b72;font-weight:bold"&gt;::&lt;/span&gt;Editor &lt;span style="color:#ff7b72;font-weight:bold"&gt;||&lt;/span&gt; world&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;WorldType &lt;span style="color:#ff7b72;font-weight:bold"&gt;==&lt;/span&gt; EWorldType&lt;span style="color:#ff7b72;font-weight:bold"&gt;::&lt;/span&gt;EditorPreview)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8b949e;font-style:italic"&gt;// EditorMode.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8b949e;font-style:italic"&gt;// Use First Editor Viewport.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;for&lt;/span&gt; (FLevelEditorViewportClient&lt;span style="color:#ff7b72;font-weight:bold"&gt;*&lt;/span&gt; &lt;span style="color:#79c0ff;font-weight:bold"&gt;level_viewport_clients&lt;/span&gt; : GEditor&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GetLevelViewportClients())&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;if&lt;/span&gt; (level_viewport_clients &lt;span style="color:#ff7b72;font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; level_viewport_clients&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;IsPerspective())&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; out_viewport_size &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; level_viewport_clients&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;Viewport&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GetSizeXY();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; out_view_location &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; level_viewport_clients&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GetViewLocation();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; out_view_quat &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; level_viewport_clients&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GetViewRotation().Quaternion();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;break&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;else&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-weight:bold;font-style:italic"&gt;#endif&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8b949e;font-style:italic"&gt;// Non EditorMode.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8b949e;font-style:italic"&gt;// Use First PlayerCamera.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;if&lt;/span&gt; (&lt;span style="color:#ff7b72"&gt;auto&lt;/span&gt;&lt;span style="color:#ff7b72;font-weight:bold"&gt;*&lt;/span&gt; camera_manager &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; UGameplayStatics&lt;span style="color:#ff7b72;font-weight:bold"&gt;::&lt;/span&gt;GetPlayerCameraManager(world, &lt;span style="color:#a5d6ff"&gt;0&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GEngine&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GameViewport&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GetViewportSize(out_viewport_size);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; out_view_location &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; camera_manager&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GetCameraLocation();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; out_view_quat &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; camera_manager&lt;span style="color:#ff7b72;font-weight:bold"&gt;-&amp;gt;&lt;/span&gt;GetCameraRotation().Quaternion();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff7b72"&gt;return&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; UWorld&lt;span style="color:#ff7b72;font-weight:bold"&gt;*&lt;/span&gt; world &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; [&lt;span style="color:#f85149"&gt;ワールド&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FVector2D out_viewport_size;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FVector out_view_location;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FQuat out_view_quat;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;// Get Info.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GetCurrentViewportInfo(world, out_viewport_size, out_view_location, out_view_quat);&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2021/11/06/201354"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>TechBlogリンクメモ</title><link>https://nagakagachi.github.io/entry/2021/09/17/235406/</link><pubDate>Fri, 17 Sep 2021 23:54:06 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/09/17/235406/</guid><description>&lt;p&gt;海外ゲームスタジオやR&amp;D系のTechBlog系リンク.&lt;br /&gt;&#10;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Twitter"&gt;Twitter&lt;/a&gt;だと後で見るのが不便(以下略).&lt;br /&gt;&#10;見つけられたものを列挙しているだけなので選出に特に理由は無い.&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#Activision"&gt;Activision&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Amazon"&gt;Amazon&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Bungie"&gt;Bungie&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#The-Coalition-Studio"&gt;The Coalition Studio&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Electronic-Arts"&gt;Electronic Arts&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Epic-Games"&gt;Epic Games&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Embark-Studios"&gt;Embark Studios&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Godot"&gt;Godot&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Guerrilla-Games"&gt;Guerrilla Games&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Microsoft"&gt;Microsoft&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Naughty-Dog"&gt;Naughty Dog&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Our-Machinery"&gt;Our Machinery&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Playstation"&gt;Playstation&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Riot-Games"&gt;Riot Games&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Ready-at-Dawn"&gt;Ready at Dawn&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Roblox"&gt;Roblox&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Traverse-Research"&gt;Traverse Research&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Treyarch"&gt;Treyarch&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Ubisoft"&gt;Ubisoft&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Unigine"&gt;Unigine&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Unity"&gt;Unity&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;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Activision"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Activision"&gt;Activision&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://research.activision.com/"&gt;Activision Research | Home&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Amazon"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Amazon"&gt;Amazon&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://aws.amazon.com/jp/blogs/gametech/"&gt;AWS for Games Blog&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Bungie"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Bungie"&gt;Bungie&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.bungie.net/en/BungieTech/Index"&gt;Bungie Tech Blog | Bungie.net&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="The-Coalition-Studio"&gt;The Coalition Studio&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.thecoalitionstudio.com/news"&gt;The Coalition Studio | News&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Electronic-Arts"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Electronic%20Arts"&gt;Electronic Arts&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.ea.com/technology"&gt;EA - Research &amp;amp; Technology&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.ea.com/frostbite/news#all"&gt;The latest News &amp;amp; updates from our Game Developers - Frostbite&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.ea.com/seed"&gt;SEED - Official Website&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Epic-Games"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Epic%20Games"&gt;Epic Games&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.unrealengine.com/en-US/feed/tech-blog?sessionInvalidated=true&amp;lang=en-US"&gt;Unreal Engine Tech | Discover How Engineers Use UE&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Embark-Studios"&gt;Embark Studios&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://medium.com/embarkstudios"&gt;Embark Studios &amp;ndash; Medium&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Godot"&gt;Godot&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://godotengine.org/devblog"&gt;Redirecting&amp;hellip;&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Guerrilla-Games"&gt;Guerrilla Games&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.guerrilla-games.com/read/publications"&gt;Newsfeed - Guerrilla Games&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Microsoft"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Microsoft"&gt;Microsoft&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://developer.microsoft.com/ja-jp/games/blog/"&gt;Articles&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Naughty-Dog"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Naughty%20Dog"&gt;Naughty Dog&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.naughtydog.com/research"&gt;Research || Naughty Dog&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Our-Machinery"&gt;Our Machinery&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://ourmachinery.com/post/"&gt;https://ourmachinery.com/post/&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Playstation"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Playstation"&gt;Playstation&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://blog.playstation.com/"&gt;PlayStation.Blog &amp;ndash; Official PlayStation Blog for news and video updates on PlayStation, PS5, PS4, PS VR, PlayStation Plus and more.&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Riot-Games"&gt;Riot Games&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://technology.riotgames.com/"&gt;Riot Games Technology&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Ready-at-Dawn"&gt;Ready at Dawn&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://medium.com/ready-at-dawn/dev-talks/home"&gt;Dev Talks &amp;ndash; Ready At Dawn &amp;ndash; Medium&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Roblox"&gt;Roblox&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://blog.roblox.com/category/product-tech/"&gt;Product &amp;amp; Tech Archive - Roblox Blog&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Traverse-Research"&gt;Traverse Research&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://blog.traverseresearch.nl/"&gt;Traverse Research&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Treyarch"&gt;Treyarch&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.treyarch.com/blog"&gt;Treyarch - Blog&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Ubisoft"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/Ubisoft"&gt;Ubisoft&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://montreal.ubisoft.com/en/tech-blog/"&gt;Tech blog - Ubisoft Montr&amp;eacute;al&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.ubisoft.com/en-us/studio/laforge/news/"&gt;Ubisoft La Forge News | Ubisoft&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Unigine"&gt;Unigine&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://unigine.com/blog/"&gt;UNIGINE Blog &amp;ndash; UNIGINE articles and blogs by team&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Unity"&gt;Unity&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt; &lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;&lt;a href="https://blog.unity.com/"&gt;Welcome to Unity | Unity Blog&lt;/a&gt;&lt;br /&gt;&#10;&lt;/p&gt;</description></item><item><title>ProjectRoot直下のShadersディレクトリをShaderIncludePathに追加するだけのPlugin [UE4]</title><link>https://nagakagachi.github.io/entry/2021/08/18/083000/</link><pubDate>Wed, 18 Aug 2021 08:30:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/08/18/083000/</guid><description>&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;/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;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="これはなに"&gt;これはなに&lt;/h3&gt;&#10;&lt;p&gt;プロジェクトルート/Shaders をUEのShaderIncludePathに自動追加する&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;.&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.25辺りからマテリアルのCustomノードで Include File Paths を指定して外部シェーダファイルをインクルードして利用できるようになったが,インクルードパスの設定が面倒だったので勉強ついでに自分用自動化&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;を作成した.&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;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnagakagachi%2Fue4%2Ftree%2Fmaster%2FPlugin%2FNglShaderIncludePlugin" title="ue4/Plugin/NglShaderIncludePlugin at master · 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/tree/master/Plugin/NglShaderIncludePlugin"&gt;github.com&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;&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;1. &lt;b&gt;zipを解凍してできたNglShaderIncludePluginを ProjectRoot/Plugins にコピー.&lt;/b&gt;&lt;br /&gt;&#10;2. &lt;b&gt;ProjectRoot/Shaders &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リにCustomノードで使いたい ush を配置.&lt;/b&gt;&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;// テストで用意した IncludeTest.ush というファイル&#10;#pragma once&#10;float3 Func00()&#10;{&#10; return float3(1.0, 0.0, 0.0);&#10;}&lt;/pre&gt;&lt;p&gt;3. &lt;b&gt;マテリアルのCustomノードの Include File Paths に "/Project/filename.ush" を入力.&lt;/b&gt;&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="Customノード例"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/6f671447c4dd4e8b946a6de2ed046a4bd43542906b659231433e4b9ef528501e.png" alt="f:id:nagakagachi:20210818012316p:plain" width="1039" height="876" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;Customノード例&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;4. &lt;b&gt;Customノードでインクルードしたushの関数などが利用できるようになる. &lt;/b&gt;&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;UEプロジェクト起動時に Shaders &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リが存在しないと以下のような警告がログに出力されるので&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リを作成するように.&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;LogTemp: Warning: [FNglShaderIncludePluginModule] directory [ProjectRoot/Shaders] does not exist.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/39be8a695b54791eb55ea1e611245b63bc991cc35fac0710945f927fd9ece0dc.png" alt="f:id:nagakagachi:20210818003947p:plain" width="1080" height="429" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>Physics Simulation 資料メモ</title><link>https://nagakagachi.github.io/entry/2021/08/12/223702/</link><pubDate>Thu, 12 Aug 2021 22:37:02 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/08/12/223702/</guid><description>&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter"&gt;Twitter&lt;/a&gt;ではあとから探すのが大変なためこちらにまとめる.&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="constraints-derivation-for-rigid-body-simulation-in-3d"&gt;Constraints Derivation for Rigid Body Simulation in 3D&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Daniel Chappuis,&lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;&lt;a href="https://danielchappuis.ch/download/ConstraintsDerivationRigidBody3D.pdf"&gt;https://danielchappuis.ch/download/ConstraintsDerivationRigidBody3D.pdf&lt;/a&gt;&lt;br /&gt;&#10;拘束力の定義から丁寧に式変形をしていてわかりやすい.&lt;br /&gt;&#10;2剛体の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%BE%F5%C2%D6%A5%D9%A5%AF%A5%C8%A5%EB"&gt;状態ベクトル&lt;/a&gt;( &lt;span class="math-inline"&gt;\(R^{14}\)&lt;/span&gt; )と変位ベクトル( &lt;span class="math-inline"&gt;\(R^{14}\)&lt;/span&gt; )の回転成分はQuaternionで表現.&lt;br /&gt;&#10;2剛体の速度ベクトル( &lt;span class="math-inline"&gt;\(R^{12}\)&lt;/span&gt; )の回転成分は角速度ベクトルで表現.&lt;br /&gt;&#10;変位ベクトルと速度ベクトルの回転成分の表現の差異やそれを考慮した変形についても説明がある.&lt;br /&gt;&#10;Ball-And-Socket-JointやHinge-Joint等、各種のジョイント系の拘束条件やそのJacobianの導出の説明がある.&lt;br /&gt;&#10;Baumgarte Stabilizationの項の追加有り.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="3d-constraint-derivations-for-impulse-solvers-july-1-2015-v100"&gt;3D Constraint Derivations for Impulse Solvers (July 1, 2015 v1.00)&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Marijn Tamis,&lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.mft-spirit.nl/files/MTamis_Constraints.pdf"&gt;http://www.mft-spirit.nl/files/MTamis_Constraints.pdf&lt;/a&gt;&lt;br /&gt;&#10;Point DIstanse, Contact, Hinge, Quaternion Constraint等多数の拘束条件とそのJacobianが記載されている.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="constraint-based-physics-solver-june-15-2015-v102"&gt;Constraint based physics solver (June 15, 2015 (v1.02))&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Marijn Tamis, Giuseppe Maggiore,&lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://mft-spirit.nl/files/MTamis_ConstraintBasedPhysicsSolver.pdf"&gt;http://mft-spirit.nl/files/MTamis_ConstraintBasedPhysicsSolver.pdf&lt;/a&gt;&lt;br /&gt;&#10;Contact Constraint や Distance Constraint 等のシンプルな拘束についてはこちらがわかりやすいかもしれない.&lt;br /&gt;&#10;Baumgarte Stabilizationの項の追加有り.&lt;br /&gt;&#10;反復ソルバの Projected Gauss-Seidel の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BC%BB%F7%A5%B3%A1%BC%A5%C9"&gt;擬似コード&lt;/a&gt;有り.&lt;br /&gt;&#10;&lt;span style="font-size: 80%"&gt;ただしDistance ConstraintのLinearVelocityに対応する部分が正規化ベクトルになっていない点が少々怪しい気がする.&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>行優先と列優先のはなし(row-major, column-major)</title><link>https://nagakagachi.github.io/entry/2021/07/02/213944/</link><pubDate>Fri, 02 Jul 2021 21:39:44 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2021/07/02/213944/</guid><description>&lt;p&gt;今ひとつ完全理解に至っていなかったので自分の言葉で残しておく&lt;br /&gt;&#10;間違ってたら&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%CD%C5%C0%BA%A4%B5%A4%F3"&gt;妖精さん&lt;/a&gt;が直してくれる&lt;/p&gt;&lt;p&gt;(WEB上にたくさんある有用な記事を読んでわかる方は当記事をこれ以上読む必要は無い)&lt;br /&gt;&#10;&lt;a href="https://docs.microsoft.com/ja-jp/windows/win32/direct3dhlsl/dx-graphics-hlsl-per-component-math"&gt;Per-Component &amp;#x7B97;&amp;#x8853;&amp;#x6F14;&amp;#x7B97; - Win32 apps | Microsoft Learn&lt;/a&gt;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="行列の要素と演算"&gt;行列の要素と演算&lt;/h3&gt;&#10;&lt;p&gt;行列の行と列の意味や行列要素の位置はrow-majorでもcolumn-majorでも変わることはない&lt;/p&gt;&#10;&lt;p&gt;行とは行列の横方向のラインであるし、列は縦方向のラインである&lt;/p&gt;&#10;&lt;p&gt;mat._11は1行目1列目の要素であり、mat._42は4行目2列目の要素である&lt;/p&gt;&#10;&lt;p&gt;行列とベクトルの乗算のルールもrow-majorでもcolumn-majorで変わることはない&lt;/p&gt;&#10;&lt;p&gt;(ただしHLSL等ではベクトルは演算の位置によって適宜列ベクトルや行ベクトルに読み替えられる)&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;V1 = M * V0; // Matrix4x4とVec4&lt;/pre&gt;&#10;&lt;p&gt;は&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;V1.x = M._11 * V0.x + M._12 * V0.y + M._13 * V0.y + M._14 * V0.w&#10;V1.y = M._21 * V0.x + M._22 * V0.y + M._23 * V0.y + M._24 * V0.w&#10;V1.z = M._31 * V0.x + M._32 * V0.y + M._33 * V0.y + M._34 * V0.w&#10;V1.w = M._41 * V0.x + M._42 * V0.y + M._43 * V0.y + M._44 * V0.w&lt;/pre&gt;&#10;&lt;p&gt;であり、&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;V1 = V0 * M; // Matrix4x4とVec4&lt;/pre&gt;&#10;&lt;p&gt;は&lt;/p&gt;&#10;&lt;pre class="code c++" data-lang="c++" data-unlink&gt;V1.x = M._11 * V0.x + M._21 * V0.y + M._31 * V0.y + M._41 * V0.w&#10;V1.y = M._12 * V0.x + M._22 * V0.y + M._32 * V0.y + M._42 * V0.w&#10;V1.z = M._13 * V0.x + M._23 * V0.y + M._33 * V0.y + M._43 * V0.w&#10;V1.w = M._14 * V0.x + M._24 * V0.y + M._34 * V0.y + M._44 * V0.w&lt;/pre&gt;&#10;&lt;p&gt;である&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title> InstancedStaticMeshとCustomDataとTextureで大量オブジェクト (UE4 Advent Calendar 2020)</title><link>https://nagakagachi.github.io/entry/UE4_AdventCalendar2020_a/</link><pubDate>Tue, 15 Dec 2020 00:05:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/UE4_AdventCalendar2020_a/</guid><description>&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt; AdventCalendar2020 15日目の記事となります&lt;br /&gt;&#10;&lt;a href="https://qiita.com/advent-calendar/2020/ue4"&gt;Unreal Engine 4 (UE4) Advent Calendar 2020 - Qiita&lt;/a&gt;&lt;/p&gt;&lt;p&gt;サンプルプロジェクトは以下(&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.26)&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnagakagachi%2Fue4%2Ftree%2Fmaster%2Fproject%2Fsample%2FStatefulInstancedMesh" title="ue4/project/sample/StatefulInstancedMesh at master · 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/tree/master/project/sample/StatefulInstancedMesh"&gt;github.com&lt;/a&gt;&lt;/cite&gt;&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="#CustomData"&gt;CustomData&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#CanvasObject"&gt;CanvasObject&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#TextureRenderTarget2Dの準備"&gt;TextureRenderTarget2Dの準備&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#InstancedStaticMeshComponentの設定"&gt;InstancedStaticMeshComponentの設定&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Instance番号をCustomDataに設定"&gt;Instance番号をCustomDataに設定&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Instanceの基準位置をテクスチャに書き込み"&gt;Instanceの基準位置をテクスチャに書き込み&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;/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;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="やりたいこと"&gt;やりたいこと&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;大量の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9"&gt;インスタンス&lt;/a&gt;メッシュについて個別のパラメータをBPからマテリアルへ渡す&lt;/li&gt;&#10;&lt;li&gt;大量の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9"&gt;インスタンス&lt;/a&gt;メッシュのパラメータ更新を&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GPGPU"&gt;GPGPU&lt;/a&gt;(マテリアル)で高速に実行する&lt;/li&gt;&#10;&lt;li&gt;BPのみでつくる (&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/C%2B%2B"&gt;C++&lt;/a&gt;つかわない)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;このような要素を含んだデモとして以下のようなサンプルを作成しました。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;基準位置とバネで接続された物体のシミュレーション&#10;&lt;ul&gt;&#10;&lt;li&gt;バネによる速度の変化&lt;/li&gt;&#10;&lt;li&gt;速度による位置の変化&lt;/li&gt;&#10;&lt;li&gt;プレイヤーとのインタ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%AF"&gt;ラク&lt;/a&gt;ション&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/2CmtMvd89KA?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://youtu.be/2CmtMvd89KA"&gt;youtu.be&lt;/a&gt;&lt;/cite&gt; &lt;br /&gt;&#10;&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/2dWGmIMSwSg?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://youtu.be/2dWGmIMSwSg"&gt;youtu.be&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;以降の説明は基本的にこのデモをベースにしていきます。&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;今回紹介する方法は大まかに以下のような流れになります。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;InstancedStaticMeshのCustomDataにInstance番号を設定する&lt;/li&gt;&#10;&lt;li&gt;テクスチャを配列データに見立ててInstanceパラメータを格納する&lt;/li&gt;&#10;&lt;li&gt;Instanceパラメータテクスチャをマテリアルで更新する&lt;/li&gt;&#10;&lt;li&gt;マテリアルでInstance番号に対応したパラメータをテクスチャから取得して使う&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;</description></item><item><title>論文メモ Fast Eulerian Fluid Simulation In Games Using Poisson Filters (SCA 2020 Showcase)</title><link>https://nagakagachi.github.io/entry/2020/12/10/222911/</link><pubDate>Thu, 10 Dec 2020 22:29:11 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/12/10/222911/</guid><description>&lt;p&gt;&lt;iframe width="480" height="270" src="https://www.youtube.com/embed/_3eyPUyqluc?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=_3eyPUyqluc"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="概要"&gt;概要&lt;/h3&gt;&#10;&lt;p&gt;2次元Euler流体を用いた&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/2.5%BC%A1%B8%B5"&gt;2.5次元&lt;/a&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%E9%A5%AF%A5%C6%A5%A3%A5%D6"&gt;インタラクティブ&lt;/a&gt;流体エフェクトに関するShowcase。&lt;br /&gt;&#10;圧力Poisson方程式のJacobi法ソルバの反復数を大幅に削減し高速化するPoisson (Separable) Filterを提案。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="poisson-filter"&gt;Poisson Filter&lt;/h3&gt;&#10;&lt;p&gt;圧力Poisson方程式のJacobi反復は、前回の反復での圧力値に対して&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2"&gt;再帰&lt;/a&gt;的に定数フィルタ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/3x3"&gt;3x3&lt;/a&gt;をかけ合わせているものとみなせる(3次元なら3x3x3)。&lt;br /&gt;&#10;N回のJacobi反復を1回の畳み込みフィルタに解析的に変換することで反復数を削減することができる。&lt;br /&gt;&#10;事前計算でこの畳込みフィルタを求めておくことでランタイムでの圧力反復計算を大幅に高速化する。&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="引用1"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/b782c0befaec31ac9c69e592d0eb8c01c4c9c2a9f2c0a96e90194ce7f72bfd6a.png" alt="f:id:nagakagachi:20201210213053p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;引用1&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;近傍の初期値にN回のフィルタを掛けた結果とおなじになるようなフィルタを事前計算して利用するということ。&lt;/p&gt;&#10;&lt;p&gt;定数重みを掛けて足し合わせるフィルタをN回掛けた場合の、近傍初期値の足し合わせ重みは地道に手計算することでも確認ができそう。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="poisson-separable-filter"&gt;Poisson Separable Filter&lt;/h3&gt;&#10;&lt;p&gt;畳み込みフィルタ化によって反復数を1回にすることができるが、N回分をまとめたことにより広範囲をサンプリングするフィルタとなり、計算量は非常に多くなってしまう。&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/canonical"&gt;canonical&lt;/a&gt; polyadic decomposition (CPD) でRank1のMatrixの和に変換し、それぞれを&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C6%C3%B0%DB%C3%CD%CA%AC%B2%F2"&gt;特異値分解&lt;/a&gt;(SVD)で Nx1. 1x1, 1xN の行列積に変換する(1x1は特異値(Scalar)になる)。&lt;br /&gt;&#10;ここで特異値が最大のものだけを選ぶことで、元の行列の性質をある程度残しながらNx1と1xNの縦横に分離された Poisson Separable Filter が得られる。 &lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="引用"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/217cc2d9a48813d6d84aeea3158513deedd331d69cd4a89ea9f75d7b27f63c25.png" alt="f:id:nagakagachi:20201210220549p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;引用&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;このようにして得られた Filter は Total variance explained が83%以下にはならないらしい(これが元の性質をある程度残しているということ？)&lt;/p&gt;&#10;&lt;p&gt;このフィルタは中心部から離れた要素の重みが小さいため、それらを切り捨てることでさらにフィルタサイズを小さくすることができる(~80% redundant)。&lt;/p&gt;&#10;&lt;p&gt;また、重みが対称的であるため実際に必要とする重みデータは更に圧縮することができる。&lt;/p&gt;&#10;&lt;p&gt;反復数が1回になったこととフィルタサイズの削減により、反復数が小さい場合には4.5倍、100反復では30倍程度高速化することができた。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="25dシミュレーション"&gt;2.5Dシミュレーション&lt;/h3&gt;&#10;&lt;p&gt;シミュレーションは2D-Gridで実行しているが、カメラの向きに応じて高さや傾きを補正することであたかも3D空間でシミュレーションされているようにみせている。&lt;/p&gt;&#10;&lt;p&gt;外力や風は3Dから2Dへ投影することでシミュレーションに取り込まれる。&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="引用"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/54cee14cd29fac87afde0b55f0ac6e03de8026fe4ddc5f71f724ba734607f985.png" alt="f:id:nagakagachi:20201210221945p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;引用&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="figure-image figure-image-fotolife" title="引用"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/a49ca8b5a4257e077e7293d128ae6f69a50009e48543b3b6f69cfb89de1a2c31.png" alt="f:id:nagakagachi:20201210222014p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;引用&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;3Dオブジェクトとの&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%EA%A5%B8%A5%E7%A5%F3"&gt;コリジョン&lt;/a&gt;は深度バッファベースの手法を利用している。&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;マスク画像によって炎や煙の生成部をコン&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB"&gt;トロール&lt;/a&gt;する。&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="引用"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/23e8b92c76ef118a0333d8f1e6e2c061449485d3530e447175ab27a3380df42f.png" alt="f:id:nagakagachi:20201210222216p:plain" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;引用&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="what-is-next"&gt;What is Next?&lt;/h3&gt;&#10;&lt;p&gt;Poisson Filterの3次元への拡張&lt;br /&gt;&#10;Multi-Runk + Rank Selector ( 負荷と品質の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%EC%A1%BC%A5%C9%A5%AA%A5%D5"&gt;トレードオフ&lt;/a&gt;ができるように )&lt;br /&gt;&#10;粘性拡散項への対応&lt;br /&gt;&#10;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>Voxel Mesh化手法についてメモ( Voxel Meshing )</title><link>https://nagakagachi.github.io/entry/2020/08/22/180515/</link><pubDate>Sat, 22 Aug 2020 18:05:15 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/08/22/180515/</guid><description>&lt;p&gt;SDFなどのVoxelからMeshを生成する手法のメモ。&lt;/p&gt;&#10;&lt;p&gt;もとのSDFのセルと、Mesh化で管理されるVoxelは一致しないので注意。&lt;/p&gt;&#10;&lt;p&gt;もとのSDFのセル中心を頂点とするようなVoxel上でMesh化が実行される。&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="marching--cubes"&gt;Marching Cubes&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="http://paulbourke.net/geometry/polygonise/"&gt;Polygonising a scalar field (Marching Cubes)&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Voxelの頂点のパターンからそのVoxelのポリゴンパターンをLookupしてMesh化する。&lt;/p&gt;&#10;&lt;p&gt;シャープな形状が作りにくいらしい。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="dual-contour"&gt;Dual Contour&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://people.eecs.berkeley.edu/~jrs/meshpapers/SchaeferWarren2.pdf"&gt;https://people.eecs.berkeley.edu/~jrs/meshpapers/SchaeferWarren2.pdf&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;あるVoxelを構成する辺について、SDFをの符号が異なる両端を持つ辺に注目し、辺を横切るような等値面の交差位置と法線をSDFの勾配等から計算する。&lt;/p&gt;&#10;&lt;p&gt;一つのVoxelについて境界面は複数存在する可能性があり、すべての境界面からの距離の自乗和が最小になるような一点をそのVoxel内の頂点として最小二乗法で推定する。&lt;/p&gt;&#10;&lt;p&gt;すべてのVoxelについて上記の点を計算し、隣接Cellで点同士をつなげてMeshを構成する。&lt;/p&gt;&#10;&lt;p&gt;シャープな形状を作ることができるらしい。&lt;/p&gt;&#10;&lt;p&gt;Voxel毎に最小二乗法を解く必要があるためコストが高い可能性。&lt;/p&gt;&#10;&lt;p&gt;また自己交差メッシュができてしまう可能性もある。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="surfacenets"&gt;SurfaceNets&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://www.merl.com/publications/docs/TR99-24.pdf"&gt;https://www.merl.com/publications/docs/TR99-24.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://medium.com/@bonsairobo/smooth-voxel-mapping-a-technical-deep-dive-on-real-time-surface-nets-and-texturing-ef06d0f8ca14"&gt;Smooth Voxel Mapping: a Technical Deep Dive on Real-time Surface Nets and Texturing | by DreamCat Games | Aug, 2020 | Medium&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://github.com/TomaszFoster/NaiveSurfaceNets/blob/master/NaiveSurfaceNets.cs"&gt;NaiveSurfaceNets/NaiveSurfaceNets.cs at master &amp;middot; TomaszFoster/NaiveSurfaceNets &amp;middot; GitHub&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;Meshを構成するVoxel内の頂点を推定することはDual Contourと同様だが、複数ある辺と等値面の交差位置を平均した地点を頂点位置とするところが異なる。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2020/08/22/180515"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>UNREAL FEST EXTREME 2020 SUMMERメモ</title><link>https://nagakagachi.github.io/entry/2020/07/18/180917/</link><pubDate>Sat, 18 Jul 2020 18:09:17 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/07/18/180917/</guid><description>&lt;p&gt;メモです&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#猫でもわかるControl-Rig---UE425版--"&gt;猫でもわかるControl Rig - UE4.25版 -&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#いままでのアニメーションワークフローでは"&gt;いままでのアニメーションワークフローでは&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Control-RIgなら"&gt;Control RIgなら&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#AnimationBPとちがうの"&gt;AnimationBPとちがうの？&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="#アセット作成"&gt;アセット作成&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Epic-Online-Services-でできること"&gt;Epic Online Services でできること&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#全部知ってたらTwinmotionマスターTwinmotionのぷちTipsテクニック"&gt;全部知ってたらTwinmotionマスター！TwinmotionのぷちTips・テクニック&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#Twinmotionとは"&gt;Twinmotionとは&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#user-library"&gt;user library&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="#Auto-Save"&gt;Auto Save&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Grass-Fading"&gt;Grass Fading&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="#Reflection-Probes"&gt;Reflection Probes&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Reflection-Volume-Resolution"&gt;Reflection Volume Resolution&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Custom-PathとParticle"&gt;Custom PathとParticle&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Angle-Snap"&gt;Angle Snap&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#viewsのレンダリング"&gt;viewsのレンダリング&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;/li&gt;&#10;&lt;li&gt;&lt;a href="#Bookmark"&gt;Bookmark&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="#shadowの設定"&gt;shadowの設定&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#viewportで操作"&gt;viewportで操作&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#carガチャリセマラ"&gt;carガチャ(リセマラ)&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="#presenter昨日をpadで"&gt;presenter昨日をpadで&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#UE4エンタープライズコンテンツを制作する際のワークフロー-Cutting-Edge-Test-Driveを題材に"&gt;UE4エンタープライズコンテンツを制作する際のワークフロー ～Cutting-Edge Test Driveを題材に～&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#用語"&gt;用語&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#UE4の利用用途"&gt;UE4の利用用途&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="#インタラクティブコンテンツ系"&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;/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;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="#要件定義フェイズ"&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;/li&gt;&#10;&lt;li&gt;&lt;a href="#詰め"&gt;詰め&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;ul&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="#シミュレーション系-1"&gt;シミュレーション系&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#これからUE4を始める方へ"&gt;これからUE4を始める方へ&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#質疑"&gt;質疑&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Bloodstainedで世界のバッカーの期待に応えたUE4事例紹介"&gt;Bloodstainedで世界のバッカーの期待に応えたUE4事例紹介&lt;/a&gt;&lt;ul&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="#60fpsのためにしたこと"&gt;60fpsのためにしたこと&lt;/a&gt;&lt;ul&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;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#途中経過を報告しつつ1600個の画面を輪繰内品質に"&gt;途中経過を報告しつつ1600個の画面を輪繰内品質に&lt;/a&gt;&lt;ul&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;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Unreal-Engine-4-で広大な世界を構築する際にひそむ罠"&gt;Unreal Engine 4 で広大な世界を構築する際にひそむ罠&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#共通アセットを探し出す"&gt;共通アセットを探し出す&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="猫でもわかるControl-Rig---UE425版--"&gt;猫でもわかるControl Rig - &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.25版 -&lt;/h3&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8"&gt;スクリプト&lt;/a&gt;可能なリギングシステム&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="いままでのアニメーションワークフローでは"&gt;いままでのアニメーションワークフローでは&lt;/h4&gt;&#10;&lt;p&gt;DCCツールでモーション作って　FBX出して　&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;で読んで確認&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%C6%A5%EC%A1%BC%A5%B7%A5%E7%A5%F3"&gt;イテレーション&lt;/a&gt;に問題がある&lt;br /&gt;&#10;更に外部の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A1%BC%A5%B7%A5%E7%A5%F3%A5%AD%A5%E3%A5%D7%A5%C1%A5%E3%A1%BC"&gt;モーションキャプチャー&lt;/a&gt;ツールなどとの連携が増えると更に難しくなる　&lt;br /&gt;&#10;つらみ&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="Control-RIgなら"&gt;Control RIgなら&lt;/h4&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;上で編集調整できてしまう&lt;br /&gt;&#10;一から作ることも、微調整も可能&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/C%2B%2B"&gt;C++&lt;/a&gt;で独自のノードで機能追加もできる&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="AnimationBPとちがうの"&gt;AnimationBPとちがうの？&lt;/h4&gt;&#10;&lt;p&gt;AnimBPに比べてバーチャルマシンがすごく軽いメリットが有る&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="使い方"&gt;使い方&lt;/h4&gt;&#10;&lt;p&gt;Rig Graphでリグとキャラの関連付け&lt;/p&gt;&#10;&lt;p&gt;Rig Hierarchy で階層構造&lt;/p&gt;&#10;&lt;p&gt;Control RigはSkeltalアセットに依存していない骨の名前と階層が同じなら流用可能&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="アセット作成"&gt;アセット作成&lt;/h5&gt;&#10;&lt;p&gt;Control Rig&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;を有効化&lt;br /&gt;&#10;右クリックメニューから新規作成&lt;br /&gt;&#10;ControlとSpaceを積んでいく&lt;br /&gt;&#10;ControlはViewport上で触って動かすモノ&lt;br /&gt;&#10;SpaceはControlの座標系制御のオブジェクト&lt;br /&gt;&#10;動かした結果をノードによってボーンに反映させる&lt;br /&gt;&#10;BeginExecuteでControlの位置などをボーンにセットする&lt;/p&gt;&lt;p&gt;ちょっとだけわかった(Sequencer版)&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%DA%B6%F6"&gt;土偶&lt;/a&gt;でもわかるControl Rig - &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.25版 -&lt;br&gt;&lt;br&gt;ワイはネコ様以下や…&lt;br&gt; &lt;a href="https://twitter.com/hashtag/ue4fest?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#ue4fest&lt;/a&gt; &lt;a href="https://t.co/Dw9rocn1VB"&gt;pic.twitter.com/Dw9rocn1VB&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/1284353917585784832?ref_src=twsrc%5Etfw"&gt;2020年7月18日&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt; &lt;br /&gt;&#10;&lt;br /&gt;&#10;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Kd-Treeメモ</title><link>https://nagakagachi.github.io/entry/2020/06/18/001027/</link><pubDate>Thu, 18 Jun 2020 00:10:27 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/06/18/001027/</guid><description>&lt;div class="section"&gt;&#10;&lt;h3 id="stackless-traversal"&gt;Stackless Traversal&lt;/h3&gt;&#10;&lt;p&gt;Stackを使わない&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%DA%B9%BD%C2%A4"&gt;木構造&lt;/a&gt;の走査. &lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="kd-tree"&gt;Kd-Tree&lt;/h4&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="kd-restart"&gt;kd-restart&lt;/h5&gt;&#10;&lt;p&gt;&lt;a href="https://graphics.stanford.edu/papers/gpu_kdtree/kdtree.pdf"&gt;https://graphics.stanford.edu/papers/gpu_kdtree/kdtree.pdf&lt;/a&gt;&lt;br /&gt;&#10;子ノードのうち始点に近い方の子を先に処理し、&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/leaf"&gt;leaf&lt;/a&gt;に到達して処理をしたら tminを&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/tmax"&gt;tmax&lt;/a&gt;で更新し、&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/tmax"&gt;tmax&lt;/a&gt;を新たにルートとの交差で更新してから走査を続ける.&lt;br /&gt;&#10;tmin,&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/tmax"&gt;tmax&lt;/a&gt;だけを保持して都度走査ノードを検索してリスタートする.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="rope"&gt;Rope&lt;/h5&gt;&#10;&lt;p&gt;水平方向のノード間のリンク(Rope)によってStacklessな走査を実現する.&lt;br /&gt;&#10;&lt;a href="http://www.johannes-guenther.net/StacklessGPURT/StacklessGPURT.pdf"&gt;http://www.johannes-guenther.net/StacklessGPURT/StacklessGPURT.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://www.cin.ufpe.br/~als3/saap/ArturLiraDosSantos-ArtigoIJPP.pdf"&gt;https://www.cin.ufpe.br/~als3/saap/ArturLiraDosSantos-ArtigoIJPP.pdf&lt;/a&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="binary-tree"&gt;Binary-Tree&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="http://jcgt.org/published/0002/01/03/paper.pdf"&gt;http://jcgt.org/published/0002/01/03/paper.pdf&lt;/a&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2020/06/18/001027"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Dreams Engineメモ</title><link>https://nagakagachi.github.io/entry/2020/06/02/221512/</link><pubDate>Tue, 02 Jun 2020 22:15:12 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/06/02/221512/</guid><description>&lt;p&gt;Dreams Engineの仕組みについてメモ&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;ul&gt;&#10;&lt;li&gt;&lt;a href="#CSG"&gt;CSG&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#PointCloud"&gt;PointCloud&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;li&gt;&lt;a href="#メモ"&gt;メモ&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="講演資料"&gt;講演資料&lt;/h3&gt;&#10;&lt;p&gt;&lt;iframe width="480" height="270" src="https://www.youtube.com/embed/u9KNtnCZDMI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; 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=u9KNtnCZDMI&amp;list=FLG_L7EFxdvJXARWutHbzh7Q&amp;index=124"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;&lt;a href="http://advances.realtimerendering.com/s2015/AlexEvans_SIGGRAPH-2015-sml.pdf"&gt;http://advances.realtimerendering.com/s2015/AlexEvans_SIGGRAPH-2015-sml.pdf&lt;/a&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="CSG"&gt;CSG&lt;/h4&gt;&#10;&lt;p&gt;アーティストはCSG(Constructive Solid Geometry)でモデルなどを作る&lt;/p&gt;&#10;&lt;p&gt;CSGのEdit-Listという形で管理される&lt;/p&gt;&#10;&lt;p&gt;Edit-Listは100kのEditまでサポート&lt;/p&gt;&#10;&lt;p&gt;1000^3のグリッド空間でそれぞれのセルについてEdit-Listを評価することで表面を決定する&lt;/p&gt;&#10;&lt;p&gt;空間を4x4x4単位で分割していき、局所空間毎のEdit-Listがなるべく短くなるようにする&lt;/p&gt;&#10;&lt;p&gt;形状の表面はなるべく分割し、空であったり完全に埋まっている部分は分割しないようにする&lt;/p&gt;&#10;&lt;p&gt;分割するかどうかの判断はCSGから計算されたSDFの値を利用する&lt;/p&gt;&#10;&lt;p&gt;実験の結果、SDFはL1距離やL2距離ではなく、Lmax距離(Max-Norm Distance)を用いるのが良いとわかった&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="PointCloud"&gt;PointCloud&lt;/h4&gt;&#10;&lt;p&gt;様々な検証の後に、メッシュ化やVolumeRenderingではなく、CSG表面へPoint Cloudの生成することを試した&lt;/p&gt;&#10;&lt;p&gt;SDFは中間表現扱いとなり、Pointを生成する際の評価に利用される&lt;/p&gt;&#10;&lt;p&gt;Edit-Listの空間分割の際にSDFの表面上を詳細に分割するようにしており、空間は4x4x4で分割されている&lt;/p&gt;&#10;&lt;p&gt;4x4x4=64スレッドでLeafVoxelにSDFのゼロ境界が交差するかチェックし、交差する場合はPointを生成する&lt;/p&gt;&#10;&lt;p&gt;LeafVoxelひとつにつきPointは一つとする&lt;/p&gt;&#10;&lt;p&gt;LeafVoxelは4x4x4単位でBrickとして管理されている&lt;br /&gt;&#10;Brickは&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D2%A5%EB%A5%D9%A5%EB%A5%C8"&gt;ヒルベルト&lt;/a&gt;曲線で空間充填するように並んでいる&lt;br /&gt;&#10;256点毎に1&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ーとしてまとめて処理をする&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D2%A5%EB%A5%D9%A5%EB%A5%C8"&gt;ヒルベルト&lt;/a&gt;順で空間的にジャンプがある場合は&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%A6%A5%F3%A5%C7%A5%A3"&gt;バウンディ&lt;/a&gt;ングボックスがタイトになるように調整(よくわからない)&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ー毎に&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%A6%A5%F3%A5%C7%A5%A3"&gt;バウンディ&lt;/a&gt;ングボックスと、法線の境界情報(&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;内法線の上限下限？)を持つ&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ー内のPointは位置、法線、ラフネスをdword(32bit?)にパックしたものと32bitカラーを持つ&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ー内のPointの情報はDXT1で圧縮される&lt;/p&gt;&lt;p&gt;また、LOD毎に独立した&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ーを計算してミップピラミッド&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;とそのPointCloudを生成する&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="レンダリング"&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0"&gt;レンダリング&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;モデルのPointCloudを描画をする&lt;br /&gt;&#10;各モデルの&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ーをBVHに配置（グローバルではなくモデル一つがBVHで&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ーを管理している？）&lt;br /&gt;&#10;LOD間の遷移を滑らかにするために、&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B7%A5%A2%A5%F3%A5%EB%A1%BC%A5%EC%A5%C3%A5%C8"&gt;ロシアンルーレット&lt;/a&gt;で25%までPointを間引く(&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;毎に256-&gt;64まで滑らかに間引かれる)&lt;br /&gt;&#10;どうもPointをComputeShaderでAtmicに"Splat"描画をしているらしい&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;Brickは4x4x4のVoxelの塊&lt;/p&gt;&#10;&lt;p&gt;CSGからSDFを作る(ランタイム？もう一度調べる)&lt;/p&gt;&#10;&lt;p&gt;SDFはL1やL2ではなくてLmaxらしい&lt;/p&gt;&#10;&lt;p&gt;試行錯誤の後にメッシュやVolumeRenderingではなく点群による描画に行き着いたとのこと&lt;/p&gt;&#10;&lt;p&gt;肝としてはPointCloudデータの生成とその圧縮、&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF"&gt;クラスタ&lt;/a&gt;ー単位のカリングとLOD、Compute?によるAtomic演算描画あたりだろうか&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2020/06/02/221512"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Maya Moduleについて</title><link>https://nagakagachi.github.io/entry/2020/05/27/204919/</link><pubDate>Wed, 27 May 2020 20:49:19 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/05/27/204919/</guid><description>&lt;p&gt;Mayaにおけるツールの配布形態の一つであるModuleについてのメモ。&lt;/p&gt;&#10;&lt;p&gt;ツール群を機能やプロダクトでModuleに分けることで最小構成の切り出しなどをやりやすくしたいというハナシ。&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#Module定義ファイルmod"&gt;Module定義ファイル(.mod)&lt;/a&gt;&lt;ul&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="#test_modulemod"&gt;test_module.mod&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Moduleロード設定"&gt;Moduleロード設定&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&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;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Module定義ファイルmod"&gt;Module定義ファイル(.mod)&lt;/h3&gt;&#10;&lt;p&gt;Moduleの名前、バージョン、Moduleルート&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リパスを記述する。&lt;br /&gt;&#10;Module毎にロードする条件(&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/win64"&gt;win64&lt;/a&gt;, &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/linux"&gt;linux&lt;/a&gt;等)を指定可能。&lt;br /&gt;&#10;上記のほかにその他&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4"&gt;環境変数&lt;/a&gt;の設定が可能。&lt;br /&gt;&#10;Maya起動時に MAYA_MODULE_PATH&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4"&gt;環境変数&lt;/a&gt; の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リが検索され、Moduleがロードされる。&lt;/p&gt;&lt;p&gt;Module定義ファイルの詳細&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fhelp.autodesk.com%2Fview%2FMAYAUL%2F2017%2FJPN%2F%3Fguid%3D__files_GUID_130A3F57_2A5D_4E56_B066_6B86F68EEA22_htm" title="Help" 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://help.autodesk.com/view/MAYAUL/2017/JPN/?guid=__files_GUID_130A3F57_2A5D_4E56_B066_6B86F68EEA22_htm"&gt;help.autodesk.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="記法"&gt;記法&lt;/h4&gt;&#10;&lt;pre&gt;&lt;code&gt;&amp;lt;pre class=&amp;quot;code c++&amp;quot; data-lang=&amp;quot;c++&amp;quot; data-unlink&amp;gt;+ MAYAVERSION:バージョン条件 PLATFORM:プラットフォーム条件 LOCALE:ロケール条件 Module名 バージョン番号 Moduleルートディレクトリパス&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;環境変数: 値&#10;環境変数: 値&#10;続く&amp;hellip;&lt;/pre&gt;&lt;p&gt;条件は省略できる。&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4"&gt;環境変数&lt;/a&gt;記述は&lt;b&gt;空の行や無効な行があるとそれ以降は無視される模様&lt;/b&gt;。&lt;br /&gt;&#10;scripts, icons, plug-ins, presets の4つの&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4"&gt;環境変数&lt;/a&gt;は、それぞれMAYA_SCRIPT_PATH 等の対応する&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4"&gt;環境変数&lt;/a&gt;にAppendされる。&lt;br /&gt;&#10;記述しなかった場合はそれぞれ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%EA%C2%D0%A5%D1%A5%B9"&gt;相対パス&lt;/a&gt;で ./scripts 等がデフォルト設定される。&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4"&gt;環境変数&lt;/a&gt;にパスを設定する際に&lt;br /&gt;&#10;[r] scripts: &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リパス&lt;br /&gt;&#10;のように [r] キーワードをつけるとサブ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リを&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2"&gt;再帰&lt;/a&gt;的に走査する。&lt;br /&gt;&#10;デフォルトではサブ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リは無視される。&lt;/p&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="設定例"&gt;設定例&lt;/h4&gt;&#10;&lt;p&gt;ロード条件無しで、Moduleのscriptsに関してのみサブ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リを&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2"&gt;再帰&lt;/a&gt;的に走査する構成&lt;/p&gt;&#10;&lt;figure class="figure-image figure-image-fotolife" title="フォルダ構成"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/1d427efbeee4df9569a58a05862754554df17696213f0c3baba5595c1cb9180e.png" alt="f:id:nagakagachi:20211006193329p:plain" width="803" height="543" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;フォルダ構成&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="test_modulemod"&gt;test_module.mod&lt;/h5&gt;&#10;&lt;pre&gt;&lt;code&gt;&amp;lt;pre class=&amp;quot;code c++&amp;quot; data-lang=&amp;quot;c++&amp;quot; data-unlink&amp;gt;+ test_module1.0.0 ../module_root&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;icons: ./icons&#10;plug-ins: ./plug-ins&#10;presets: ./presets&#10;[r] scripts: ./scripts&lt;/pre&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="Moduleロード設定"&gt;Moduleロード設定&lt;/h5&gt;&#10;&lt;p&gt;規定のmodules&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リにmodファイルを置くことでもロードされるが、Maya.envで上記modファイルのある&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リをMAYA_MODULE_PATHに指定しても良い。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MAYA_MODULE_PATH &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; test_module.modのディレクトリパス&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Houdini HDK ビルドメモ (18.0.460)</title><link>https://nagakagachi.github.io/entry/2020/05/24/190639/</link><pubDate>Sun, 24 May 2020 19:06:39 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/05/24/190639/</guid><description>&lt;p&gt;HDK(&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/C%2B%2B"&gt;C++&lt;/a&gt;)のサンプルについてcmakeでVisualStudioプロジェクトを作成してビルドする機会があったのでメモ.&lt;br /&gt;&#10;&lt;b&gt;注意:ビルドが成功してdllが作成されるところまでの確認しかしていない(未実行).&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;Houdini 18.0.460&lt;/p&gt;&#10;&lt;p&gt;VisualStudio 2017&lt;/p&gt;&#10;&lt;p&gt;対象のサンプルは SOP_Star&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="事前準備"&gt;事前準備&lt;/h3&gt;&#10;&lt;p&gt;Houdiniインストール&lt;/p&gt;&#10;&lt;p&gt;VisualStudioインストール&lt;/p&gt;&#10;&lt;p&gt;cmake インストール&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;Houdiniインストール&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リのtoolkit&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リを丸ごと適当な&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リにコピー(Documentsなど)&lt;/p&gt;&lt;p&gt;&lt;u&gt;コピー元&lt;/u&gt;&lt;br /&gt;&#10;C:/Program Files/Side Effects Software/Houdini 18.0.460/toolkit&lt;/p&gt;&lt;p&gt;&lt;u&gt;コピー先&lt;/u&gt;&lt;br /&gt;&#10;Documents等&lt;/p&gt;&lt;p&gt;以降はコピー先&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リで作業する&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3&gt;対象のサンプル&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リへ移動&lt;/h3&gt;&#10;&lt;p&gt;初期だと以下のような状態のはず&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/71e22c4f03af5759aaee6fc13b8d66cc5c71144cb65389e9ef130de00fff4f2d.png" alt="f:id:nagakagachi:20200524181238p:plain" title="f:id:nagakagachi:20200524181238p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3&gt;VisualStudioプロジェクト作成用&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リ作成&lt;/h3&gt;&#10;&lt;p&gt;cmakeで作成するプロジェクトファイル群を入れる&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リを適当な名前で作成(ここではbuildという名前)&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/7a4ddea87d4d59ce6ecae61252fb0777c7ae226446f250e23514dbde6804f64e.png" alt="f:id:nagakagachi:20200524181336p:plain" title="f:id:nagakagachi:20200524181336p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="houdini-command-line-tools-起動"&gt;Houdini Command Line Tools 起動&lt;/h3&gt;&#10;&lt;p&gt;Houdiniの&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%DE%A5%F3%A5%C9%A5%E9%A5%A4%A5%F3"&gt;コマンドライン&lt;/a&gt;ツールHoudini Command Line Tools(以降Command Line)を起動&lt;figure class="figure-image figure-image-fotolife" title="Houdini Command Line Tools"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/fbc260599f9d90c243dcc795f75a82d2f7903ca5b9c906804c9d1e00e5e0b451.png" alt="f:id:nagakagachi:20200524175758p:plain" title="f:id:nagakagachi:20200524175758p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;Houdini Command Line Tools&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3&gt;プロジェクト作成&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リに移動(Command Line)&lt;/h3&gt;&#10;&lt;p&gt;SOP_Star&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リに作成したbuild&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リに移動&lt;/p&gt;&lt;p&gt;cd /d "作業&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リ"/toolkit/samples/SOP/SOP_Star/build&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/c9468b8dcddfc4610cdae5577404bc4ec017d6e85c2ce6daad0a57699e79ed11.png" alt="f:id:nagakagachi:20200524181857p:plain" title="f:id:nagakagachi:20200524181857p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="cmakeコマンドでvisualstudioプロジェクト作成command-line"&gt;cmakeコマンドでVisualStudioプロジェクト作成(Command Line)&lt;/h3&gt;&#10;&lt;p&gt;cmakeに -G オプションで作成したいVisualStudioプロジェクトのバージョンを指定して実行する&lt;/p&gt;&#10;&lt;p&gt;cmake -help でマシンでサポートされているバージョン一覧が表示されるので参考に&lt;/p&gt;&#10;&lt;p&gt;今回はVisualStudio2017の64bitビルドプロジェクトを作りたいので以下のように指定&lt;/p&gt;&#10;&lt;p&gt;cmake -G "&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Visual%20Studio"&gt;Visual Studio&lt;/a&gt; 15 2017 &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Win64"&gt;Win64&lt;/a&gt;" ..&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/e1f5685ea303843ddc83b457291141eaf329caf64ca5ef51109b1b322795b087.png" alt="f:id:nagakagachi:20200524182709p:plain" title="f:id:nagakagachi:20200524182709p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;実行すると以下のようなログが流れる&lt;figure class="figure-image figure-image-fotolife" title="cmake実行結果"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/4e1e4ad5822336b0d024b3df06fda591ab88c0f3a5e6e9739d14783fb4005861.png" alt="f:id:nagakagachi:20200524182757p:plain" title="f:id:nagakagachi:20200524182757p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;cmake実行結果&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;成功すると実行した&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8"&gt;ディレクト&lt;/a&gt;リ(ここではbuild)に以下のようにVisualStudioソリューションファイルが作成される&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/005e3084ae4a1465568cdc67ddd924586221c33e5b1559cab54ef2921ecc8a29.png" alt="f:id:nagakagachi:20200524183016p:plain" title="f:id:nagakagachi:20200524183016p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>論文メモ[CARL: Controllable Agent with Reinforcement Learning for Quadruped Locomotion](SIGGRAPH2020)</title><link>https://nagakagachi.github.io/entry/2020/05/16/193506/</link><pubDate>Sat, 16 May 2020 19:35:06 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/05/16/193506/</guid><description>&lt;p&gt;&lt;iframe width="480" height="270" src="https://www.youtube.com/embed/t9CdF_Pl19Q?feature=oembed" frameborder="0" allow="accelerometer; autoplay; 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=t9CdF_Pl19Q"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#Paper"&gt;Paper&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Abstract"&gt;Abstract&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Proposed-Method"&gt;Proposed Method&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#関連研究"&gt;関連研究&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Paper"&gt;Paper&lt;/h3&gt;&#10;&lt;p&gt;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Finventec-ai-center.github.io%2Fprojects%2FCARL%2Findex.html" title="CARL: Controllable Agent with Reinforcement Learning for Quadruped Locomotion" 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://inventec-ai-center.github.io/projects/CARL/index.html"&gt;inventec-ai-center.github.io&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Abstract"&gt;Abstract&lt;/h3&gt;&#10;&lt;p&gt;本論文では物理ベース制御アニメーションで駆動するエージェントに対して、ユーザによる制御が可能且つダイナミックな環境に自然に反応する四足歩行エージェント「CARL」を提案する。本研究ではエージェントは段階的に学習する。まずアニメーションクリップを模倣して身体を制御するように学習する。次にユーザによる高度な制御に対して適切なアニメーションを対応させる行動分布を学習する。行動分布の獲得にはGenerative Adversarial Networksを用いる。さらに深層&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%AF%B2%BD%B3%D8%BD%AC"&gt;強化学習&lt;/a&gt;によるfine-tuningによって、外部からの摂動から回復しつつ滑らかな遷移を可能にする。本研究では、ユーザの制御に対する追従性能を計測し、生成された動作を視覚的に分析することでその有効性を評価する。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Introduction"&gt;Introduction&lt;/h3&gt;&#10;&lt;p&gt;(1)動的環境と物理的に相互作用する能力と，&lt;/p&gt;&#10;&lt;p&gt;(2)参照モーションクリップから学習した自然な動きを採用することで，データ駆動型の物理ベースの制御可能な四足歩行エージェントを提案する．&lt;/p&gt;&#10;&lt;p&gt;複数段階のプロセスからなり、はじめに模倣によってリファレンスモーションを学習、次に速度や向きなどの高度なユーザー制御をGenerative Adversarial Networksを用いたjoint-actionに&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%C3%A5%D4%A5%F3%A5%B0"&gt;マッピング&lt;/a&gt;することを学習する。&lt;/p&gt;&#10;&lt;p&gt;本研究の貢献をまとめると次のようになる。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;高次のユーザ制御と学習した自然な動きを効果的に&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%C3%A5%D4%A5%F3%A5%B0"&gt;マッピング&lt;/a&gt;するための GAN Supervision &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EC%A1%BC%A5%E0%A5%EF%A1%BC%A5%AF"&gt;フレームワーク&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;DRLを用いて訓練された四足歩行エージェントのための物理ベースのコントローラで、アクションラベルを必要とせずに意味のある反応を生成しながら、様々な外部摂動に適応することが可能&lt;/li&gt;&#10;&lt;li&gt;高レベルのナビゲーションモジュールをエージェントに接続する方法&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Proposed-Method"&gt;Proposed Method&lt;/h3&gt;&#10;&lt;p&gt;本研究では、高度なユーザ制御に追従しながら、外部からの擾乱を受けて自然な動きや反応を生成する物理ベースのコントローラを設計することを目的とする。生成された動きは、リファレンスモーションの動きに似ていれば自然なものと評価する。そのために、コントローラを3段階に分けて学習させる。&lt;/p&gt;&#10;&lt;p&gt;第 1 段階では、リファレンスモーションクリップの自然な動きを模倣学習により物理ベースのコントローラに伝達することを目的としている。これは物理ベースのコントローラが従うべき行動分布を方策ネットワークで学習することで達成される。&lt;/p&gt;&#10;&lt;p&gt;この方策ネットワークはプリミティブネットワークと歩法ネットワークを含み、行動分布を低レベルプリミティブ分布に分解する。結果としてこの方策ネットワークは物理ベースのコントローラが自然な動きを作り出すことを可能にする行動分布を生成し、アニメーションと物理の橋渡しに成功した。&lt;/p&gt;&#10;&lt;p&gt;2つ目の学習段階ではGANコントローラーアダプタを採用し、高レベルの歩法ネットワークが先に学習した自然な行動分布を近似できるようにした。しかし、2つ目の訓練段階では外部摂動がないため、外部からのノイズに対応できない。&lt;/p&gt;&#10;&lt;p&gt;そこで最後に GAN regularized DRL fine-tuning を追加し、コントローラがそのような外部摂動の影響から回復できるようにする。&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;物理ベース制御アニメーションの具体的な方策や実装などについてはこちらのほうが詳しそう&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fxbpeng.github.io%2Fprojects%2FMCP%2Findex.html" title="MCP: Learning Composable Hierarchical Control with Multiplicative Compositional Policies" 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://xbpeng.github.io/projects/MCP/index.html"&gt;xbpeng.github.io&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;</description></item><item><title>UE5の発表についてのメモ</title><link>https://nagakagachi.github.io/entry/2020/05/14/120000/</link><pubDate>Thu, 14 May 2020 12:00:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/05/14/120000/</guid><description>&lt;p&gt;&lt;s&gt;In-house Engineでこれと戦わなきゃいけないってマジ？&lt;/s&gt;&lt;/p&gt;&lt;p&gt;PlayStation5 上で動作している &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Unreal%20Engine"&gt;Unreal Engine&lt;/a&gt; 5 のデモが発表されたので、この時点で感じたことなど覚えておくためにメモ。&lt;/p&gt;&lt;p&gt;目玉は動的GIシステムLumenと微細ジオメトリの&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0"&gt;レンダリング&lt;/a&gt;を実現するNanite。&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.unrealengine.com%2Fja%2Fblog%2Fa-first-look-at-unreal-engine-5%3Flang%3Dja" title="Unreal Engine 5 初公開" 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://www.unrealengine.com/ja/blog/a-first-look-at-unreal-engine-5?lang=ja"&gt;www.unrealengine.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#Lumen-動的GI"&gt;Lumen (動的GI)&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Nanite-仮想化マイクロポリゴンジオメトリ"&gt;Nanite (仮想化マイクロポリゴンジオメトリ)&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Niagara"&gt;Niagara&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="#Chaos"&gt;Chaos&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;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Lumen-動的GI"&gt;Lumen (動的GI)&lt;/h3&gt;&#10;&lt;p&gt;動的なGlobal IlluminationシステムでDiffuse及びSpecular間接光を&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0"&gt;レンダリング&lt;/a&gt;する。&lt;br /&gt;&#10;動的なライトは最近のGIだと半分当然のようなところがあるが、動的なジオメトリはどこまでサポートされるのか気になる。&lt;br /&gt;&#10;レイトレハードウェアは使ってないらしいのでCompute Shaderによるものか、EnlightenのようにCPU側で非同期計算する方式なのか。&lt;figure class="figure-image figure-image-fotolife" title="LumenによるGI有効"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/680ed60850f8b2a6024cd37b26e36b24381350ceb4d4f9c9ee5dab290ed45f5f.png" alt="f:id:nagakagachi:20200514071027p:plain" title="f:id:nagakagachi:20200514071027p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;LumenによるGI有効&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="figure-image figure-image-fotolife" title="GI無し"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/a84bdee9f74fb5bd111fbb0bfc1948a7a3f2229a6952b73f2cad6064cb25fa4f.png" alt="f:id:nagakagachi:20200514071116p:plain" title="f:id:nagakagachi:20200514071116p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;GI無し&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Nanite-仮想化マイクロポリゴンジオメトリ"&gt;Nanite (仮想化マイクロポリゴンジオメトリ)&lt;/h3&gt;&#10;&lt;p&gt;Texture-StreamingのようにジオメトリをStreamingし、&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D4%A5%AF%A5%BB%A5%EB"&gt;ピクセル&lt;/a&gt;レベルのジオメトリ描画を可能にする。&lt;br /&gt;&#10;デモでは10億Triを超えるソースジオメトリを、Naniteが適切にコン&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB"&gt;トロール&lt;/a&gt;して2000万Triのジオメトリを描画しているらしい。&lt;figure class="figure-image figure-image-fotolife" title="もはやノイズにしか見えないトライアングル群"&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/1051d3b5480215bf9fb7c9b059eba35139f999b4c33708b3b913b4cf8322a03d.png" alt="f:id:nagakagachi:20200514070258p:plain" title="f:id:nagakagachi:20200514070258p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;figcaption&gt;もはやノイズにしか見えないトライアングル群&lt;/figcaption&gt;&lt;/figure&gt;DCCツールでの特別な作業は不要で、&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/ZBRush"&gt;ZBRush&lt;/a&gt;などで作ったものをそのままインポート可能。&lt;br /&gt;&#10;いままでNormalMapで表現していたディ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%A3%A1%BC"&gt;ティー&lt;/a&gt;ルをジオメトリによって直接表現する。&lt;br /&gt;&#10;LoDもNaniteがやってくれる。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Niagara"&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Niagara"&gt;Niagara&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;エフェクト以外にもコウモリや蟲の群れなどにも&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Niagara"&gt;Niagara&lt;/a&gt;を利用している。&lt;br /&gt;&#10;パーティクル同士の通信や環境の知覚などもできるらしい。&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/e72ea0bc52f8a0fecd0a8166001aba95939376e4dc15fe84d85df347bd52e3e8.png" alt="f:id:nagakagachi:20200514072020p:plain" title="f:id:nagakagachi:20200514072020p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&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;さらっと流されたけど流体シミュレーション。&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/c7d7a0b043b5c9918422647928809b18d6bed35a60e1f489f9c0ef0723678e35.png" alt="f:id:nagakagachi:20200514072246p:plain" title="f:id:nagakagachi:20200514072246p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Chaos"&gt;Chaos&lt;/h3&gt;&#10;&lt;p&gt;スカーフのClothシミュレーションや落石にはChaosを使用。&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/869cc4ea7f5c126866c715ab15a729a2a74db68e34e1bc52ae05293ed2d12b03.png" alt="f:id:nagakagachi:20200514072548p:plain" title="f:id:nagakagachi:20200514072548p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>調べものリンク集</title><link>https://nagakagachi.github.io/entry/2020/05/09/173039/</link><pubDate>Sat, 09 May 2020 17:30:39 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2020/05/09/173039/</guid><description>&lt;p&gt;読みたいもの,あとで読み返したいものの雑多なメモ&lt;/p&gt;&#10;&lt;p&gt;カテゴリは結構適当. 適宜更新と整理をする予定.&lt;/p&gt;&#10;&lt;ul class="table-of-contents"&gt;&#10;&lt;li&gt;&lt;a href="#SIGGRAPH"&gt;SIGGRAPH&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Algorithms"&gt;Algorithms&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#Distance-Transform"&gt;Distance Transform&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#tree-traversal"&gt;tree traversal&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Animation"&gt;Animation&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#CollisionTraverse"&gt;Collision,Traverse&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Graphics"&gt;Graphics&lt;/a&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#Snow"&gt;Snow&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#MachineLearning-ArtificialIntelligence"&gt;MachineLearning, ArtificialIntelligence&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Mathematics"&gt;Mathematics&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Physics"&gt;Physics&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Robotics"&gt;Robotics&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Voxel"&gt;Voxel&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Dreams"&gt;Dreams&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Remedy"&gt;Remedy&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#Roblox"&gt;Roblox&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="SIGGRAPH"&gt;&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/SIGGRAPH"&gt;SIGGRAPH&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="http://kesen.realtimerendering.com/sig2020.html"&gt;SIGGRAPH 2020 Papers&lt;/a&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Algorithms"&gt;Algorithms&lt;/h3&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="Distance-Transform"&gt;Distance Transform&lt;/h4&gt;&#10;&lt;p&gt;&lt;a href="https://prideout.net/blog/distance_fields/#the-marching-parabolas-algorithm"&gt;Distance Fields&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="http://cs.brown.edu/people/pfelzens/papers/dt-final.pdf"&gt;http://cs.brown.edu/people/pfelzens/papers/dt-final.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="tree-traversal"&gt;tree traversal&lt;/h4&gt;&#10;&lt;p&gt;&lt;a href="https://graphics.stanford.edu/papers/gpu_kdtree/kdtree.pdf"&gt;https://graphics.stanford.edu/papers/gpu_kdtree/kdtree.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="http://www.johannes-guenther.net/StacklessGPURT/StacklessGPURT.pdf"&gt;http://www.johannes-guenther.net/StacklessGPURT/StacklessGPURT.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="http://jcgt.org/published/0002/01/03/paper.pdf"&gt;http://jcgt.org/published/0002/01/03/paper.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="http://www.cs.uu.nl/docs/vakken/magr/2015-2016/slides/lecture%2011%20-%20GPU%20ray%20tracing%20%281%29.pdf"&gt;http://www.cs.uu.nl/docs/vakken/magr/2015-2016/slides/lecture%2011%20-%20GPU%20ray%20tracing%20%281%29.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="http://www.cs.uu.nl/docs/vakken/magr/2017-2018/slides/lecture%2012%20-%20GPU%20ray%20tracing%20%282%29.pdf"&gt;http://www.cs.uu.nl/docs/vakken/magr/2017-2018/slides/lecture%2012%20-%20GPU%20ray%20tracing%20%282%29.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://www.cin.ufpe.br/~als3/saap/ArturLiraDosSantos-ArtigoIJPP.pdf"&gt;https://www.cin.ufpe.br/~als3/saap/ArturLiraDosSantos-ArtigoIJPP.pdf&lt;/a&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="Animation"&gt;Animation&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="http://www.cs.cmu.edu/~15464-s13/lectures/lecture6/IK.pdf"&gt;http://www.cs.cmu.edu/~15464-s13/lectures/lecture6/IK.pdf&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://ramanans1.github.io/plan2explore/"&gt;Planning to Explore via Self-Supervised World Models&lt;/a&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="CollisionTraverse"&gt;Collision,Traverse&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://hal.inria.fr/hal-00920666/document"&gt;https://hal.inria.fr/hal-00920666/document&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://www.diva-portal.org/smash/get/diva2:1260971/FULLTEXT02"&gt;https://www.diva-portal.org/smash/get/diva2:1260971/FULLTEXT02&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://www.scratchapixel.com/lessons/advanced-rendering/introduction-acceleration-structure/grid"&gt;https://www.scratchapixel.com/lessons/advanced-rendering/introduction-acceleration-structure/grid&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="http://www.physicsbasedanimation.com/2018/03/28/siggraph-2018/"&gt;SIGGRAPH 2018 &amp;raquo; Physics-Based Animation&lt;/a&gt;&lt;br /&gt;&#10;&lt;a href="https://iphys.wordpress.com/2020/05/11/local-optimization-for-robust-signed-distance-field-collision/"&gt;Local Optimization for Robust Signed Distance Field Collision | Computer Graphics and Simulation&lt;/a&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;/div&gt;</description></item><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><item><title>UE4 C++プラグインでPostProcess検証</title><link>https://nagakagachi.github.io/entry/2019/04/20/224732/</link><pubDate>Sat, 20 Apr 2019 22:47:32 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2019/04/20/224732/</guid><description>&lt;p&gt;エンジン改造をせずに&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/C%2B%2B"&gt;C++&lt;/a&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3"&gt;プラグイン&lt;/a&gt;とGlobalShaderでPostProcess的なことをできないか調べてみた。&lt;br&gt;&lt;br /&gt;&#10;結論としては&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;は動的解像度関係で複雑なUV計算などを隠蔽しているのでそのあたりを再現しないと正常に動かない&lt;/li&gt;&#10;&lt;li&gt;UI描画と同じフル解像度に対して処理するので動的解像度の恩恵を受けられない&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;まぁ、ダメでしたね。&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="概要"&gt;概要&lt;/h4&gt;&#10;&lt;p&gt;基本的にゲームスレッドからの描画命令は ENQUEUE_RENDER_COMMANDマクロによってキューに積み込んで描画スレッドが処理する。&lt;/p&gt;&#10;&lt;p&gt;描画スレッドはキューに積まれた順番に処理をしていく。&lt;/p&gt;&#10;&lt;p&gt;ActorのTickで積み込むとScene描画(ベースパスやPostProcess)の前に積み込まれるので、PostProcessでよく使うSceneColorテクスチャなどがまだ出来上がっていない。&lt;/p&gt;&#10;&lt;p&gt;ActorにはUI描画の直前(PostProcess後)のタイミングでコールされる関数を設定できるのでそれを利用すればいい感じのタイミングに描画コマンドを差し込めるのでは？&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="結果"&gt;結果&lt;/h4&gt;&#10;&lt;p&gt;というわけでActorのPostRenderFor()を利用して描画コマンドを積んでみたところをRenderDocで確認してみた。&lt;/p&gt;&#10;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/2c3a48a97669357bebd69593745c15af8efa29a83965365cda37c775a0eb9dfd.png" alt="f:id:nagakagachi:20190420212602p:plain" title="f:id:nagakagachi:20190420212602p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;p&gt;一応いい感じの場所で自前の描画コマンドが実行されていることが確認できる。&lt;/p&gt;&#10;&lt;p&gt;ただし以下の実行結果のようにSceneColorの領域とRendetTargetのViewportのマッチング計算がうまくいっていなかったりしていろいろ問題がある。&lt;/p&gt;&#10;&lt;p&gt;(ウィンドウサイズを変更すると描画領域が変わっておかしくなる)&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe allowfullscreen="" src="//www.youtube.com/embed/9i00cuWclkc" width="560" height="315" frameborder="0"&gt;&lt;/iframe&gt;&lt;br&gt;&lt;a href="https://youtube.com/watch?v=9i00cuWclkc"&gt;UE4 C++プラグインでPostProcess検証&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;側でToneMap後にHookできるようになったり描画領域に応じたUV補正計算の自動化がサポートされないだろうか…&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h4 id="関連コード"&gt;関連コード&lt;/h4&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h5 id="シェーダ"&gt;シェーダ&lt;/h5&gt;&#10;&lt;pre&gt;&lt;code&gt;&amp;lt;pre class=&amp;quot;code lang-cpp&amp;quot; data-lang=&amp;quot;cpp&amp;quot; data-unlink&amp;gt;&amp;lt;span class=&amp;quot;synPreProc&amp;quot;&amp;gt;#include &amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;&amp;amp;quot;/Engine/Public/Platform.ush&amp;amp;quot;&amp;lt;/span&amp;gt;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;Texture2D SceneColor;&#10;SamplerState SceneColorSampler;&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="synComment"&gt;// フルスクリーンVS&lt;/span&gt;&#10;&lt;span class="synType"&gt;void&lt;/span&gt; MainVS(&#10;in uint GlobalVertexId : SV_VertexID,&#10;out float2 OutUV : TEXCOORD0,&#10;out float4 OutPosition : SV_POSITION&#10;)&#10;{&#10;uint VertexId = GlobalVertexId;&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;float2 CellVertexUV = float2(&amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;0x1&amp;lt;/span&amp;gt; &amp;amp;amp; ((VertexId + &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;) / &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;), VertexId &amp;amp;amp; &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;0x1&amp;lt;/span&amp;gt;);&#10;&#10;&amp;lt;span class=&amp;quot;synComment&amp;quot;&amp;gt;// Output vertex position.&amp;lt;/span&amp;gt;&#10;OutPosition = float4(CellVertexUV * &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;2&amp;lt;/span&amp;gt; - &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;, &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;, &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt;);&#10;&#10;&amp;lt;span class=&amp;quot;synComment&amp;quot;&amp;gt;// Output top left originated UV of the vertex.&amp;lt;/span&amp;gt;&#10;OutUV = float2(CellVertexUV.x, &amp;lt;span class=&amp;quot;synConstant&amp;quot;&amp;gt;1&amp;lt;/span&amp;gt; - CellVertexUV.y);&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;}&lt;/p&gt;</description></item><item><title>UE4 翻訳メモ Mesh Drawing Pipeline Conversion Guide for Unreal Engine 4.22</title><link>https://nagakagachi.github.io/entry/2019/04/18/150522/</link><pubDate>Thu, 18 Apr 2019 15:05:22 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2019/04/18/150522/</guid><description>&lt;p&gt;4.22で大幅に変更されたらしいメッシュ描画パイプラインのドキュメントを&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%CB%DD%CC%F5"&gt;Google翻訳&lt;/a&gt;先生の力を借りて翻訳しつつメモ&lt;/p&gt;&lt;p&gt;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdocs.unrealengine.com%2Fen-us%2FProgramming%2FRendering%2FMeshDrawingPipeline%2F4_22_ConversionGuide" title="Mesh Drawing Pipeline Conversion Guide for Unreal Engine 4.22" 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://docs.unrealengine.com/en-us/Programming/Rendering/MeshDrawingPipeline/4_22_ConversionGuide"&gt;docs.unrealengine.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;p&gt;より詳細は&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdocs.unrealengine.com%2Fen-us%2FProgramming%2FRendering%2FMeshDrawingPipeline" title="Mesh Drawing Pipeline" 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://docs.unrealengine.com/en-us/Programming/Rendering/MeshDrawingPipeline"&gt;docs.unrealengine.com&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;や&lt;br /&gt;&#10;&lt;iframe width="480" height="270" src="https://www.youtube.com/embed/qx1c190aGhs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; 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?time_continue=526&amp;v=qx1c190aGhs"&gt;www.youtube.com&lt;/a&gt;&lt;/cite&gt;&lt;br /&gt;&#10;を参照&lt;br /&gt;&#10;&lt;br /&gt;&#10;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;div class="section"&gt;&#10;&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Unreal%20Engine"&gt;Unreal Engine&lt;/a&gt;（&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;）4.22リリースでは、Mesh Drawing Pipelineは完全に書き直されました。主な変更点は、フレーム毎に描画の準備をするImmediate Mode からすべてのシーン描画が事前に準備される Retained Mode に移行したことです。これは、シーン全体のシェーダ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%A4%A5%F3%A5%C7%A5%A3%A5%F3%A5%B0"&gt;バインディング&lt;/a&gt;テーブルを必要とする&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/DirectX"&gt;DirectX&lt;/a&gt; Raytracing（DXR）や、CPUが可視性の情報無しに描画の準備をする必要がある &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;-Driven-Rendering など、今後のテク&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CE%A5%ED"&gt;ノロ&lt;/a&gt;ジをサポートできるようになるための重要な変更です。&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt; 4.22でのMesh Drawing Pipelineの変更についての詳細は、Mesh Drawing PipelineのドキュメントおよびGame Developer's Conference（&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GDC"&gt;GDC&lt;/a&gt;）のプレゼンテーション&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/Unreal%20Engine"&gt;Unreal Engine&lt;/a&gt; 4.22用Mesh Drawing Pipelineの&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%D5%A5%A1%A5%AF%A5%BF%A5%EA%A5%F3%A5%B0"&gt;リファクタリング&lt;/a&gt;を参照してください。&lt;/p&gt;</description></item><item><title>2019年やりたいことメモ</title><link>https://nagakagachi.github.io/entry/2019/03/30/214656/</link><pubDate>Sat, 30 Mar 2019 21:46:56 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2019/03/30/214656/</guid><description>&lt;p&gt;リアルタイム流体の続き&lt;/p&gt;&#10;&lt;p&gt;XPBDの論文を読む&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/%BF%F4%C3%CD%B7%D7%BB%BB"&gt;数値計算&lt;/a&gt;勉強&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%E9%A5%D5%CD%FD%CF%C0"&gt;グラフ理論&lt;/a&gt;勉強&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC"&gt;機械学習&lt;/a&gt;ネタ&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2019/03/30/214656"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>UE4 周期的なリムエミッシブ</title><link>https://nagakagachi.github.io/entry/2019/01/19/090000/</link><pubDate>Sat, 19 Jan 2019 09:00:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2019/01/19/090000/</guid><description>&lt;p&gt;あけましておめでとうございます&lt;/p&gt;&#10;&lt;p&gt;&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;周期的リムライトで遊んでみたり。グ&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EC%A5%A4%A5%DE%A5%F3"&gt;レイマン&lt;/a&gt;さんみたいに凹凸が多いと水面の反射みたいになる。後半の球はリム計算用のベクトルを視線ではなくワールド空間ベクトル(この場合は+Z)にして周期的リムのパラメータを変えたところ。リムってなんだっけ…&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://twitter.com/hashtag/UE4?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#UE4&lt;/a&gt; &lt;a href="https://t.co/zGuOW6giG1"&gt;pic.twitter.com/zGuOW6giG1&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://twitter.com/nagakagachi/status/1086286532242137093?ref_src=twsrc%5Etfw"&gt;2019年1月18日&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;&lt;p&gt;視線ベクトルと&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D4%A5%AF%A5%BB%A5%EB"&gt;ピクセル&lt;/a&gt;法線の&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C6%E2%C0%D1"&gt;内積&lt;/a&gt;を利用して縁をエミッシブで光らせるリムライト的表現をすることがよくあると思います。今回はこのリムライト的表現で使われる値をそのまま使わずに周期関数へ入力してから使うことで、周波数を変えたり波にオフセットをかけたりできるヘンなリムライト？を作ってみます。&lt;/p&gt;&lt;p&gt;視線ベクトルvの逆向きベクトル-vと法線ベクトルnの&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%C6%E2%C0%D1"&gt;内積&lt;/a&gt;は正面から縁に向かって1から0に変化します。&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/529e5d85dfcee3d1c51c5080afab4d6fe039297c48e2c79185bd322abc528f9c.png" width="1023" height="526" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;&lt;span class="math-inline"&gt;\(1 - dot(\vec{-v},\vec{n})\)&lt;/span&gt;&lt;br /&gt;&#10;とすれば正面が0で縁が1になり、単純にこれをエミッシブに出力すれば縁が光ると思います。&lt;/p&gt;&lt;p&gt;これを周期関数である sin() に入力します。&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(sin(1 - dot(\vec{-v},\vec{n}))\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;このままだと -1 ~ +1 の値になるので、1を足して0.5を掛けることで 0 ~ 1 の値に変換します。&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\((sin(1 - dot(\vec{-v},\vec{n})) + 1)*0.5\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;さらに周波数を変えるための変数 freq をsin() の中にかけ合わせます。&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\((sin( (1-dot(\vec{-v},\vec{n}) )*freq)+1)*0.5\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;周期のオフセットのための変数 offset をsin() の中に足します。&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\((sin( (1-dot(\vec{-v},\vec{n}) )*freq+offset)+1)*0.5\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;最後に0から1への変化の急峻さをコン&lt;a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB"&gt;トロール&lt;/a&gt;する変数 sharpness を使ってべき乗します。&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\((power(sin( (1-dot(\vec{-v},\vec{n}) )*freq+offset)+1)*0.5, sharpness)\)&lt;/span&gt;&lt;/p&gt;&#10;&lt;p&gt;この値を適当なカラーにかけてエミッシブ出力するなどすれば完成。&lt;/p&gt;&#10;&lt;p&gt;freqを大きくするとリムライトの波の数が増え、&lt;/p&gt;&#10;&lt;p&gt;offsetを増やすと波の位置が移動し、&lt;/p&gt;&#10;&lt;p&gt;sharpnessを大きくすると明るい部分が狭く（鋭く）なります。&lt;/p&gt;&#10;&lt;br /&gt;&#10;&lt;p&gt;プロジェクトはこちら&lt;br /&gt;&#10;(サンプルプロジェクトではsin()ではなく自前で周期関数モドキ作っていますがsin()などに置き換えても同じような挙動になるはずです)&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdrive.google.com%2Fopen%3Fid%3D1JOK3EEDW2qqXo1PYR7uBqqa402GCGuxQ" title="PeriodicRimEmissiveMaterial.zip" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://drive.google.com/open?id=1JOK3EEDW2qqXo1PYR7uBqqa402GCGuxQ"&gt;drive.google.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;</description></item><item><title>UE4 マテリアルブループリントでGPUバイトニックソート</title><link>https://nagakagachi.github.io/entry/2018/12/15/080000/</link><pubDate>Sat, 15 Dec 2018 08:00:00 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/12/15/080000/</guid><description>&lt;p&gt;多分2018年最後の記事。（思ったほど効果がなかったので温めずに公開）&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnagakagachi%2Fue4%2Fblob%2Fmaster%2Fproject%2Fsample%2FMaterialBitonicSort.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/MaterialBitonicSort.zip"&gt;github.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;p&gt;&lt;iframe width="480" height="270" src="https://www.youtube.com/embed/C8mmNhjWrNw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://youtu.be/C8mmNhjWrNw"&gt;youtu.be&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;&lt;b&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;のマテリアルBPでバイトニックソート&lt;/b&gt;を作ってみました。&lt;br /&gt;&#10;RG32fテクスチャを「R=キー, G=値」の配列に見立ててテクセルを並べ替えます。&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;パーティクル等でテクスチャに格納した情報をソートする場合に、&lt;br /&gt;&#10;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;からCPUへデータをフィードバックしてCPUでソート、&lt;br /&gt;&#10;再び&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;に戻すよりも全部&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU"&gt;GPU&lt;/a&gt;でやったほうが速いだろうということで。&lt;/p&gt;&lt;p&gt;バイトニックソート自体はDirect Computeのサンプルなどがわかりやすいです。&lt;br /&gt;&#10;&lt;a href="https://msdn.microsoft.com/ja-jp/library/ee416561(v=vs.85).aspx"&gt;ComputeShaderSort11 &amp;#x30B5;&amp;#x30F3;&amp;#x30D7;&amp;#x30EB;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;今回のマテリアルBPを利用した方法はほぼ&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D4%A5%AF%A5%BB%A5%EB"&gt;ピクセル&lt;/a&gt;シェーダ実装なのでt-pot様も参考になると思います。&lt;br /&gt;&#10;&lt;a href="https://t-pot.com/program/90_BitonicSort/index.html"&gt;t-pot&amp;#x300E;Bitonic sort&amp;#x300F;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;バイトニックソートの大まかな流れは&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ステップ1&#10;&lt;ul&gt;&#10;&lt;li&gt;サブステップ 2要素毎に1個隣と入れ替え&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ステップ2&#10;&lt;ul&gt;&#10;&lt;li&gt;サブステップ 4要素毎に2個隣と入れ替え&lt;/li&gt;&#10;&lt;li&gt;サブステップ 2要素毎に1個隣と入れ替え&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ステップ3&#10;&lt;ul&gt;&#10;&lt;li&gt;サブステップ 8要素毎に4個隣と入れ替え&lt;/li&gt;&#10;&lt;li&gt;サブステップ 4要素毎に2個隣と入れ替え&lt;/li&gt;&#10;&lt;li&gt;サブステップ 2要素毎に1個隣と入れ替え&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ステップi&#10;&lt;ul&gt;&#10;&lt;li&gt;同様に最大要素の半分の要素毎のステップまで続ける&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;という感じです。要&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4"&gt;素数&lt;/a&gt;が 2^n の場合は合計で n*(n+1)/2 のサブステップによってソートが完了します。&lt;br /&gt;&#10;65536=2^16 なら 136サブステップです。&lt;br /&gt;&#10;実際には昇順降順を入れ違いにするので詳細は先に挙げたページを参考にしてください。&lt;br /&gt;&#10;また、バイトニックソートの制限として要&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4"&gt;素数&lt;/a&gt;が2のべき乗でないとダメなのでそのあたりはBPで調整してます。&lt;/p&gt;</description></item><item><title>UE4 内部構造が透けているように見える疑似透過シェーダ(CEDEC2018?)</title><link>https://nagakagachi.github.io/entry/2018/09/08/203717/</link><pubDate>Sat, 08 Sep 2018 20:37:17 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/09/08/203717/</guid><description>&lt;p&gt;UE4.20.2&lt;/p&gt;&#10;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/f8eedb14d990b17be3a2393435fda19ea0ea8bb5e94465427a27daf1d2f798f6.png" width="951" height="571" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;p&gt;CEDEC2018のモンスターハンター：ワールドのシェーダ関連講演で触れられていた「疑似透過シェーダ」が面白そうだったのでUE4マテリアルでやってみる.&lt;/p&gt;&#10;&lt;p&gt;MH:Wのストーリーラストのアイツのように内部が透けて見えるようなことをしたいというもの。&lt;/p&gt;&#10;&lt;p&gt;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Ftwitter.com%2Fnagakagachi%2Fstatus%2F1037723917933207552" title="X" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;br /&gt;&#10;&lt;blockquote data-conversation="none" class="twitter-tweet" data-lang="ja"&gt;&lt;p lang="ja" dir="ltr"&gt;&lt;a href="https://x.com/hashtag/UE4?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#UE4&lt;/a&gt; &lt;a href="https://x.com/hashtag/UE4Study?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#UE4Study&lt;/a&gt; 疑似透過シェーダで遊ぶ。後でブログ書いてサンプルプロジェクト貼る。BlenderとUE4を完全に理解してたらグレイマンの骨モデル作ってもっとそれっぽくできそうだけどﾑﾘ &lt;a href="https://t.co/ZfOc05uD2G"&gt;pic.twitter.com/ZfOc05uD2G&lt;/a&gt;&lt;/p&gt;&amp;mdash; なが (@nagakagachi) &lt;a href="https://x.com/nagakagachi/status/1038247245819260928?ref_src=twsrc%5Etfw"&gt;2018年9月8日&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.x.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt; &lt;br /&gt;&#10;「普通の不透明な外側モデル」の内部に「疑似透過シェーダのモデル」を配置すると&lt;br /&gt;&#10;内部のモデルが透けて見えるようになる。&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;3行説明&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Translucentマテリアルで&lt;/li&gt;&#10;&lt;li&gt;深度テスト無効で&lt;/li&gt;&#10;&lt;li&gt;SceneDepthよりPixelDepthのほうが大きい場合だけその差に応じて色を決定&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;以上&lt;/p&gt;&#10;&lt;p&gt;CEDECの講演については以下の記事の下の方。&lt;br /&gt;&#10;&lt;iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.famitsu.com%2Fnews%2F201808%2F23162839.html" title="『モンスターハンター：ワールド』開発を支えた“アーティストが作ったシェーダー”とは？【CEDEC 2018】&#9; - ファミ通.com" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"&gt;&lt;/iframe&gt;&lt;cite class="hatena-citation"&gt;&lt;a href="https://www.famitsu.com/news/201808/23162839.html"&gt;www.famitsu.com&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&#10;&lt;p&gt;講演時は内部構造モデルをカメラの方に引き寄せて描画するという説明で、内部構造モデルが手前に飛び出しているような絵で説明されていた。&lt;/p&gt;&#10;&lt;p&gt;ただ本当に頂点操作で手前に飛び出させると色々問題がありそうなのであれはあくまでイメージで、きっと深度テストの工夫でやっていたと予想。&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;追記:実際に頂点操作でやっていたらしいので深度ではないらしい&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;&lt;br /&gt;&#10;というわけで以下のように半分埋まった球を透けさせてみる。&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/dc0b457f995da4ac2cc2bc641744f6ee9619673b3ce1d12f56dce2eb3d7e1ab1.png" width="859" height="566" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;br /&gt;&#10;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;新規マテリアルを作成してメッシュにセットしておく. マテリアル名はとりあえず MAT_PseudoTranslucentTest で.&lt;/li&gt;&#10;&lt;li&gt;マテリアルの Blend Mode を Additive に変更. Opaqueだと後述する 深度テスト無効 が使えないので.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/c243fc36cb236e7051b018c89cabc4aed01a6047beee50c80c143e25982836a1.png" width="317" height="341" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;マテリアルの Disable Depth Test (深度テスト無効) をONにする.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/810a23f228b795d18625463b04112ab2def3bdbc1df65788817c4bda6a8a6a15.png" width="317" height="429" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;エミッシブに赤を入力する. 後のために乗算ノードを挟んでおく.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/18dd05b3d447b6a23824cad55560f13df0ad6630c523f20ad6db7a59a8e0bfd2.png" width="597" height="512" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;ここまででこうなる. 深度テスト無効で描いてるのだから当然.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/f582cc17f742a43033986ad6b03a5601714121bad1d9a18c29a9fa048f51b5d9.png" width="951" height="566" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;次は透過の表現のためにPixelDepthとSceneDepthの差を使ってグラデーションを計算する. PixelDepthとSceneDepthの出力はMax2048らしいので0~1の範囲にするために割っている. DepthRangeパラメータは深度差のグラデーション範囲を制御する(値は0.02). Sharpnessパラメータはグラデーションの鋭さを制御する(値は2).&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/67dc3fea909e5d3cd4714d77908881079c1b5b94c599312d5c36e9270745a96b.png" width="1024" height="317" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;ここまでで以下のようにメッシュが埋まっている部分が表面に近いほど色が濃いグラデーションになる.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/2a3ed3f8dd5a1a304fabff509e11900b1ea6cfe91ac8cd08a3678984d22c81e8.png" width="951" height="566" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;PixelDepthのほうがSceneDepthのほうが手前の場合は表示しないように条件と乗算を追加.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/bc3d37cdb47fba27f34c1399d573bf418d1be8ee92b8826c5c4d1d276a60d9bb.png" width="1024" height="403" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;埋まってる部分だけが表示される.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/707bf40683806a61aea873eaa76f518fab7da381978058d5056b9a20df8f4a1b.png" width="951" height="566" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;わかりにくいので壁メッシュのマテリアルをスターターコンテンツの"M_Tech_Hex_Tile"に変えてみたところ.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/50a2e36139559220f693971ac02179700225eecb6031c6b6ba7a95d3ceb7dc63.png" width="951" height="566" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/f8eedb14d990b17be3a2393435fda19ea0ea8bb5e94465427a27daf1d2f798f6.png" width="951" height="571" loading="lazy" title="" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;　わかりやすいように位置調整.&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;なんとなく表面からの距離によって透過度合いが変わって透けているように見えるかな？あくまで外側は普通のOpaqueマテリアルで、内部構造側のマテリアルが透けているように見せている。&lt;/p&gt;</description></item><item><title>UE4 動的にStaticMeshを生成する</title><link>https://nagakagachi.github.io/entry/2018/09/02/152927/</link><pubDate>Sun, 02 Sep 2018 15:29:27 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/09/02/152927/</guid><description>&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.20.2&lt;/p&gt;&lt;p&gt;Add Static Mesh Component ( Static Mesh Component を追加 )&lt;br /&gt;&#10;でStaticMesh&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;をアクターに新規追加&lt;/p&gt;&lt;p&gt;必要なら AttachToComponent でルート&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;に紐づけ&lt;br /&gt;&#10;必要なら Set Collision Enable などで&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%EA%A5%B8%A5%E7%A5%F3"&gt;コリジョン&lt;/a&gt;無効化などを設定&lt;/p&gt;&lt;p&gt;Set Static Mesh&lt;br /&gt;&#10;によってスタティックメッシュアセットをStaticMesh&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;に設定&lt;/p&gt;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/c8ae99346b4faa9fc02998646448a9795c7589d5f022bfeee2e9d51df35c9139.png" alt="f:id:nagakagachi:20180902151411p:plain" title="f:id:nagakagachi:20180902151411p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;球メッシュ&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;をもったアクターの周りにキューブスタティックメッシュを動的に生成してみた図&lt;br /&gt;&#10;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/424c2dd70ef240b987a40a43e786b0e0018d40252fb26cc04b6dfbcb1a4f7639.png" alt="f:id:nagakagachi:20180902152006p:plain" title="f:id:nagakagachi:20180902152006p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;p&gt;通常のStaticMeshだとDrawCallがバンバン増えるので、同一メッシュをたくさん出すなら&lt;/p&gt;&#10;&lt;p&gt;InstancedStaticMeshを使ってAddInstanceで配置したほうが良さそう&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2018/09/02/152927"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>UE4 エディタ操作をMaya風にする4.20.2</title><link>https://nagakagachi.github.io/entry/2018/09/02/124544/</link><pubDate>Sun, 02 Sep 2018 12:45:44 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/09/02/124544/</guid><description>&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC"&gt;バー&lt;/a&gt;ジョンが変わるたびに微妙に設定する場所が変わっていく&lt;br /&gt;&#10;「エディタのMaya風操作設定」&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.20.2 ではついに（もっと前から？）項目名から Maya という単語が&lt;br /&gt;&#10;消えてしまったのでメモしておく&lt;/p&gt;&#10;&lt;p&gt;エディタの環境設定&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&gt;レベルエディタ&lt;/li&gt;&#10;&lt;li&gt;&gt;ビューポート&lt;/li&gt;&#10;&lt;li&gt;&gt;Invert Middle Mouse Pan をON&lt;/li&gt;&#10;&lt;/ul&gt;&lt;p&gt;&lt;span itemscope itemtype="http://schema.org/Photograph"&gt;&lt;img src="images/74dae8ea2c3c5adf4d172015b863caab5292142076c8212bc9cb482f27b3c102.png" alt="f:id:nagakagachi:20180902124305p:plain" title="f:id:nagakagachi:20180902124305p:plain" class="hatena-fotolife" itemprop="image"&gt;&lt;/span&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2018/09/02/124544"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title> UE4 TArrayのSetNumZeroedふるまいメモ</title><link>https://nagakagachi.github.io/entry/2018/08/26/163803/</link><pubDate>Sun, 26 Aug 2018 16:38:03 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/08/26/163803/</guid><description>&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;.20.2&lt;/p&gt;&lt;p&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/UE4"&gt;UE4&lt;/a&gt;のCodePluginでTArrayを多用していていつもSetNumZeroedの挙動を忘れるのでメモ&lt;/p&gt;&lt;br /&gt;&#10;&lt;p&gt;TArray::SetNumZeroed(NewSize, bAllowShrinking)&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;SetNumZeroed()によって要&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4"&gt;素数&lt;/a&gt;が増える場合&#10;&lt;ul&gt;&#10;&lt;li&gt;ゼロ値要素が末尾に付加される。元の要素は変化しない。&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;pre class="code" data-lang="" data-unlink&gt;TArray&amp;lt;float&amp;gt; testArray;&#10;testArray.Add(1.0f);&#10;testArray.Add(2.0f);&#10;testArray.Add(3.0f); // { 1.0, 2.0, 3.0 }&#10;testArray.SetNumZeroed(5); // { 1.0, 2.0, 3.0, 0.0, 0.0 }&lt;/pre&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;SetNumZeroed()によって要&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4"&gt;素数&lt;/a&gt;が減る場合&#10;&lt;ul&gt;&#10;&lt;li&gt;単純に切り詰められる。元の要素は変化しない。&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;pre class="code" data-lang="" data-unlink&gt;TArray&amp;lt;float&amp;gt; testArray;&#10;testArray.Add(1.0f);&#10;testArray.Add(2.0f);&#10;testArray.Add(3.0f); // { 1.0, 2.0, 3.0 }&#10;testArray.SetNumZeroed(1); // { 1.0 }&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&#10;関係ないけどTArray&lt;float&gt;の要素を指定した値（ゼロとか）にするメソッドがほしい&lt;br /&gt;&#10;（ないよね？）&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2018/08/26/163803"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>最適化 Newton法メモ</title><link>https://nagakagachi.github.io/entry/2018/07/28/002457/</link><pubDate>Sat, 28 Jul 2018 00:24:57 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/07/28/002457/</guid><description>&lt;p&gt;自分の言葉で書いて覚えるため（誤りがあればご指摘ください）&lt;/p&gt;&#10;&lt;br /&gt;&#10;&lt;p&gt; 関数 &lt;span class="math-inline"&gt;\(f(\vec{x})\)&lt;/span&gt; の2次までのTaylor展開&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(f(\vec{x} + \vec{h}) = f(\vec{x}) + dot(\nabla f(\vec{x}), \vec{h}) + \frac{1}{2} dot(\vec{h^T}, \nabla^2 f(\vec{x})\vec{h})\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;ここで &lt;span class="math-inline"&gt;\(\nabla^2 f(\vec{x})\)&lt;/span&gt; はHesse行列&lt;/p&gt;&lt;p&gt;右辺を最小化にするような&lt;span class="math-inline"&gt;\(\vec{h}\)&lt;/span&gt;によって&lt;span class="math-inline"&gt;\(\vec{x}_{next} = \vec{x} + \vec{h}\)&lt;/span&gt;と更新することで&lt;br /&gt;&#10;&lt;span class="math-inline"&gt;\(f(\vec{x})\)&lt;/span&gt;をより小さくする&lt;span class="math-inline"&gt;\(\vec{x}\)&lt;/span&gt;が得られる。&lt;br /&gt;&#10;そのために&lt;span class="math-inline"&gt;\(\vec{h}\)&lt;/span&gt;で&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%F9%CA%AC"&gt;微分&lt;/a&gt;して&lt;span class="math-inline"&gt;\(=0\)&lt;/span&gt;となるような&lt;span class="math-inline"&gt;\(\vec{h}\)&lt;/span&gt;を求める&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(\frac{\mathrm{d} f(\vec{x}+\vec{h})}{\mathrm{d} \vec{h}} = \frac{\mathrm{d} f(\vec{x})}{\mathrm{d} \vec{h}} + \frac{\mathrm{d} dot(\nabla f(\vec{x}), \vec{h})}{\mathrm{d}\vec{h}} + \frac{1}{2} \frac{\mathrm{d} dot(\vec{h^T}, \nabla^2 f(\vec{x})\vec{h})}{\mathrm{d} \vec{h}} = 0\)&lt;/span&gt;&lt;br /&gt;&#10; &lt;br /&gt;&#10;右辺第一項は変数&lt;span class="math-inline"&gt;\(\vec{h}\)&lt;/span&gt;が無いので&lt;span class="math-inline"&gt;\(0\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;右辺第二項は&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C6%E2%C0%D1"&gt;内積&lt;/a&gt;をベクトル&lt;span class="math-inline"&gt;\(\vec{h}\)&lt;/span&gt;で&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%F9%CA%AC"&gt;微分&lt;/a&gt;するので&lt;span class="math-inline"&gt;\(\nabla f(\vec{x})\)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;右辺第三項は二次の同次&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C2%BF%B9%E0%BC%B0"&gt;多項式&lt;/a&gt;の二次形式&lt;span class="math-inline"&gt;\(dot(\vec{x^T}, A\vec{x})\)&lt;/span&gt;の&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%F9%CA%AC"&gt;微分&lt;/a&gt;なので、&lt;/p&gt;&lt;p&gt;&lt;span class="math-inline"&gt;\(\frac{1}{2} \frac{\mathrm{d} dot(\vec{h^T}, \nabla^2 f(\vec{x})\vec{h})}{\mathrm{d} \vec{h}} = \frac{1}{2} (\nabla^2 f(\vec{x}) + \nabla^2 f(\vec{x})^T)\vec{h}\)&lt;/span&gt;&lt;/p&gt;</description></item><item><title>確率統計の学習</title><link>https://nagakagachi.github.io/entry/2018/07/23/102540/</link><pubDate>Mon, 23 Jul 2018 10:25:40 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/07/23/102540/</guid><description>&lt;p&gt;とてつもなく優しい表現で確率統計を説明しているのでプログラミングのためじゃなくても買ってよいかもしれない&lt;/p&gt;&#10;&lt;div class="freezed"&gt;&#10;&lt;div class="hatena-asin-detail"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274067750/hatena-blog-22/"&gt;&lt;img class="hatena-asin-detail-image" title="プログラミングのための確率統計" src="images/8c59527b48b88f73f6923ec471f436a9612d9a7bdc475ca5d9c15d9ff7bcc266.jpg" alt="プログラミングのための確率統計" /&gt;&lt;/a&gt;&#10;&lt;div class="hatena-asin-detail-info"&gt;&#10;&lt;p class="hatena-asin-detail-title"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274067750/hatena-blog-22/"&gt;プログラミングのための確率統計&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;作者:&lt;/span&gt; 平岡和幸,堀玄&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;出版社/メーカー:&lt;/span&gt; &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%E0%BC%D2"&gt;オーム社&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;発売日:&lt;/span&gt; 2009/10/20&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;メディア:&lt;/span&gt; 単行本（ソフトカバー）&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;購入&lt;/span&gt;: 10人 &lt;span class="hatena-asin-detail-label"&gt;クリック&lt;/span&gt;: 133回&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/asin/4274067750/hatena-blog-22" target="_blank"&gt;この商品を含むブログ (31件) を見る&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="hatena-asin-detail-foot"&gt; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;この辺は基本を押さえるためということで&lt;/p&gt;&#10;&lt;div class="freezed"&gt;&#10;&lt;div class="hatena-asin-detail"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4130420658/hatena-blog-22/"&gt;&lt;img class="hatena-asin-detail-image" title="統計学入門 (基礎統計学?)" src="images/19c435bf69c4c757b85040d2d4d734ccf0d60e9e15ec9dca92a21d4c07d307c3.jpg" alt="統計学入門 (基礎統計学?)" /&gt;&lt;/a&gt;&#10;&lt;div class="hatena-asin-detail-info"&gt;&#10;&lt;p class="hatena-asin-detail-title"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4130420658/hatena-blog-22/"&gt;統計学入門 (基礎統計学?)&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;作者:&lt;/span&gt; &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B5%FE%C2%E7%B3%D8"&gt;東京大学&lt;/a&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%B5%CD%DC%B3%D8%C9%F4"&gt;教養学部&lt;/a&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%FD%B7%D7%B3%D8"&gt;統計学&lt;/a&gt;教室&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;出版社/メーカー:&lt;/span&gt; &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B5%FE%C2%E7%B3%D8%BD%D0%C8%C7%B2%F1"&gt;東京大学出版会&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;発売日:&lt;/span&gt; 1991/07/09&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;メディア:&lt;/span&gt; 単行本&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;購入&lt;/span&gt;: 158人 &lt;span class="hatena-asin-detail-label"&gt;クリック&lt;/span&gt;: 3,604回&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/asin/4130420658/hatena-blog-22" target="_blank"&gt;この商品を含むブログ (79件) を見る&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="hatena-asin-detail-foot"&gt; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="freezed"&gt;&#10;&lt;div class="hatena-asin-detail"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4130420674/hatena-blog-22/"&gt;&lt;img class="hatena-asin-detail-image" title="自然科学の統計学 (基礎統計学)" src="images/bd33dec7ce0c2d0a29ba8685b7dae171c25fa901941ffcd470060d90d5030e43.jpg" alt="自然科学の統計学 (基礎統計学)" /&gt;&lt;/a&gt;&#10;&lt;div class="hatena-asin-detail-info"&gt;&#10;&lt;p class="hatena-asin-detail-title"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4130420674/hatena-blog-22/"&gt;自然科学の統計学 (基礎統計学)&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;作者:&lt;/span&gt; &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B5%FE%C2%E7%B3%D8"&gt;東京大学&lt;/a&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%B5%CD%DC%B3%D8%C9%F4"&gt;教養学部&lt;/a&gt;&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%FD%B7%D7%B3%D8"&gt;統計学&lt;/a&gt;教室&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;出版社/メーカー:&lt;/span&gt; &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B5%FE%C2%E7%B3%D8%BD%D0%C8%C7%B2%F1"&gt;東京大学出版会&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;発売日:&lt;/span&gt; 1992/08/01&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;メディア:&lt;/span&gt; 単行本&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;購入&lt;/span&gt;: 26人 &lt;span class="hatena-asin-detail-label"&gt;クリック&lt;/span&gt;: 308回&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/asin/4130420674/hatena-blog-22" target="_blank"&gt;この商品を含むブログ (22件) を見る&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="hatena-asin-detail-foot"&gt; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;あと最適化関連で「これならわかる最適化数学」の次に読むものとして以下も購入&lt;/p&gt;&#10;&lt;div class="freezed"&gt;&#10;&lt;div class="hatena-asin-detail"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4621088548/hatena-blog-22/"&gt;&lt;img class="hatena-asin-detail-image" title="基礎系 数学 最適化と変分法 (東京大学工学教程)" src="images/4bdde6035410ad91fd0039ab676cdcf06905a696f6d272868151106313ca2d03.jpg" alt="基礎系 数学 最適化と変分法 (東京大学工学教程)" /&gt;&lt;/a&gt;&#10;&lt;div class="hatena-asin-detail-info"&gt;&#10;&lt;p class="hatena-asin-detail-title"&gt;&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4621088548/hatena-blog-22/"&gt;基礎系 数学 最適化と変分法 (東京大学工学教程)&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;作者:&lt;/span&gt; 寒野善博,土谷隆,&lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B5%FE%C2%E7%B3%D8"&gt;東京大学&lt;/a&gt;工学教程編纂委員会&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;出版社/メーカー:&lt;/span&gt; &lt;a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%DD%C1%B1%BD%D0%C8%C7"&gt;丸善出版&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;発売日:&lt;/span&gt; 2014/10/22&lt;/li&gt;&#10;&lt;li&gt;&lt;span class="hatena-asin-detail-label"&gt;メディア:&lt;/span&gt; 単行本（ソフトカバー）&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/asin/4621088548/hatena-blog-22" target="_blank"&gt;この商品を含むブログを見る&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div class="hatena-asin-detail-foot"&gt; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2018/07/23/102540"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>趣味プロその他の知見を残しておきたい</title><link>https://nagakagachi.github.io/entry/2018/07/16/194516/</link><pubDate>Mon, 16 Jul 2018 19:45:16 +0900</pubDate><guid>https://nagakagachi.github.io/entry/2018/07/16/194516/</guid><description>&lt;p&gt;今日から始める&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;a href="https://nagakagachi.hatenablog.com/entry/2018/07/16/194516"&gt;元のはてなブログ記事&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Test00</title><link>https://nagakagachi.github.io/lab/webgpu/introduction/test00/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nagakagachi.github.io/lab/webgpu/introduction/test00/</guid><description>&lt;p&gt;学習用にAgentCodingで生成したデモです&lt;/p&gt;&#10;&lt;p&gt;WebGPUの初期化と、最小限の描画パイプラインを確認する。下のボタンでGPUを取得し、WGSLの頂点シェーダーとフラグメントシェーダーで三角形を描画します。&lt;/p&gt;&#10;&lt;p&gt;描画は一度だけ実行します。未対応や初期化失敗の場合は、状態欄に理由を表示します。&lt;/p&gt;&#10;&lt;!-- demo --&gt;&#10;&lt;h2 id="コードの解説"&gt;コードの解説&lt;/h2&gt;&#10;&lt;p&gt;以下は実装の抜粋です。DirectX 12との対応は役割の比較であり、APIの一対一対応ではありません。全文は末尾の「ソース」から確認できます。&lt;/p&gt;&#10;&lt;h3 id="htmlの描画先とモジュール"&gt;HTMLの描画先とモジュール&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#7ee787"&gt;canvas&lt;/span&gt; id&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;gpu-canvas&amp;#34;&lt;/span&gt; width&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;960&amp;#34;&lt;/span&gt; height&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;540&amp;#34;&lt;/span&gt; &lt;span style="color:#f85149"&gt;...&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#7ee787"&gt;canvas&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#7ee787"&gt;script&lt;/span&gt; type&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;module&amp;#34;&lt;/span&gt; src&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;.../main.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#7ee787"&gt;script&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;canvas&lt;/code&gt;はHTML内の描画領域です。widthとheightは内部の描画解像度で、CSSの表示サイズとは別です。ウィンドウと表示サーフェスを用意する役割に近いものです。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;type=&amp;quot;module&amp;quot;&lt;/code&gt;でJavaScriptをモジュールとして読み込みます。このコードはブラウザのCPU側で動き、WGSLだけがGPUで実行されます。&lt;code&gt;...&lt;/code&gt;は抜粋のための省略です。&lt;/p&gt;&#10;&lt;h3 id="html要素の取得とクリック処理"&gt;HTML要素の取得とクリック処理&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; button &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; document.querySelector(&lt;span style="color:#a5d6ff"&gt;&amp;#39;#gpu-start&amp;#39;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; canvas &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; document.querySelector(&lt;span style="color:#a5d6ff"&gt;&amp;#39;#gpu-canvas&amp;#39;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;button.addEventListener(&lt;span style="color:#a5d6ff"&gt;&amp;#39;click&amp;#39;&lt;/span&gt;, &lt;span style="color:#ff7b72"&gt;async&lt;/span&gt; () =&amp;gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;document&lt;/code&gt;はブラウザが用意するHTML文書のオブジェクトです。&lt;code&gt;querySelector&lt;/code&gt;はCSSセレクターで要素を探し、&lt;code&gt;#&lt;/code&gt;はidを指定します。取得したbuttonへクリックのコールバックを登録します。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;async&lt;/code&gt;関数内の&lt;code&gt;await&lt;/code&gt;は非同期処理の結果を待ちます。UIスレッドを同期的にブロックする待ちではなく、処理を中断して結果が届いたら続きを実行します。&lt;/p&gt;&#10;&lt;h3 id="アダプターとデバイス"&gt;アダプターとデバイス&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;if&lt;/span&gt; (&lt;span style="color:#ff7b72;font-weight:bold"&gt;!&lt;/span&gt;navigator.gpu) &lt;span style="color:#ff7b72"&gt;throw&lt;/span&gt; &lt;span style="color:#ff7b72"&gt;new&lt;/span&gt; Error(&lt;span style="color:#a5d6ff"&gt;&amp;#39;このブラウザ環境ではWebGPUを利用できません&amp;#39;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; adapter &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; &lt;span style="color:#ff7b72"&gt;await&lt;/span&gt; navigator.gpu.requestAdapter();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; currentDevice &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; &lt;span style="color:#ff7b72"&gt;await&lt;/span&gt; adapter.requestDevice();&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;navigator.gpu&lt;/code&gt;はブラウザ組み込みのWebGPU APIの入口です。役割として、アダプター取得とD3D12デバイス作成に近い順序です。実装ではadapterがnullの場合も確認しています。deviceからリソースやパイプラインを作ります。&lt;/p&gt;&#10;&lt;h3 id="canvasを表示先として設定"&gt;Canvasを表示先として設定&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;context &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; canvas.getContext(&lt;span style="color:#a5d6ff"&gt;&amp;#39;webgpu&amp;#39;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; format &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; navigator.gpu.getPreferredCanvasFormat();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;context.configure({ device, format, alphaMode&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#a5d6ff"&gt;&amp;#39;opaque&amp;#39;&lt;/span&gt; });&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;CanvasのWebGPUコンテキストを取得し、デバイスと表示用フォーマットを関連付けます。swap chainの設定に近い役割ですが、DXGIのswap chainを直接操作するものではありません。&lt;code&gt;opaque&lt;/code&gt;はCanvasの表示を不透明として扱う指定です。&lt;/p&gt;&#10;&lt;h3 id="wgslファイルの取得"&gt;WGSLファイルの取得&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; shaderResponse &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; &lt;span style="color:#ff7b72"&gt;await&lt;/span&gt; fetch(&lt;span style="color:#ff7b72"&gt;new&lt;/span&gt; URL(&lt;span style="color:#a5d6ff"&gt;&amp;#39;./triangle.wgsl&amp;#39;&lt;/span&gt;, &lt;span style="color:#ff7b72"&gt;import&lt;/span&gt;.meta.url));&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; shader &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; device.createShaderModule({ code&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#ff7b72"&gt;await&lt;/span&gt; shaderResponse.text() });&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;fetch&lt;/code&gt;はURLからファイルを取得するブラウザAPIです。&lt;code&gt;import.meta.url&lt;/code&gt;は実行中のmain.jsのURLなので、そこを基準に同じフォルダのWGSLを解決します。OSのファイルパスを開いているわけではありません。&lt;/p&gt;</description></item><item><title>Test01</title><link>https://nagakagachi.github.io/lab/webgpu/introduction/test01/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nagakagachi.github.io/lab/webgpu/introduction/test01/</guid><description>&lt;p&gt;学習用にAgentCodingで生成したデモです&lt;/p&gt;&#10;&lt;p&gt;Uniform BufferでCPU側から角度を渡し、頂点シェーダーで三角形を回転させる。初期化から描画まで、このTest内で独立して実装します。&lt;/p&gt;&#10;&lt;h2 id="操作"&gt;操作&lt;/h2&gt;&#10;&lt;p&gt;「開始」でGPUを初期化して回転を開始します。「停止」で回転を止めます。停止中でも角度スライダーで描画を更新できます。「再開」でその角度から回転を再開します。回転速度は毎秒45度です。別タブへ移ると自動で停止します。&lt;/p&gt;&#10;&lt;!-- demo --&gt;&#10;&lt;h2 id="コードの解説"&gt;コードの解説&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="../test00/"&gt;Test00&lt;/a&gt;で説明したデバイス・Canvas・Shader Module・基本のDraw処理は省略し、追加した部分を抜粋します。実装自体はTest00のコードを参照せず、このTestだけで完結しています。&lt;/p&gt;&#10;&lt;h3 id="htmlの角度入力"&gt;HTMLの角度入力&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#7ee787"&gt;input&lt;/span&gt; id&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;gpu-angle&amp;#34;&lt;/span&gt; type&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;range&amp;#34;&lt;/span&gt; min&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;0&amp;#34;&lt;/span&gt; max&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;360&amp;#34;&lt;/span&gt; step&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;1&amp;#34;&lt;/span&gt; value&lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;0&amp;#34;&lt;/span&gt; disabled&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ブラウザ標準のスライダーです。0～360度を1度刻みで入力します。初期化成功後にdisabledを解除します。HTMLの入力値は文字列なので、JavaScriptで数値へ変換します。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;slider.addEventListener(&lt;span style="color:#a5d6ff"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;, () =&amp;gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; angle &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; Number(slider.value);&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;input&lt;/code&gt;は値を変更している途中にも届くイベントです。停止中もこのイベントからdrawを1回呼び、CPU→GPUの値の更新を確認できます。&lt;/p&gt;&#10;&lt;h3 id="cpu側のデータとgpubuffer"&gt;CPU側のデータとGPUBuffer&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;const&lt;/span&gt; uniformData &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; &lt;span style="color:#ff7b72"&gt;new&lt;/span&gt; Float32Array(&lt;span style="color:#a5d6ff"&gt;4&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;uniformBuffer &lt;span style="color:#ff7b72;font-weight:bold"&gt;=&lt;/span&gt; device.createBuffer({ size&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#a5d6ff"&gt;16&lt;/span&gt;, usage&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; GPUBufferUsage.UNIFORM &lt;span style="color:#ff7b72;font-weight:bold"&gt;|&lt;/span&gt; GPUBufferUsage.COPY_DST });&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Float32Arrayは32ビットfloatを連続配置するJavaScriptのTyped Arrayです。GPU用のメモリそのものではなく、CPU側の転送元です。4要素・16バイトを確保します。GPUBufferにはuniform用途と書き込み先用途を指定します。&lt;/p&gt;&#10;&lt;h3 id="wgslの定数バッファ"&gt;WGSLの定数バッファ&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-wgsl" data-lang="wgsl"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;struct&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;Uniforms&lt;span style="color:#6e7681"&gt; &lt;/span&gt;{&lt;span style="color:#6e7681"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;rotation:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;vec4f,&lt;span style="color:#6e7681"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&lt;span style="color:#6e7681"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#d2a8ff;font-weight:bold"&gt;@group&lt;/span&gt;(&lt;span style="color:#a5d6ff"&gt;0&lt;/span&gt;)&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#d2a8ff;font-weight:bold"&gt;@binding&lt;/span&gt;(&lt;span style="color:#a5d6ff"&gt;0&lt;/span&gt;)&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#ff7b72"&gt;var&lt;/span&gt;&lt;span style="color:#ff7b72;font-weight:bold"&gt;&amp;lt;&lt;/span&gt;uniform&lt;span style="color:#ff7b72;font-weight:bold"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;uniforms:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;Uniforms;&lt;span style="color:#6e7681"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HLSLのcbufferに近い宣言です。4成分の内容は角度・アスペクト比・未使用・未使用です。group/bindingはWebGPUのバインド番号で、HLSLのregisterやspaceの番号へ直接対応するわけではありません。&lt;/p&gt;&#10;&lt;h3 id="リソースのレイアウト"&gt;リソースのレイアウト&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;binding&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#a5d6ff"&gt;0&lt;/span&gt;, visibility&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; GPUShaderStage.VERTEX,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;buffer&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; { type&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#a5d6ff"&gt;&amp;#39;uniform&amp;#39;&lt;/span&gt;, minBindingSize&lt;span style="color:#ff7b72;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#a5d6ff"&gt;16&lt;/span&gt; },&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;createBindGroupLayout&lt;/code&gt;のentryです。binding 0がuniform bufferで、頂点ステージから読み、少なくとも16バイトを必要とする契約を定義します。Root Signatureでリソースの種類・位置・Shader Visibilityを記述する役割に近いものです。&lt;/p&gt;</description></item></channel></rss>