マイクロテクスチャについて
- Unagi
- 2025年10月1日
- 読了時間: 15分
はじめに
こんにちは、わもちです。 普段は専門学校に通いCGについて学んでいます。自分の学びを、備忘録じゃありませんが残しておこうと思い、この場をお借りして記載しております。ともに業界を目指す学生の皆さん、そしてすでに業界で働いている皆さんなど、多くの人にこの記事を読んでいただき、ご意見いただけると幸いです。 今回はマイクロテクスチャ(勝手にそう呼んでいますが笑)について記載しようと思います。
※注意点※
あくまで学生のメモであり、専門的な内容を書くことはできておりません。もし、内容の誤りやこれ以上の最適解があれば、コメントにてご指摘いただけると幸いです。貴重なご意見お待ちしています!
マイクロテクスチャって?
上記でも少し触れましたが、正式名称ではありませんし、私たちがそう呼んでいるだけです。では一体それは何なのか?一文にまとめると「細かいディティールを追加することを目的としたシームレスなテクスチャのこと」です。 これをオブジェクトに細かくタイリングすることで、ノーマルマップやディスプレイスメントマップであればより細かい凹凸情報を、ラフネスマップなら微細な粗さやムラを表現することができます。 と大げさに記載しましたは、要はマップを細かくタイリングしているだけです。あまり気を追わず、進めていきましょう。 今回はディスプレイスメントマップを使用していきます。
実践!…の前に、3種類のディスプレイスメントマップを1枚にしよう!(不必要であれば、とばしてもOK)
いざ実践!と行きたいところですが、その前に複数あるディスプレイスメントマップを1枚にまとめていきましょう。突然何を言っているんだ?という方も少なくないと思います。なので、なるべくかみ砕いて説明しますね。 3種類のディスプレイスメントマップは、例えば1枚はZBから書き出しをしたディスプレイスメントマップ、もう2枚はディティールを追加するためのマップみたいに分けて使うことがあります。
この辺りは texturing.xyz を見ていただけると良いかもです。 https://texturing.xyz/pages/vface-tutorials 色々とチュートリアルもあるので、参考になります。
そして3枚を1枚にすることで、「管理のしやすさ」、「データが軽さ」があげられます。 まず、詳細な表現をする際は、複数のディスプレイスメントマップを使い、それをノード上で少しずつ調整するのが好ましいと考えています。
その際、複数のディスプレイスメントマップにそれぞれノードをつないで管理することは可能です。しかし、なるべくシンプルかつ少ないノードで管理ができた方が調整も容易で理想的です。そして、ディスプレイスメントマップの枚数が少なければその分データ量が軽くなります。以上の点から、枚数が少ないに越したことはありません。
また、今回はディスプレイスメントマップですが、白黒のマップであればほかのマップでも応用が利きます。AO、ラフネス、メタルネスなどでもまとめることができ、これは可能な限りデータを軽くしたゲーム制作においてとてもは効果的な手段です。 そのため、今回のメインではありませんが、この方法を同時に覚えてしまいましょう。使用するソフトはSubstance 3D Painterです。Substance 3D Painterを使用したことがない方もいると思いますので、なるべくわかりやすく説明しますが、Substance 3D Painterはチュートリアル動画が数多くありますので、ぜひ自分でも調べてみてください。
それでは、以下の手順で制作してください。
オブジェクトを読み込む準備をしよう。
Substance 3D Painterに制作した3種類のディスプレイスメントマップを読み込もう。
「テクスチャ設定」のチャンネルの+マークから、「ユーザーチャンネル」を3つ作ろう。
「塗りつぶしレイヤー」を3つ作り、それぞれに作った「ユーザーチャンネル」を割りふろう。
それぞれのマテリアルモードに読み込んだディスプレイスメントマップを割りふろう。
出力テンプレートを作って書き出そう。
1.オブジェクトを読み込む準備をしよう。
まずは、オブジェクトを読み込んでいきましょう。左上にある「ファイル」から、「新規(ctrl+N)」で新規プロジェクトを開いてください。ここで、詳細な設定ができます。 しかし、あくまで今回はディスプレイスメントマップを1つにまとめることが目的のため、設定はデフォルトで大丈夫です。上から2行目の「ファイル」の項目の「選択」から、fbxファイル、もしくはobjファイルを読み込みます。

