Custom Nodeの作成(Shader Graph Version7.3.1)

Custom Nodeの作成(Shader Graph Version7.3.1)

 Unityではシェーダを視覚的に作成できる「Shader Graph」が使用できます。このShader Graphでは様々なノードが利用でき、それらを繫げることでシェーダを作成します。このノードの中にCustom Function Nodeがあり、これを利用することでオリジナルのノードを作成することができます。

ノードへ直接記述する方法

 Shader Graphを開き、Custom Functionを追加します。このノードの歯車をクリックすると以下のようにメニューが表示されます。

TypeをStringにするとBodyが表示されます。ここへ、hlslコードを直接記述します。

試しに、UV座標をx成分、y成分へ分けるノードを作成します。Inputsの+から入力用の変数UVを追加します。さらに、Outputsの+から出力用の変数X及びYを追加します。

ノードの名前を入力し、BodyへUVのx成分をOutputsのXへ、y成分をOutputsのYへ出力するコードを記述します。

これで、Custom Function Nodeが完成しました。新しく作成したノードへUV座標を入力し、出力X、YをPreviewによって表示すると

となり、ノードが意図したとおりに動作していることが分かります。

ファイルを利用する方法

 前回作成したタイリング可能なセルラーノイズをファイルを用いてノードへ追加します。新しくhlslファイルを作成します。このhlslファイルへ記述した関数を利用することができます。ノードで利用する関数には、関数名へfloatを追加で記述する必要があります(関数名_float)。

#ifndef MYHLSLINCLUDE_INCLUDED
#define MYHLSLINCLUDE_INCLUDED
void TilingVoronoi_float()
{
・・・
}
#endif

次に、ノードの入出力値を関数の引数へ記述します。下記関数ではfloat2 UV, int Scale, int Seed, float2 Offsetが入力値、out float Outが出力値となります。

#ifndef MYHLSLINCLUDE_INCLUDED
#define MYHLSLINCLUDE_INCLUDED
void TilingVoronoi_float(float2 UV, int Scale, int Seed, float2 Offset, out float Out)
{
・・・
}
#endif

タイリング可能なセルラーノイズのコードを全て記述すると以下のコードとなります。

#ifndef MYHLSLINCLUDE_INCLUDED
#define MYHLSLINCLUDE_INCLUDED

int2 tiling_position(float2 st, float scale)
{
	float eps = 0.1;
	int2 sig = step(0.0, st);
	int2 p = fmod(floor(st), scale) + eps * sign(st);
	p = p * sig + (scale + p) * sign(-p) * (1 - sig);

	return p;
}

float2 rand2d(float2 st, int seed)
{
	float2 s = float2(dot(st, float2(127.1, 311.7)) + seed, dot(st, float2(269.5, 183.3)) + seed);
	return frac(sin(s) * 43758.5453123);
}

float Tiling_CellularNoise(float2 st, int scale, int seed)
{
	float2 f_st = frac(st);

	float min_dist = 1.0;
	float2 min_p;
	for (int j = -1; j <= 1; j++)
	{
		for (int k = -1; k <= 1; k++)
		{
			float2 n = float2(j, k);
			float2 p = rand2d(tiling_position(st + n, scale), seed);
			float dist = distance(f_st, p + n);
			if (dist < min_dist)
			{
				min_dist = dist;
				min_p = p;
			}
		}
	}
	return min_dist;
}

void TilingCellularNoise_float(float2 UV, int Scale, int Seed, float2 Offset, out float Out)
{
	UV = UV * Scale + Offset;

	float result = Tiling_CellularNoise(UV, Scale, Seed);

	Out = result;
}

#endif

このhlslファイルをノードで利用できるよう設定をします。まずは、Custom Functionノードを新規作成します。

Sourceへ先ほど作成したhlslファイルを設定します。そして、Nameを_floatを除いた関数名(TilingCellularNoise)を入力します。

次に、Inputsの+から入力用の変数(UV、Scale、Seed、Offset)を、Outputsの+から出力用の変数(Out)を追加します。変数名はhlslファイルに記述した変数名と異なる名前でも問題ありません。

これで、新しくTilingCellularNoiseノードを作成することができました。この新しく作成したノードへUVノードをつなげると

となり、問題なく動作していることが分かります。

※Color Spaceの設定が異なっているため、前回と見た目が変わっています(前回はGamma、今回はLinear)。

参考サイト

Unity:Custom Function Node