2016年9月13日

UE4 でノイズを最大限活用する

作成 Ryan Brucks

UE4 にはマテリアル ベースのプロシージャルなノイズが以前からありますが、ほとんどのユーザーはその使用を制限せざるを得ませんでした。パフォーマンス コストが高いからです。その結果、多くのユーザーはタイリングのノイズ テクスチャを別のプログラムで作成し、それを使用するために UE4 に取り込んでいました。このステップを UE4 内で行いたいという声はありましたが、簡単に行う方法がありませんでした。

アンリアル エンジン 4.13 ではこのニーズに応えました。改善点は、以下のカテゴリに分類されます。

1) タイリングのノイズのオプション
2) 新たに追加された Voronoi (ボロノイ) ノイズ
3) パフォーマンスの最適化とその他の改善事項

まず、タイリングと Voronoi のオプションの作業に私と一緒に携わっていただいたレンダリング エンジニアであり、教授でもある Marc Olano 氏に謝意を表します。パフォーマンスの改善とコードのクリーンアップも行ってくださいました。多くの既存オプションも最適化されて、ツールチップには負荷の内容が示されるようになりました。こうした最適化によって大幅な改善が施されましたが、プロシージャルなノイズのほとんどは、今だにレンダリングの負荷が高いものです。そのため、静的テクスチャのベイクができるタイリングのノイズ オプションについて最初にお話しします。最後のセクションでは、様々なノイズ関数の相対的な負荷も示します。

タイリングのノイズ

4.13 では、Noise ノードをマテリアルに配置し、それを選択すると、下部に 2 つの新しいオプション、[Tiling] と [Repeat Size] があるのがわかります。

noiseNode

[Tiling] にチェックを入れると、ノイズは指定した [Repeat Size] (ドメイン) で繰り返されます。タイリングのノイズをベイクするためのセットアップは非常に単純です。[Repeat Size] は、ベイクするサンプリングしたサイズに一致するようにします。これを行う最も簡単な方法は、入力位置にデフォルトの 0-1 Texture Coordinate を使用して、Scale と Repeat Size を上の画像のサンプルと同じように設定することです。

位置に対してデフォルトの 0-1 UV を使うのは、新しい [Draw Material to Render Target] 機能を使って、テクスチャーをベイクするためです。この機能は、レンダリング エンジニアの Daniel Wright 氏のご厚意によるものです。この記事では、この機能で可能なことのごく一部を紹介します。以下のようにセットアップしたら、関連操作で何回でも再利用できるので頑張ってください。

最初に、コンテンツ ブラウザで新しい Actor ブループリントを作成する必要があります。[Add New] をクリックし、Blueprint クラスをクリックします。新規ダイアログがポップアップしたら、Actor をクリックし、アセットに名前を付けます。

次に、コンテンツ ブラウザでレンダー ターゲットを作成する必要があります。[Add New] 、[Materials and Textures] 、 [Render Target] の順にクリックします。その後、この新しいレンダー ターゲットをダブルクリックし、解像度をベイクするサイズに設定します。あと少しで終わります。

新規に追加したブループリントを開いて、[Event Graph] に進みます。Custom Event を追加し、"Bake" と名前を付けます。ベイクするマテリアルを指定し、作成した Render Target を指定します。

次に、コンストラクション スクリプトに進んで、Custom Event の Bake を呼び出します。

bakeNode

constructionNode

ブループリントをコンパイルしたら、マテリアルがレンダー ターゲットに書き込まれます。レンダー ターゲットを右クリックして、 [Create Static Texture] を選択すればテクスチャが作成されます。

createStaticTex

Voronoi Noise

Voronoi ノイズは、大きくうねる雲、コースティックなど自然界で見られる様々なパターンに適しています。Worley ノイズや Cellular ノイズと呼ばれることもありますが、すべて同じようなものです。以下は細かい設定なしに作成できる基本的なものの例です。

voroniNoise

左から右に説明します。
1) 1 オクターブ、Power = 2
2) 1 オクターブ、反転 (1-x)
3) 3 オクターブ反転

以下は UE4 で全体を Voronoi ノイズを使って作られたひび割れた土です。

crackedFloor1

crackedFloor2

以下はその作成ステップです。

noiseBreakdown

左から右に説明します。
1) 1 オクターブの Raw Voronoi ノイズ、反転
2) 少量の "Gradient" ノイズを入力位置に追加して歪みを適用した Voronoi ノイズ
3) エッジのディテールを平均化 (イコライズ) する High Pass マテリアルでサンプリングした Voronoi ノイズ
4) Normal from Heightmap 関数を使って法線マップを生成。

最後の砂の画像は、上のステップ 3 のテクスチャを [Parallax Occlusion Mapping] マテリアルのハイトマップとして使って作成されました。

High Pass は、新しいマテリアル関数、High Pass Texture を使って行われました。エッジにバリエーションを付けるには、別の Gradient ノイズを追加して、オフセットの幅を変化させます。この High Pass 関数のバージョンでは、この時点のテクスチャが以下を使用するために保存されることを想定しています。

