【CG】テクスチャのサイズをcm単位で指示するマテリアルインスタンス【UE4】
たぶん建築ビジュアライゼーションだけ手がけていらっしゃる方にとっては「なにそれ? そんな考慮要る?」って話題かもしれませんが、CAD屋さんにとっては重要(?)な話だったりします。という件の実装方法の例です。
例えば、以下のようなブロックのテクスチャがあったとします。このとき、
「ブロックのサイズは幅30cm×高さ10cmの商品だから、CG上でもそのサイズで表現されるようにしといて。」
という注文が普通にあります。
通常のUE4の使い方だとそんなのどうやって設定すんねん、目測でやれってか!? っていう話になります。
このように、ビジュアライゼーションだったら見栄えがそれなりであればOKなのかもしれません(?)が、CAD等ではそうもいきません。30cm×10cmのブロックで施工する予定であれば、CGの世界でも30cmで表現してもらわないと困るわけです。
建設会社vs施主のトラブルの元であり、(訴訟問題まで発展することはさすがに聞きませんが、)顧客満足度的な部分が微妙に落ちる可能性はなくもないです。
うそだろフォトリアルだったらそれでいいじゃん―なんて思うでしょうが、これらは実際にある話しです。
話を本題に戻しましょう、
1枚のテクスチャが実世界のスケールで何cmかどうかを
UE4公式ドキュメントには「Absolute World Positionノードを使おう」ってのは載っていますが、これはXY平面にしか効かないので(?)、あまり有効ではない手法です。
ではでは、UE4でもオブジェクトのスケールに依存せずに自分が決めたUV値だけに従うマテリアル設定をしてみましょう。
やってみよう
①1枚のテクスチャ(1UV)を100cmだと定義するマテリアル関数を作成し、
②そのマテリアル関数を使用するマテリアルを作成して、
③そのマテリアルからマテリアルインスタンスを作成して、オブジェクトに貼り付ける順序で進めていきましょう。
UE4フォーラムなんかでも似たような質問の解決策としてAbsolute World Positionを使っていますが、今回の実装方法でもAbsolute World Positionを使用します。それに加えてパラメータを追加して使いやすくしよう。という感じで進めていきましょう。
サンプルとして以下のような赤レンガの外壁を使ってみます。
先程「このレンガは30×10cmです」と定義しました。このテクスチャをみると3つのレンガが横並びしています。ということはこのテクスチャ1枚あたりの長さは90cmですってことになりますね。
①マテリアル関数を作る
Absolute World Positionノードを使うことで実現できます。
例えば、
・Absolute World PositionノードにMaskノードを接続して、
・R、G(つまりXY平面)をONにして、
・さらに100で割る(100cm=1UV単位に変換)ことで、
Z軸方向の面(上向きの面)においてオブジェクトがどんな状況にあっても100cmあたり1UVになります。
この方法はよく紹介されているのですが1つ弱点があります。真上を向く面にしか適用できません。建物で言うならば、床と天井はうまくいきますが、壁や屋根が上手くいきません。そこで、どの軸方向にも絶対座標が有効になるようなマテリアル関数を作ります。
・パラメータはスカラー値でInputCMという名前にしました。デフォルト値は100にしました。
・出力されるのはUVsです。
②マテリアルで関数を利用する
さてマテリアルを作りましょう。先程マテリアル関数の出力をUVsにしたので、Texture SampleのUVにセットすればOK。楽ちん。
③マテリアルインスタンスを作成しパラメータを適用
マテリアルインスタンスを作りましょう。開くと①で作成したパラメータ「InputCM」が登場します。
最初にこのテクスチャは90cmだと言っていましたのでInputCM=90と設定すればOK。
完成
いかがでしょうか。このマテリアルインスタンスであれば、どんなUV設定でも、どんなスケールであっても床、壁などに常に30×10cmの赤レンガが表示されるようになります。
注意:用途は限定的
1点注意があるんです。斜め方向の面に対しては正しく計算されません。最大でななめ45度のときに√2(=1.414)倍大きく表示されてしまいます。
超パッと見はわかりませんが、実は45×15cmの赤レンガになってしまっています。
例えば屋根面とかはずれるということです。この解決法はまた後日。