【Shader Graph】UVに依存しない「Triplanarノイズ」の作り方

Triplanarなノイズの作り方 ゲーム制作メモ

今回はUnityのShader Graphに関する上級者向けの話題で、タイトルの通り「UVに依存しないノイズの作り方」についての話です。

はじめに前提として、Shader Graphにはデフォルトで「Triplanarノード」があり、テクスチャ画像であればUVに依存しない投影が可能となっています。しかしShader Graphを使い込んでいるとテクスチャを使わずに色々な模様を作りたくなる場合が多いのですが、そのときに最もよく使うノイズ系のノードはデフォルトではUVに依存しない投影を行うことが不可能です。

そこでここでは、既存のTriplanarノードの仕組みを解析し、それをノイズ用に改造したサブグラフを作るまでの流れを書いていきますね。

スポンサーリンク

「Triplanarなノイズ」を適用した場合の結果

では、まずは今回の主題である「UVに依存しないTriplanarなノイズ」と、「デフォルトのノイズ」をそれぞれ3Dモデルにそのまま適用した結果を掲載します。

UVに依存しないTriplanarノイズ

Triplanarノイズ

デフォルトのノイズ

デフォルトのノイズ

違いは一目瞭然ですね!TriplanarなノイズはUVに関係なく均一にノイズが投影されているのに対して、デフォルトのノイズはUVに依存しているので3Dモデルによってノイズのスケール等がバラバラな状態で投影されてしまっています。

テクスチャ用のTriplanarノードの仕組みについて知る

さてTriplanarなノイズを作るためには、とにかくTriplanarノードがどのように実装されているのかを知る必要があります。そこでShader Graphのマニュアルを見てみますと、Triplanarノードの説明に次のようなコードが掲載されています:

float3 Node_UV = Position * Tile;
float3 Node_Blend = pow(abs(Normal), Blend);
Node_Blend /= dot(Node_Blend, 1.0);
float4 Node_X = SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.zy);
float4 Node_Y = SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.xz);
float4 Node_Z = SAMPLE_TEXTURE2D(Texture, Sampler, Node_UV.xy);
float4 Out = Node_X * Node_Blend.x + Node_Y * Node_Blend.y + Node_Z * Node_Blend.z;

これがTriplanarノード内で行われている処理ですね。ただこのままでは意味がよく分からないのですが、ググってみるとTriplanarマッピングについての詳しい説明がありました。

2DテクスチャをUVを使わずに投影するTri-Planar Texture Mapping - Qiita
概要 Shadertoyのこの作品を見ていたら知った手法。 通常の2Dテクスチャを3Dモデルの位置と法線から投影するように貼り付ける方法です。 詳細については以下の記事をご覧ください。 今回はこれを理解するために自分なりのメモ...

端的に言うと、3Dモデルに対してX、Y、Z軸のそれぞれの方向からテクスチャを貼りつけてブレンドする…というような処理になっているようです。

「UVに依存しないノイズ」のサブグラフ

では調べてわかったことを元にして、今回の主題である「Triplanarなノイズ」のサブグラフを作ってみましょう。サブグラフの全体図は次の図の通りです。

Triplanarなノイズのサブグラフ

基本的には先ほどのコードを真似してShader Graphに落とし込み、テクスチャの部分をノイズに置き換えただけです。ただしブレンドの計算では、Dot Productで割り算すると結果が変になったのでそこを省略してあります。

おわりに

以上、「UVに依存しないノイズの作り方」についてのお話でした。非常にマニアックな内容でしたが、今回作ったノイズを使いこなせればShader Graphの表現幅がぐっと広がると思うので是非ご活用いただければと思います。

この記事がゲーム制作のお役に立てば幸いです。