スタイライズのルック開発


Kuwahara Filter

Kuwaharaフィルターのウィンドウ

Kuwaharaフィルターはもともと、エッジを保持しながら画像のノイズを減らすために開発されました。
上の図は、Kuwaharaフィルターがピクセルを平均化する様子を示しています。結果は絵画のようなイメージになります。

https://en.wikipedia.org/wiki/Kuwahara_filter

Unreal Engine用のKuwaharaフィルターコードの書き方を詳しく説明した素晴らしいチュートリアルがYouTubeにあります⇩

最終的なノード配置

Kuwahara C# Code

float sobelX[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1};
float sobelY[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1};

float3 mean[4] = {
	{0,0,0},
	{0,0,0},
	{0,0,0},
	{0,0,0}
};

float3 sigma[4] = {
	{0,0,0},
	{0,0,0},
	{0,0,0},
	{0,0,0}
};

float2 offsets[4] = {{-Radius.x, -Radius.y}, {-Radius.x, 0}, {0, -Radius.y}, {0, 0}};

float2 pos;
float3 col;

float gradientX = 0;
float gradientY = 0;

int index = 0;

float2 texelSize = 1.0/ViewSize;


for(int x = -1; x <= 1; x++)
{
	for(int y = -1; y <= 1; y++)
	{
		if(index == 4)
		{
			index++;
			continue;
		}
		float2 offset = float2(x, y) * texelSize;
		float3 pxCol = SceneTextureLookup(UV + offset, 14, false).xyz;
		float pxLum = dot(pxCol, float3(0.2126, 0.7152, 0.0722));

		gradientX += pxLum * sobelX[index];
		gradientY += pxLum * sobelY[index];

		index++;
	}
}

float angle = 0;
if(abs(gradientX) > 0.001)
{
	angle = atan(gradientY / gradientX);
}

float s = sin(angle);
float c = cos(angle);

for(int i = 0; i < 4; i++)
{
	for(int j = 0; j <= Radius.x; j++)
	{
		for(int k = 0; k <= Radius.y; k++)
		{
			pos = float2(j, k) + offsets[i];
			float2 offs = pos * texelSize;
			offs = float2(offs.x * c - offs.y * s, offs.x * s + offs.y * c);
			float2 uvpos = UV + offs;
			col = SceneTextureLookup(uvpos, 14, false);

			mean[i] += col; 
			sigma[i] += col * col;
		}
	}
}

float n = (Radius.x+1)*(Radius.y+1);
float sigma_f;

float min = 1;

for(int i = 0; i < 4; i++)
	{
		mean[i] /= n;
		sigma[i] = abs(sigma[i] / n - mean[i] * mean[i]);
		sigma_f = sigma[i].r + sigma[i].g + sigma[i].b;

		if(sigma_f < min)
		{
			min = sigma_f;
			col = mean[i];
		}
	}

	return col;


Kuwaharaフィルターの実装

上の動画で見られるように、その結果は絵画のようです。
ただし、半径が増加すると、パフォーマンスに大きな影響を与える可能性があります。

Kuwahara + アウトライン

カメラ距離のブレンドを使用したポストプロセスのアウトラインを追加しました。最終的な効果はどう思いますか?



この記事が気に入ったらサポートをしてみませんか?