<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Shader on ながむしメモ</title><link>https://nagakagachi.github.io/categories/shader/</link><description>Recent content in Shader on ながむしメモ</description><generator>Hugo</generator><language>ja-JP</language><lastBuildDate>Sat, 02 Mar 2024 14:07:04 +0900</lastBuildDate><atom:link href="https://nagakagachi.github.io/categories/shader/index.xml" rel="self" type="application/rss+xml"/><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 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>縮小バッファによる半透明パーティクル描画についてのメモ</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>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>行優先と列優先のはなし(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></channel></rss>