マテリアルノードの解説 その2

マテリアルノード解説第2弾はテクスチャ関係をやりましょう。

カテゴリとしては、Coordinates、Textureと他一部って感じです。

前回やったMathカテゴリと併せて利用すれば、大半の表現はできるようになると思います。

テクスチャをサンプリング(UV座標からテクスチャのカラーなどを取得する行為。テクスチャフェッチなどとも)するのはマテリアルの基本です。

Playstation、SegaSaturnなどの時代ではまだテクスチャを貼らずにポリゴンカラーだけで表現されるゲームもありましたが、PS2時代にはさすがに全滅していた…と思います。

PS時代ですらほとんどなかったはずですが、確か有名な『修羅の門』ではキャラクタにテクスチャが貼られてなかった記憶があります。

では、進めていきましょう。

・TextureSample, TextureSampleParameter2D, etc...

ue125.jpg

テクスチャをサンプリングする各種ノードです。

TextureSampleは入力されたUV値を用いて設定されているテクスチャのカラーを取得します。

設定されたテクスチャはマテリアルで固定されるため、外部から変更することはできなくなります。

また、設定されるテクスチャによってUV値がfloat2ではなくfloat3になります。

具体的には設定したテクスチャがキューブマップの場合はfloat3が必要です。

また、法線マップを設定した場合は出力されるパラメータがタンジェントスペースでの法線をサンプリングします。

通常、法線マップというのはテクスチャ座標空間における法線を格納しています。

正確には、法線の各要素に0.5を掛けて0.5を足した値が入っていますが、UE4をそのまま使う分にはこの辺は考えなくてもいいです。

テクスチャ座標空間というのは、基本的にU方向がX軸、V方向がY軸、画面手前側(テクスチャを板とした見た場合の法線方向)がZ軸となります。

ここから取得した法線を使ってマテリアル内で何らかの計算をする場合、そのままの利用だと支障をきたす場合があります。

ただし、マテリアル出力の法線にはタンジェントスペースの法線を入力すればOKです。

TextureSampleParameterは2D, Cube, Movie, SubUVの4種類が存在します。

これらはTextureSampleとは違って外部から変更することが可能ですが、使用するテクスチャの種類についてだけは固定化されています。

TextureSampleParameter2Dにキューブマップを指定したりはできません。

なお、TextureSampleParameterSubUVはParticleSubUVのパラメータバージョンです。

・FontSample, FontSampleParameter

ue126.jpg

フォントテクスチャ用のサンプリング命令と、そのパラメータバージョンです。

TextRendererComponentで使用することを目的としたノードですが、現状ではフォントテクスチャの特定ページしか利用できません。

3D空間中に長い日本語文章を表示しようとするとこの制限が問題になりますね。

ただ、この制限はバグだという話もあるので、そのうち修正されるかもしれません。

・SceneColor, SceneTexture

ue127.jpg

SceneColorはイマイチよくわからないです。

説明を見る限りだとフレームバッファを取得できるんじゃないかと思うのですが、どうもそうじゃないっぽいんですよね。

リファレンスを見てもよくわからないので、詳しい方、教えてください。

使用できるのはポストプロセスと半透明マテリアルのみです。

SceneTextureはポストプロセスのみで使用可能なシーンとして保存している各種テクスチャです。

フレームバッファや深度バッファ、GBufferなどを取得して加工、様々なポストプロセスに利用するという感じです。

Detailタブの[Scene Texture Id]から取得したい情報を選択できます。

・TextureCoordinate

ue128.jpg

いわゆるUV座標です。モデルデータとして設定されているUVの値を利用します。

2Dテクスチャのサンプリングで特にUVを指定していない場合はデフォルト状態のこのノードを入力したのと同じ結果になります。

Detailsタブでは使用するUV座標の通し番号(デフォルトは0番)と、繰り返し回数の指定ができます。

繰り返し回数はUV座標をスケーリングするのと同じ効果を持ちます。

UVを時間経過に合わせて移動したり歪ませたりするには、このノードの出力を加工してテクスチャサンプルを行ってください。

・Panner, Rotator

ue129.jpg

UV座標の平行移動を行うのがPanner、回転を行うのがRotatorです。

どちらもCoordinate入力ピンに何も入れないと0番のUV座標を未加工で利用します。

Pannerは一定速度で平行移動させるのに便利です。UV座標それぞれの平行移動速度を指定し、入力のTimeを変更してやると平行移動します。

速度を0.0にするとその方向には移動しないので、それぞれの方向に対応するのも難しくありません。

ただし等速運動となるため、デザイナさんが指定したカーブを使いたい場合は自前でUV座標を加工した方がよいでしょう。

RotatorはPannerと同様の等速回転運動を行います。

こちらは、回転の中心座標(UV値なので0.0~1.0が基本)と速度を与えて、それからTimeピンの入力によって変更することができます。

・WorldPosition, PixelNormalWS, VertexNormalWS

ue130.jpg

WorldPositionはその名の通り、そのピクセルのワールド空間中の座標を取得します。