モデルは板ポリゴンで読み込んでください。MayaのデフォルトのPlane(プレーン)を使ってもらえば、UVも開かれているので、問題ないと思います。 余談ですが、オブジェクトをSubstance 3D Painterの読み込んだ時にエラーを起こすときがあります。
その時はまず、UVを確認してみてください。UVチャンクからUVシェルがはみ出ているとエラーを起こして読み込むことができません。一見はみ出ていなくても、画面を引いてみると大きく離れた場所にUVシェルが見つかることもあると思います。
確認して問題がない場合は、objファイルで読み込んでみてください。fbxファイル内に不要なデータが入り込みエラーを起こすことがあります。これに対し、objファイルは純粋にオブジェクトのデータのみなので、シンプルなデータで読み込むことができます。この2つのパターンを試してもらえるとだいたい解決できると思います。(私は今ままでこの2つで解決しました!解決できなければ、ぜひ状況をコメント欄に)
2.Substance 3D Painterに制作した3種類のディスプレイスメントマップを読み込もう。
画面内にアセットがたくさん並んでるところがあると思います(画面左側か、下の方にあるような印象があります笑)。そこに画像をドラック&ドロップしてください。そうすると、「リソースを読み込み」のウィンドウに移ります。読み込んだテクスチャが一覧で表示されるので、「未定義」から「texture」を選択してください。その後、ウィンドウ下にある「リソースの読み込み先」を「現在のセッション」にしておくと、そのデータはこのプロジェクト内にのみ保存されます。「ライブラリ」にしておくと、今後開くすべてのプロジェクトに反映されます。どちらか好きなものを選んでください。その後「読み込み」でテクスチャを読み込むことができます。

3.テクスチャ設定のチャンネルの+マークから、ユーザーチャンネルを3つ作ろう。
「テクスチャセットの設定」の「チャンネル」の+を選択してください。表示される項目の1番したの「ユーザーチャンネル」を3つ選択します。今回は上から「User0」、「User1」、「User2」を選択しましょう。
その後「チャンネル」の一覧のこの3つが追加されたと思います。「歯車マーク」を選択し、「L32F」を選択してください。私も詳しくありませんが、「L」が「Luminance(輝度)」で白黒画像と、「32」が32ビットと、「F」は「Float(浮動小数点)」を示します。遊動小数点については正直全くわかりませんが笑、要するに「32ビットで非常に詳細な情報を持つことができる白黒画像」のことです。なので、ディスプレイスメントマップを制作するにあたって、この設定が好ましいです。これ以下のビット数だと、レンダリング時にディスプレイスメントマップの粗さが目立つようになります。


4.塗りつぶしレイヤーを3つ作り、それぞれに作ったユーザーチャンネルを割りふろう。
「レイヤー」で「塗りつぶしレイヤー(ビーカーから液体を流すようなマーク)」を3つ入れてください。今回は分かりやすいよう、それぞれのレイヤーの名前をUser0、User1、User2としましょう。そして、それぞれのマテリアルでuser0、user1、user2の項目を選択してください。それ以外があっても構いませんが、関係がないので、ややこしければ、外しても大丈夫です。


5.それぞれのマテリアルモードに読み込んだディスプレイスメントマップを割りふろう。
割り振られたuser0、user1、user2にそれぞれ、読み込んだディスプレイスメントマップをドラッグ&ドロップしてください。※今回は結果が分かりやすいよう、私はSubstance 3D Painterにデフォルトで入っている模様を含む白黒画像3つで制作します。皆さんは各自準備したディスプレイスメントマップを使用してみてください。

