読者です 読者をやめる 読者になる 読者になる

Transition

プログラミング・数学の学習の記録

UE4のマテリアルでマスクとLerpを使う

UE4のマテリアルに関する日本語での解説やチュートリアルがほぼなくて僕自身困っていたのですが、サンプルのマテリアルと公式のドキュメントを読んで少し理解できたと思うので、ここに書いておきます。

最初に断っておきますが、僕自身シェーダーについての知識はないので間違っていることを書いてるかもしれませんが、そのときはぜひご指摘をお願いします。

では岩のマテリアルを例にみていきます。

なぜあんなにサンプルのマテリアルは複雑怪奇なノード構成になっているの?

まずサンプルをみてこう思った人多いんじゃないでしょうか。

f:id:idetatsu:20140709171940p:plain

なぜこんなシンプルなマテリアルじゃだめなのか?と。これは2048 × 2048のテクスチャとノーマルマップの2枚だけを使用しています。

ではこのマテリアルを実際に岩のメッシュに適用してみます。ちなみにテクスチャ、メッシュともモデリングソフトで作ったものです。

こちらです。

f:id:idetatsu:20140709172401p:plain

全体的にぼけぼけで、ディテールが失われ、情報量が足りなく、美しくありません。

これを解決していきます。

メッシュ上に十分な情報量、テクセル解像度を持たせるためにマスクを使う

ここでサンプルのマテリアルを見てみます。サンプル「VehicleGame」のM_Cliffsというマテリアルです。

f:id:idetatsu:20140709174237p:plain

ちょっと複雑すぎるのですが、公式のドキュメント

Unreal Engine | Material Expression Reference

を参考に一個一個ノードを読んでいくと、どうやらマスク用のテクスチャを使って部分ごとに質感を変化させているらしいことがわかります。これがこのマテリアルで使われているマスクテクスチャT_Cliff_Mです。

f:id:idetatsu:20140709175945p:plainUE4のサンプルには似たようなマスクテクスチャがたくさん入っています。

パッと見何がなんなのか分からない画像ですが、これは単純にRGBAの各チャンネルにグレースケールのマスクが格納されているだけです。左上の「View」をクリックしてRチャンネルだけ表示してみるとこのようになっています。

f:id:idetatsu:20140709181203p:plain

サンプルではこのようなマスク用テクスチャの各チャンネルに格納されたグレースケール画像を用いて、黒い部分と白い部分とで質感の変化をつけています。

Lerpを使って変化をつける

では、先ほどの岩にマスクを用いて変化をつけてみます。Gチャンネルに下の画像のようなマスクを格納したテクスチャを作成しました。

f:id:idetatsu:20140709183015p:plain

まずはこの黒い部分に赤色をつけてみます。ここで使うのはLerpMultiplyというノードです。

f:id:idetatsu:20140709183958p:plain

ノード構成はこのようになりました。

Lerpとは線形補間を行うノードです。ざっくり言ってしまえば2つの値をとって黒いところと白いところにそれぞれに対応させる、といった感じでしょうか。

MultipyはPhotoshopなどの乗算レイヤーのようなことを行うノードです。ほかにも単純に値同士の掛け算に用いたりします。

結果は以下のとおりです。

f:id:idetatsu:20140709185823p:plain

マスク上で黒い部分は赤くなっています。

これを応用させてこんなマテリアルを作ってみました。

f:id:idetatsu:20140709192557p:plain

f:id:idetatsu:20140709193031p:plain

サンプル中に含まれる岩のテクスチャ「T_RocksCliffs_D」をマスクの白い部分に、砂のテクスチャ「T_Sand_D」を黒い部分にLerpでそれぞれ対応させています。

ノーマルに関しても同じことをやっていますが、ここではBlendAngleCorrectedNormalsというマテリアルファンクションを使用してもともとのノーマルマップと合成しています。

ほかにはTexCoordノードなどをつかってタイリングを調整したりしていますが、マスクとLerpを使うことでサンプルのように十分な解像度を得ることができました。

 

質問、ご指摘等ありましたらTwitterID @idetatsuuuuuuuuまでお願いします。