materialSetup

テクスチャの代わりに関数をとる方式の、 “High Pass Function” のバージョンもあります。

法線をベイクするには、上のステップ 3 の結果をレンダー ターゲットにベイクし、Normal From Heightmap 関数を使って、このマテリアルを RT にレンダリングします。

normalFromHeightMap

ハイパス オフセットを減らす、ハイパス強度を増やすなどのわずかな変更で、以下のようなコースティック テクスチャのようなバリエーションを作成することができます。

caustics

以下は定型化された大きくうねる雲です。

smokeyPillar

このエフェクトは、2 つの単純な Voronoi テクスチャを Panning テクスチャとしてサンプリングして作成されます。テクスチャは掛け合わされ、平方根を取ってふっくらとした大きくうねる形状を維持します。これは細分化されたシリンダー メッシュに適用されます。World Position Offset に接続する前に、ワールド空間の法線によって最終的な高さは乗算処理されます。

materialSetuo

以下は Voronoi ベースの大理石の例です。

voroniMarble

以下で Voronoi ノイズを使って大理石タイプのテクスチャを作成する方法を説明します。

voroniMarbleWorkflow

左から右に説明します。
1) 標準 Voronoi ノイズ、1 オクターブ
2) "Gradient" ノイズを入力位置に追加した Voronoi ノイズ、 0.05 に設定
3) Voronoi 入力位置に追加する前に、0.3 の乗算処理をした Gradient ノイズ
4) ステップ 3 の結果を、以下からのランダム テクスチャの Texture Coordinate として使用します。engine\content:

Texture2D'/Engine/Engine_MI_Shaders/T_Base_Tile_Specular.T_Base_Tile_Specular'

これはグラデーション マッピングという技術を使ったものです。使用する色の正確な範囲は、テクスチャに入力する前に結果に追加または結果を乗算処理して制御することができます。参照するカスタム テクスチャをペイントする、または使いたい色がある任意の画像を使用することができます。

marbleMaterial

この例は、スカラーの歪みを入力位置に加えます。上の画像からわかるように、斜めのストリーク パターンになります。大理石の場合はこれは問題ありませんが、他のエフェクトの場合、X と Y の歪みや法線マップを使用するオフセットに対して別のノイズ パターンを使用します。

Voronoi ノイズの負荷に関する注意事項

​​Voronoi ノイズは負荷が高く、4 種類のクオリティ レベルを使用することができます。その違いは、検索するセル数です。一般的に、クオリティの数字が大きくなるほど、グリッドのアーティファクトは少なくなります。Voronoi ノイズのノードを配置すると、デフォルトで 6 オクターブに設定されますが、1 オクターブに対する命令数しか表示されません。

Quality 1 は 8 セルを検索、  1 オクターブあたり ~160 命令
Quality 2 は 16 セルを検索、  1 オクターブあたり ~320 命令
Quality 3 は 27 セルを検索、  1 オクターブあたり ~540 命令
Quality 4 は 32 セルを検索  1 オクターブあたり ~640 命令

比較の参考として、通常のマテリアルでは 100 命令程度です。Quality 4 の 6 オクターブの Voronoi ノイズのマテリアルは約 3800 命令であり、約 30 倍レンダリングの負荷が高くなります。Quality 1 の 1 オクターブの Voronoi ノイズは、わずか 160 命令であり、基本的なマテリアルに対して妥当なものです。

octaves

左から右に説明します。
1) Quality 1
2) Quality 2
3) Quality 3
4) Quality 4

Quality 2 は他のものに比べて少々暗めになっています。これは、 2 つのオフセットの 2x2x2 グリッドを使っているからです。つまり、こうしたポイントではより高密度になっています。これは、2 で乗算処理することで簡単に対処できます。

パフォーマンスの特性

ノイズ ノードを使う実際の負荷を示すために、フル スクリーンのクワッドを使って 1-6 レベルのオクターブで各関数のパフォーマンス コストを測定しました。通常の Texture Sample との比較も追加しました。通常の Texture Sample に対して、オクターブのサンプルが追加されました。

noisePerformance

予測どおり、ほとんどのノイズ オプションは、シンプルなテクスチャ ルックアップに比べて著しく遅くなります。“Fast Gradient - 3D Texture” は、ボリューム テクスチャにベイクされているため、ノイズ関数のなかで群を抜いて速いものです。これに対して、“Texture Based” オプションでは、2D ノイズ テクスチャを使ってランダムさの演算を行いますが、これは 3D としてサンプリングするために演算を追加する必要があります。プロシージャルなノイズを使う必要があり、シーンのレンダリングを高速に保つには、現時点では “Fast Gradient” が最良ですが、大きなエリアに対して使用したり、タイリングの数が増えすぎれば繰り返しが表れます。

高品質の Voronoi ノイズ関数は最も負荷が高くなります。したがって、パフォーマンスの制約がある環境で使用する必要があれば、テクスチャにベイクすることが重要です。

この記事が皆さんのお役に立ち、実際のプロジェクトで効果的なノイズの使用につながれば幸いです。