6.出力テンプレートを作って書き出そう
「ファイル」の「テクスチャの書き出し(ctrl+shift+E)」を選択してください。
「設定」、「出力テンプレート」、「書き出しリスト」の3つの項目があると思います。 「出力テンプレート」の項目から「PBR Metallic Roughness」を複製してください。右クリック「複製」もしくは一覧の上にある「書類が重なったようなマーク」から複製ができます。
どのプリセットから制作してもらっても構いませんが、個人的には「PBR Metallic Roughness」プリセットがおすすめです。出力テンプレートの中にはMaya、Unity、UEなどあらゆる専用プリセットがあります。が、これはそのどれでもありません。そのためどのソフトにも使用できるテクスチャを書き出しができます。

名前は好きなものをつけてください。 画面中央には書き出されるテクスチャの一覧があると思います。その上の「出力マップ」の作成から「R+G+B」を選択してください。

そして画面右側にある「マップを入力」の項目から、user0、user1、user2をそれぞれR、G、Bにドラッグ&ドロップで割り振ってください。割り振る際に出てくる項目は「グレーチャンネル」を選択してください。

そして、画像の設定をexrで32fビットにしてください。

これでテンプレートの準備は完了です。 「設定」の項目に戻ってください。「グローバル設定」が標示されていると思います。上から「保存先ディレクトリ」で保存先を指定します。「出力テンプレート」を先ほど制作してテンプレートにしましょう。

「ファイルの種類」で画像形式を、「サイズ」で画像サイズを選択してください。 「パディング」は簡単に説明すると、UVに対して画像をどこまで延長させるかを決定します。今回は板ポリゴン一面にディスプレイスメントマップを制作するので、これはデフォルトの設定のままでOKです。 さいごに、「グローバル設定」の項目内にある、マテリアルを選択し、「出力マップ」で、先ほど追加した項目以外を外してください。このチェックの入った項目が全てのマップが書き出されます。今回は、ディスプレイスメントマップのみでいいので、そのほかのベースカラーやラフネス、ノーマルなどは不必要です。 かなり長くなりましたが、これで準備は完了です。書き出してみてください。

3つのディスプレイスメントマップがRGBに割りふられ、1つに書き出せたと思います。Photoshopで確認してみるとわかりやすいですね。
3種類の模様がそれぞれRGBに割り振られたことがわかります。実際は皮膚のディスプレイスメントなどで行います。

いざ、実践!やってみよう!(ここから本題!)
それではディスプレイスメントマップも準備できたことですし(かなり長旅でしたが笑)、さっそく進めていきましょう。以下の6つの手順をおって説明していきます。ここから画像はMayaに切り替わります。
サブディビジョンを確認しよう。
ハイパーシェードにマイクロテクスチャを読みこもう。
aiSubtractで、ディスプレイスメントマップの膨張を大まかに調整しよう。
aiLayerRgbaで3種のディスプレイスメントマップの細かく調整しよう。
displacemenntShaderでディスプレイスメントマップをマテリアルに接続しよう。
place2dTextureでUVをタイリングしよう。
複数のディスプレイスメントマップを併用しよう。
1.サブディビジョンを確認しよう。
ディスプレイスメントは実際にオブジェクトの形を変形します。そのため、レンダリングするための設定が必要です。まずは以下の手順をふんで、3番キーでおなじみスムーズメッシュプレビューをオフにします。