マテリアル出力としてWorld Position Offsetを指定できますが、これを無視するかどうかの指定が可能です。

また、カメラからの相対座標を取得することも可能ですが、これはカメラ空間での座標ってことかな?

PixelNormalWSとVertexNormalWSはワールド空間中の法線を取得します。

マテリアル出力のNormalに何も出力しない場合はこの2つはどちらも同じ結果になります。

Normalに何かを出力した場合(例えば、法線マップのサンプリング結果)、PixelNormalWSで取得できる法線が法線マップの結果をワールド空間に変換したものとなります。

そのため、PixelNormalWSの結果はNormalに出力することができない点に注意してください。

VertexNormalWSは頂点シェーダの結果の法線をそのまま使うので、Normal出力に依存しません。

・Transform

ue131.jpg

3Dベクトルを指定空間に変換する命令です。

Detailsタブで入力、および出力のベクトル空間を指定すると、入力で指定したベクトル空間中にある(ということになっている)3Dベクトルを出力で指定したベクトル空間に変換してくれます。

画像の例ではタンジェントスペースのベクトルをワールド空間に変換しますので、入力に法線マップのサンプリング結果を与えるとPixelNormalWSと同じ結果を得られます。

4Dベクトルの入力ができない点を見るとあくまでも回転変換しかしてくれないっぽいです。

つまり、向きだけが変化するわけですね。

・BrendAngleCorrectedNormals, DetailTexturing

ue132.jpg

Detailマッピングなどと呼ばれるテクスチャリング手法を実現するために用意されているマテリアル関数です。

エンジン側で用意されているマテリアル関数ですが、内部の処理は参照することができるので、似たようなものを作りたいときには参考にしてください。

BlendAngleCorrectedNormalsはReoriented Normal Mappingと呼ばれる法線マップの合成計算を行っています。

計算式自体はそれほど難しくないのですが、理論的な部分を知りたい人はこちらを参照してください。

http://blog.selfshadow.com/publications/blending-in-detail/

単純にベクトル合成するだけより高品質な結果を出力できるのでお勧めです。

DetailTexturingはDiffuseとNormalだけですが、合成結果を取得することができる命令です。

NormalはReoriented Normal Mappingを利用していませんが、合成するDetailテクスチャの強さを指定できる点が強みです。

・Detailマッピング

こちらはノードの解説ではなく、前述のノード解説で出てきたDetailマッピングについて簡単に解説しようと思います。

次世代機のゲームを作る上では結構重要な技術になると思いますので、前述のノードと一緒に覚えてみてはいかがでしょうか?

Detailマッピングというのは、1つのマテリアルの要素を詳細レベルの違いに応じた別々のテクスチャで表現する手法です。

と言ってもわかりにくいですよね?

テクスチャのサイズというのは基本的には解像度です。

しかし、各テクセル(テクスチャのピクセル)を現実世界のサイズに照らし合わせたとき、ある2つのテクスチャのサイズが同じといえるでしょうか?

同じ解像度の2つのテクスチャが存在するものと仮定します。

テクスチャAは1テクセルのサイズが1m*1mを表現するように描かれているのに対して、テクスチャBは1cm*1cmを表現するように描かれているとしましょう。

この2つのテクスチャを同じUV、同じサイズの床面に貼りつけると、当然ですがテクスチャBの方が間延びしてぼやけた印象を与えることになるでしょう。

なぜなら、テクスチャBは1cm*1cmを表現するための1テクセルで1m*1mまで引き延ばされてしまうからです。

テクセルの表現サイズを同じにしたいのであれば、テクスチャBはUV値を100倍にしてやる必要があるわけです。

このように、同じ解像度でもテクスチャが表現するサイズには違いがあるので、これを利用して2つの表現サイズが異なるテクスチャを合成することで、大まかな表現と細かな表現を同居させることができるようになります。

この手法は特に法線マップで有効に働きますので、BlendAngleCorrectedNormalsは非常に有用なノードになるはずです。

とても適当ではありますが、2種類の法線マップをBlendAngleCorrectedNormalsで合成した例をお見せします。

BaseNormalはT_Brick_Clay_New_N、AdditionalNormalはUV座標を適当な値でスケーリングしてT_Detail_Rocky_Nを採用しています。

下の画像の左側がBaseNormalのみ、右側がBlendAngleCorrectedNormalsの結果です。

ue133.jpg

それっぽいかどうかというのはともかく、左はきちんと切り出されたレンガブロック、右は自然の形を残した石垣っぽいブロックの表現になります。

もちろん、これは表現の違いでしかないのですが、右のような表現を1枚のテクスチャでやろうとすると細かな法線が少し間延びしてしまう可能性があります。

まあ、UE4のスターターコンテンツのテクスチャはどれも2048*2048というかなり大きなサイズを利用しているので、そこまで違和感は出ないかもしれませんがね。

また、2種類以上のテクスチャをランタイムで合成する理由としては製作過程の簡略化も含まれているのですが、それはDetailマッピングとはまた別の話ですね。