オブジェクトの選択
アトリビュートエディタ
スムーズ メッシュ
サブディビジョン レベル
レンダリングのためにプレビューを使用をオフにする。
これをオフにすることで、レンダリング時に誤ってサブディビジョンをかけたうえでスムーズメッシュをかけてしまうことを防ぎます。試してはいませんが、サブディビジョン×スムーズメッシュでとんでもなく重くなってしまうと思います笑
次にレンダリング時の分割の確認です。オブジェクトを実際に分割せずとも、レンダリングの際に分割するという設定ができます。
オブジェクトの選択
アトリビュートエディア
Arnold
Subdivision
Typeをnoneからcatclackへ
IterationsとAdaptive Errorを調整する。
私も詳しい訳ではないのですが、4のTypeはnone、linear、catclarkの3種類があります。noneはサブディビジョンを無視し、そのままレンダリングされます。linearはリニアサブディビジョンのことです。各面の中央に頂点を置き、サブディビジョンをかけます。スムーズがかからないため輪郭に変化がありません。そのため形が完成しており、大きな変化を加えたくないモデルに、細かいディティール等を加えるときに使ったりします。catclackはスムーズがかかる一般的なサブディビジョンです。今回はcatclackを使用します。 5のIterationsは反復のことです。この数値を上げるほどディスプレイスメントの質は上がります。ただその分レンダリングにも時間がかかるので注意が必要です。 Adaptive Errorの項目の設定では、どれだけlimit Surface(サブディビジョンサーフェスを無限に細分化したときに収束する、最も滑らかな形状)に近づけるかを決める誤差を調整できます。数値が小さいほど滑らかな結果が得られるものの、処理が多く重くなります。数値が大きいほど、見た目が荒いものの、処理が軽くなります。0はAdaptive Subdivision(必要な部分のみ細分化する方法)を無効にし、Uniform Subdivision(常に均一な細分化)を適用します。 少し難しいことを話しましたが、今回はIterationsを5、Adaptive Errorを2としておきましょう。

最後にディスプレイスメントマップについての調整をします。ディスプレイスメントマップは物によって、どこを中央値にしているなどが異なり、そのマップごとに調整することが必要です。
上記と同様に、アトリビュートエディタ、Arnoldへ
Displacement AttributesでHeght、Bounds Padding、Scalar Zero Valueを調整します。
Height:高さです。数値が大きいほど変化量が増えます。基本的にデフォルトの1で構いません。 Bounds Padding:バウンディングボックスを拡張するためのパラメータです。オブジェクトの形状が変わるため、バウンディングボックスも適切に拡張しないと、オブジェクトが正しくレンダリングされない可能性があります。と、難しく説明しましたが、ざっくりとしたイメージで説明すると、オブジェクトの少し外側を囲む箱です。少し話がズレますが、この箱の中心がオブジェクトの中心になります。皆さんがスケールや移動のを行う際にの中心も、このバウンディングボックスの中心ということになります。そして、ディスプレイスメントマップの凹凸はこのバウンディングボックス内で行われるため、ある程度拡張する必要があるというわけです。これは大きいに越したことないので、1にしておけばいいと思います。 Scalar Zero Value:ディスプレイスメントマップの基準値(デフォルトの変化なしの状態)を定義するパラメータです。0を基準にすると、負の値は沈み込み、正の値は隆起します。0.5ならそれより大きければ隆起、小さければ沈み込みます。グレースケールのディスプレイスメントマップを使う場合は0.5 を基準値に設定すると、ちょうど良いバランスで変化をコントロールできるとされています。しかし、上記でも説明しましたが、ディスプレイスメントマップの基準値は物により差があります。また、この項目では、そのオブジェクトに対して一律に反映されるため、複数のディスプレイスメントマップを使用している場合など、細かいコントロールが難しいです。なので、細かい調整が不要な程度に完成されたディスプレイスメントマップや、学生で難しいことをするには少しハードルが高い場合は、Scalar Zero Valueで調整(0.5)、そうでなければ、この後、紹介するノードを使用した調整をお勧めします(こちらの場合は0にいしておいてください。)。

2.ハイパーシェードにマイクロテクスチャを読みこもう
ようやく準備が整いました。ここからが本番です。まずは、先ほど製作したディスプレイスメントマップをハイパーシェードにドラッグ&ドロップしましょう。
3.aiSubtractで、ディスプレイスメントマップの大まかなに調整しよう。
先ほど、Scalar Zero Valueによる中央値の調整について説明しました。ここでは、後々より細かい設定をしていきために、Scalar Zero Valueをデフォルトの0のまま、ノードで中央値を調整していきます。 aiSubtractは減算ノードです。tabキーを押してこのノードを追加、マップの出力カラーをInput1に接続、Input2の明度(V)を0.5にします。これにより、ディスプレイスメントマップの基準値を黒にし、Scalar Zero Valueの0にあわせます。このひと手間が後々生きていきます。


4.aiLayerRgbaでディスプレイスメントマップの細かく調整しよう。
aiLayerRgbaは複数のテクスチャを合成するのに使用するノードです。ここでは、ディスプレイスメントマップの最終的な強弱の調整に使います。今回はRGBチャンネルにそれぞれ別のディスプレイスメントマップを割りふったので、aiLayerRgbaのそれぞれのレイヤーに割りふります。
OutColorRをInput1、Input1Rに、OutColorGをInput2、Input2Rに、OutColorBをInput3、Input3Rに接続します。(3つめのレイヤーは初期状態だと、表示されていません。3つ目のOutColorは、aiLayerRgbaノードの上にある黄色の丸につなげてください。
そうすると「その他」と表示され、そこから下の図のように、Input3Rに接続できます。)そして今回は、それぞれのレイヤーの名前を上からRed、Green、Blueとしましょう。
この際、各レイヤーのEnableの項目にチェックを入れましょう。これにより、それぞれのレイヤーが反映されます。ここで、それぞれRedレイヤーでRチャンネルに割りふったディスプレイスメントを、GreenでGチャンネルを、BlueでBチャンネルのコントロールをします。Mixの数値で調整します。最初は0.01くらいから調節することをお勧めします。
そして、ここで、先ほどのaiSubtractが生きてきます。というより、Scalar Zero Value0.5にして調整したものだと、レイヤーでわけ、各項目で調整した際、異常な沈み込みを引き起こすことがあります。私も具体的な理由まではわかりませんが、おそらく、Scalar Zero Valueが3枚のディスプレイスメントマップのそれぞれの調整に対応しきれず、同時に調整されてしまっているのかなと考えています(あくまで推測です。どなたかお詳しい方がいらっしゃればコメントで教えていただきたいです!。)(21~23のレイヤーRGBA画像を挿入)



5.displacemenntShaderでディスプレイスメントマップをマテリアルに接続しよう。
この工程により、ようやくディスプレイスメントマップが反映されます。aiLayerRgbaのOutColorRをdisplacemenntShaderのディスプレイスメントに接続し、aiStandardSurfaceのSGノード、ディスプレイスメントシェーダーに接続してください。 ここで一度レンダリングしてみてください。ディスプレイスメントが細かくタイリングされていると思います。

6.最後に!place2dTextureでUVをタイリングしよう。
この項目で、ディスプレイスメントマップを細かくタイリングすることにより、マイクロテクスチャの完成です。place2dTextureのRepeatUVの数値を調節し、細かいディティールを作りましょう。(★チャネルボックスから簡単にタイリングをできるようにするスクリプトをここで説明したいです。)

7.応用!aiaddで複数のディスプレイスメントマップを併用しよう。
ディスプレイスメントマップを複数使いタイリングすることによって、より複雑な情報を反映させることができます。また、同じディスプレイスメントマップでも、タイリングのスケールを変えることで、同様の効果が期待できます。上記の作業を繰り返し、同じノードを組みましょう。 ぞれぞれのaiLayerRgbaのOutColorを加算レイヤー、aiaddのInput1、Input2に接続しましょう。そして、5同様にOutColor、OutColorRをdisplacemenntShaderのディスプレイスメントに接続し、aiStandardSurfaceのSGノード、ディスプレイスメントシェーダーに接続してください。

さいごに
最後まで読んでくださりありがとうございました。少しはお力になれましたでしょうか?わかりにくい点や誤っている点があれば、ぜひコメントいただけたらと思います。次回は、IDマップを使用した、ディスプレイスメントやラフネス、メタルネスのコントロールについて備忘録を残せたらと思います。それではまた、お会いしましょう!


コメント