UnityのHDRP向けのLOD対応背景アセットのテクスチャを作る

はじめに

背景アセット用のHDRP向けのSubstanceを利用したテクスチャの制作手順をメモします。 LODに対応したアセットとして作成していきます。 我流で適当にやっているものなのでこれで正しいのかはわかっていないのですが、参考程度にはなるかと……。

  • Unity: 2019.3.0f3
  • HDRP: 7.1.6
  • Substance Painter: 2019.3.0
  • Substance Designer: 2019.2.3

2020/01/17追記

この記事の手順を簡略化するためのツールを作りました。

Substance Automation Toolkitを利用してHDRP向けLOD0テクスチャをLOD1、LOD2に転写するツールを作成した | 測度ゼロの抹茶チョコ

DetailMap無しバージョン

最初にシンプルな場合で作り方の手順を見ていきます。

LOD対応の3Dモデルを準備する

好きなモデリングソフトウェアでハイポリと各LODのモデルを作成してください。

ハイポリモデル

ハイポリモデルとして次のようなモデルを用意しました。

2019 12 19 10 01 42

ポリゴン数は55,884triです。

後でテクスチャ作成時にマテリアルを割り当てるために、マテリアルごとに頂点カラーを割り当ててあります。

Nゴンが含まれていると、Substanceでベイクする際にうまく三角形化してくれない場合があるので、あらかじめモデリングツールで三角形化しておきます。

ハイポリモデルでは、とりあえず縁をベベルしておくとベイクしたときよい感じになります。

ハイポリモデルはUVを展開しておく必要はありません。

LOD0モデル

LOD0のモデルとして次のようなモデルを用意しました。

2019 12 19 10 07 41

ポリゴン数は4428triです。モデルの割にはちょっと多いですかね。

ベイクする前に三角形面化しておくのがポイントです。

テクスチャ作成のためにUV展開をしました。 UVは次のとおりです。

2019 12 19 10 08 10

LOD1モデル

LOD1モデルとして次のようなモデルを用意しました。

2019 12 19 10 08 38

ポリゴン数は588triです。

こちらも三角形面化しておきます。

UVは次のとおりです。

2019 12 19 10 09 17

LOD2モデル

LOD2モデルとして次のようなモデルを用意しました。

2019 12 19 10 10 28

ポリゴン数は12triです。

こちらも三角形面化しておきます。

UVは次のとおりです。

2019 12 19 10 10 46

Substance PainterでLOD0のテクスチャを作成する

Substance Painterを開き、「PBR - Metallic Roughness (allegorithmic)」でLOD0のモデルを読み込みます。

2019 12 19 10 16 57

「TEXTURE SET SETTINGS」から「Bake Mesh Maps」を選択します。

2019 12 19 10 17 32

2019 12 19 10 17 58

「High Definition Meshes」から、ハイポリのメッシュを選択します。

2019 12 19 10 18 55

2019 12 19 10 19 37

とりあえずパラメータはそのままで「Bake Material Mesh Maps」をクリックしてベイクを開始します。

ベイクした結果をみるとうまくベイクできていないようです。

2019 12 19 10 21 44

2019 12 19 10 21 54

面の後ろ方向に飛ばすレイがハイポリに到達していないようなので、「Max Rear Distance」を上げてもう一度ベイクします。

2019 12 19 10 22 45

今度はうまくベイクできました。

2019 12 19 10 28 41

2019 12 19 10 29 06

テクスチャを作成していきます。

まずはコンクリートのマテリアルをレイヤーにドラッグ&ドロップします。

2019 12 19 10 24 39

マスクを追加します。「Add mask with color selection」を実行します。

2019 12 19 10 25 42

「Pick color」でメインの部分を選択します。

2019 12 19 10 26 47

2019 12 19 10 27 14

2019 12 19 10 27 24

2019 12 19 10 27 36

コンクリートのマテリアルがheightだけでnormalを出力していないようです。

2019 12 19 10 29 41

最終的にはheightもnormalに焼いてくれるのかもしれませんが、今回は表面のnormalも必要なのでnormalを出力するように変更します。

2019 12 19 10 31 02

つぎにボルトの部分の金属のマテリアルを割り当てます。 金属のマテリアルをレイヤーにドラッグ&ドロップします。

2019 12 19 10 31 22

マスクを追加します。「Add mask with color selection」を実行します。

2019 12 19 10 32 19

「Pick color」でボルトの部分を選択します。

2019 12 19 10 32 59

2019 12 19 10 33 08

2019 12 19 10 33 19

2019 12 19 10 33 42

こちらもNormalを出力しておきます。

2019 12 19 10 35 06

適当にペイントも加えていきます。 fillレイヤーを追加します。

2019 12 19 10 35 48

ペイントがわかりやすいようにピンクにしました。

2019 12 19 10 36 22

「Add black mask」を実行します。

2019 12 19 10 37 03

maskを選択した状態で右クリックから「Add paint」を実行します。

2019 12 19 10 37 53

「Particles」から「Leak Heavy」を選択して適当にペイントしていきます。

2019 12 19 10 40 12

2019 12 19 10 40 01

2019 12 19 10 41 32

ひとまずこれでペイントは完了とします。

次にテクスチャを出力していきます。

「File」から「Export Textures...」をクリックします。

2019 12 19 10 43 33

開いたウィンドウの「CONFIGURATION」タブを開きます。

2019 12 19 10 44 15

「Unity HD Render Pipeline」の項目を見つけて右クリックから複製します。

2019 12 19 10 45 41

複製したらわかり易い名前をつけた後に、RGBのマップを一枚追加します。

2019 12 19 10 48 46

追加したマップの名前を「$mesh$textureSetMicroNormal」とし、「Input maps」のNormalをドラッグ&ドロップし、RGBチャンネルに割り当てます。 「Mesh maps」のNormalやConverted mapsのNormalではないので注意してください。

2019 12 19 10 50 02

2019 12 19 10 51 22

次にGrayのマップを2枚追加します。

2019 12 19 10 52 26

それぞれ「$mesh$textureSetMetallic」と「$mesh$textureSetSmoothness」と名付けます。

2019 12 19 10 54 44

「$mesh$textureSetMetallic」に「Metallic」をドラッグ&ドロップしてGrayチャンネルに割り当てます。

2019 12 19 10 56 17

2019 12 19 10 56 39

「$mesh$textureSetSmoothness」に「Glossiness」をドラッグ&ドロップしてGrayチャンネルに割り当てます。

2019 12 19 10 58 32

2019 12 19 10 58 52

これで新しく作成したpresetは次のようになります。

2019 12 19 10 59 12

プリセットは保存されているので次回以降はpreset作成は行う必要はありません。

「EXPORT」タブから「Config」で作成したpresetを選択し、エクスポート先のディレクトリを指定して 「Export」します。

2019 12 19 11 01 28

今回はEmissiveやAnisotropyなどは使わないため、マップの数が足りないと警告が出ています。 必要に応じて「TEXTURE SET SETTINGS」からテクスチャを追加しておけば出力されます。

これでHDRPに必要なBaseColor、MaskMap、NormalMapは出力されました。 LOD1、LOD2を作成するのに必要なMetallic、Smoohness、MicroNormalも出力されました。

MicroNormalはメッシュのノーマルを含まない表面のディティールのノーマルマップです。

こちらが通常のノーマルマップ。

2019 12 19 12 23 58

こちらがMicroNormalとして出力されたノーマルマップです。

2019 12 19 12 24 34

Substance Designerで各LODのテクスチャを作成する

作成したLOD0のテクスチャをもとにSubstance DesignerでLOD1とLOD2のテクスチャを作成します。 また、LOD0のBent NormalがSubstance Painterでは作成されないので、そちらのベイクも行います。

Substance Designerを立ち上げます。

「Empty」なグラフを作成します。

2019 12 19 11 05 15

2019 12 19 11 05 51

EXPLORERからsbsを右クリックして「Link」から「3D Mesh」を選択します。

2019 12 19 11 06 09

ハイポリとLOD0、LOD1、LOD2の3Dモデルを読み込みます。

2019 12 19 11 07 09

LOD0のBent Normalをベイクする

最初にLOD0のBent Normalをベイクしていきます。

EXPLORERからLOD0を右クリックして「Bake model Information」をクリックします。

2019 12 19 11 07 55

「Add high definition model」の「From Resources」からハイポリモデルを選択します。

2019 12 19 11 11 08

2019 12 19 11 11 54

2019 12 19 11 12 11

「Add baker」から「Bent Normal Map from Mesh」を選択します。

2019 12 19 11 12 51

2019 12 19 11 13 19

Real valueとFrontal valueを適当に変更しておきます。

2019 12 19 11 14 08

UnityのNormalはDirectXではなくOpenGLだそうなので、Baker Parametersの「Normal Orientation」を「OpenGL」に変更しておきます。

2019 12 19 11 18 04

「Start Rrender」を実行します。

2019 12 19 11 19 22

Bent Normalマップが無事ベイクされました。

LOD1のテクスチャを作成する

次にLOD1のテクスチャを作成していきます。 作成するのはBaseColor、MaskMap、NormalMap、BentNormalMapです。 ハイポリからメッシュのノーマルマップとBent Normal、アンビエントオクルージョンマップをベイクします。 LOD0からBase ColorとMetallicとSmoothness、Micro Normalをベイクします。

最初にハイポリからベイクしていきます。

EXPRORERからLOD1を右クリックして「Bake model Information」をクリックします。

2019 12 19 11 21 56

「Add high definition model」の「From Resources」からハイポリモデルを選択します。

2019 12 19 11 23 11

2019 12 19 11 23 43

レイのFrontal valueとRear valueを適当に変更します。

2019 12 19 11 24 29

「Add baker」から「Ambient Occlusion Map from Mesh」、「Bent Normals Map from Mesh」、「Normal Map from Mesh」を追加します。

2019 12 19 11 25 27

Bent NormalとNormalの「Normal Orientation」をOpenGLに変更します。

2019 12 19 11 26 31

2019 12 19 11 26 51

「Start Rrender」を実行します。

2019 12 19 11 28 22

ハイポリのマップがひととおりベイクできました。

次にLOD0のモデルから転写をします。

まずは今使ったハイポリのモデルを除去します。

2019 12 19 11 29 14

2019 12 19 11 29 37

「Add high definition model」の「From Resources」からLOD0モデルを選択します。

2019 12 19 11 23 11

2019 12 19 11 30 20

2019 12 19 11 30 31

Delete bakerでさきほど追加したbakerを全部削除します。

2019 12 19 11 31 05

2019 12 19 11 31 23

Add bakerで「Transferred Texture from Mesh」を4つ追加します。

2019 12 19 11 32 34

追加したBakerの名前を「BaseColor」、「Metallic」、「Smoothness」、「MicroNormal」とします。

2019 12 19 11 34 27

「From File...」から、それぞれLOD0のBaseColor、Metallic、Smoothness、MicroNormalのテクスチャを設定します。 MicroNormalについてはNormal Mapのチェックボックスをチェックします。

2019 12 19 11 35 02

2019 12 19 11 36 15

2019 12 19 11 36 35

2019 12 19 11 37 28

2019 12 19 11 37 35

「Start Rrender」を実行します。

2019 12 19 11 38 42

LOD0の情報がベイクされました。

ベイクされたテクスチャを組み合わせてHDRP用のテクスチャに仕上げます。

EXPRORERでsbsにLOD1という空のグラフを作成します。

2019 12 19 11 40 20

HDRPのMaskMapを作成していきます。

ベイクされた「metallic」、「Smoothness」、「ao」をグラフにドラッグ&ドロップします。

2019 12 19 11 41 30

2019 12 19 11 46 35

MetallicとSmoothnessをGrayscaleとして読み込みます。

2019 12 19 11 46 51

2019 12 19 11 47 24

「RGBA Merge」でマージします。 MaskMapはrがメタリック、gがao、bがディティールマスク(今回は使わない)、aがスムースネスです。

2019 12 19 11 48 57

Outputノードを接続し、MaskMapという名前にします。 UsageでLinearを指定しました。

2019 12 19 12 07 30

次にノーマルマップを作成していきます。

ベイクされたNormal from meshとmicronormalをグラフにドラッグ&ドロップします。

2019 12 19 11 50 53

2019 12 19 11 51 09

Normal Combineノードでノーマルを合成します。

2019 12 19 11 52 01

Outputノードを接続しNormalという名前にします。 UsageをnormalのNormaXYZRightにしました。

2019 12 19 11 53 09

EXPRORERのLOD1のグラフを右クリックしてExport outputs as bitmapsでテクスチャとしてグラフの結果を出力します。

2019 12 19 11 53 25

LOD2のテクスチャを作成する

LOD2のテクスチャはLOD1のテクスチャの作り方と同じです。 ハイポリからメッシュのノーマルマップとBent Normal、アンビエントオクルージョンマップをベイクします。 LOD0からBase ColorとMetallicとSmoothness、Micro Normalをベイクします。

ボルトのようなものを平面にベイクするにはAverage normalsを外すとよいかもしれません。

2019 12 19 12 00 52

Gamasutra: Peter Kojesta's Blog - Skewmesh Tutorial: Remove Skewing in Normal map bakes

Average normalsの場合。

2019 12 19 12 02 59

Average normalsをオフにした場合。

2019 12 19 12 03 37

新しいグラフを作成し、RGBA mergeでMaskMapを作成、Normal Combineでノーマルを作成します。

HDRPに持ち込む

HDRPのUnityプロジェクトを新しく立ち上げます。

2019 12 19 12 25 30

LOD0、LOD1、LOD2のモデルをUnityに読み込みます。

2019 12 19 12 41 58

マテリアルをセットするためのPrefab Variantを作成します。

2019 12 19 12 42 29

2019 12 19 12 43 29

テクスチャをUnityに読み込みます。

2019 12 19 12 44 23

NormalとBent NormalについてはTexture TypeをNormal mapに変更しApplyします。

2019 12 19 12 45 06

MaskMapのsRGBのチェックを外します。

2019 12 19 12 46 16

LOD1、LOD2のテクスチャを必要に応じてMax Sizeを小さめにします。

2019 12 19 12 47 04

2019 12 19 12 48 23

「Create > Material」でMaterialを作成します。

2019 12 19 12 49 25

マテリアルのテクスチャに対応するテクスチャをドラッグ&ドロップしていきます。 Metallicを1に指定します。

2019 12 19 12 51 21

2019 12 19 12 51 31

2019 12 19 12 51 10

さきほど作成したPrefab Variantにマテリアルを設定します。

2019 12 19 12 52 03

2019 12 19 12 52 20

2019 12 19 12 52 36

適当なシーンを作りました。

2019 12 19 12 52 54

2019 12 19 12 53 04

空のGameObjectを作成しLODのルートとします。

2019 12 19 12 53 39

LODのルートの下にさきほど作成したPrefab Variantを配置します。

2019 12 19 12 54 18

LODのルートオブジェクトに「Lod Group」コンポーネントをアタッチします。

2019 12 19 12 55 06

ドラッグ&ドロップでLOD Groupを設定します。

2019 12 19 12 56 14

好みでクロスフェードにしました。

2019 12 19 12 58 28

あとはルートのオブジェクトをProjectビューにドラッグ&ドロップしてprefab化して完成です。

2019 12 19 13 01 09

2019 12 19 13 02 06

2019 12 19 13 02 35

2019 12 19 13 05 13

2019 12 19 13 05 25

DetailMap無し・opacityベイク有りバージョン

次にLOD2のOpacityベイクを入れたバージョンをやっていきます。

3Dモデルの準備

次のようなモデルを用意しました。

ハイポリ:

2019 12 19 17 50 05

LOD0:

2019 12 19 17 51 05

2019 12 19 17 51 37

LOD1:

2019 12 19 17 52 07

2019 12 19 17 52 17

LOD2:

2019 12 19 17 53 56

2019 12 19 17 54 07

LOD2ではポリゴンで表現することを諦めてalpha clipしようと考えています。

Alpha Clipに使用するアルファをどうするかですが、 Substance DesignerではOpacityをベイクする事ができるのでそれを使います。

Substance PainterでLOD0のテクスチャ作成

2019 12 19 18 04 34

テクスチャを適当に作成しました。

先ほど作成したプリセットを利用してExportします。

Substance Designerで各LODのテクスチャの作成

LOD0、LOD1のテクスチャの作成は先程と全く同じです。

LOD2のハイポリのベイクの際に、「Opacity Mask from Mesh」を追加しopacityマップを作成します。

2019 12 19 18 13 45

2019 12 19 18 14 20

BaseColorのalphaをこのopacityマップに置き換えます。 BaseColorとOpacityをグラフにドラッグ&ドロップします。

2019 12 19 18 22 03

Alpha mergeノードを使ってalphaを置き換えます。

2019 12 19 18 21 22

UnityでLOD2のマテリアル作成時にAlpha Clippingを有効にします。 Double-Sidedも有効にします。

2019 12 19 18 30 42

LOD2のモデルを表示したところです。

2019 12 19 18 30 59

LODを適用するとこんな感じになりました。

DetailMap有りバージョン

HDRPのLitシェーダにはDetail Mapという機能があります。 その機能を利用する例も示しておきます。

モデルの準備

次のようなモデルを用意しました。

ハイポリ

2019 12 19 18 39 08

LOD0

2019 12 19 18 39 58

UV

2019 12 19 18 40 12

UV1

2019 12 19 18 40 46

LOD1

2019 12 19 18 42 12

UV

2019 12 19 18 42 26

UV1

2019 12 19 18 42 39

LOD2

2019 12 19 18 44 40

UV

2019 12 19 18 48 04

UV1

2019 12 19 18 48 16

広い天面のあるモデルです。 この天面部分にDetailMapを適用していきます。

各LODのモデルにはUVとUV1が展開されています。

UVでは天面はだいぶ小さめに展開されています。 UV1では天面を全面に展開しています。

Substance Painterでテクスチャを作成する

「TEXTURE SET SETTINGS」の「Channels」から「Blending mask」を追加します。

2019 12 19 18 49 16

「Blending mask」が天面の部分だけ白くなるようにマスクを作成します。

2019 12 19 18 53 40

天面のディティールはあとから追加するのでnormalマップとRoughnessマップはとりあえず単色を出力するようにしておきます。 天面を濡れた路面にしたいのでラフネスは低く設定しています。

2019 12 19 18 54 56

2019 12 19 19 44 39

2019 12 19 18 55 31

コンフィグからGrayマップを追加してDetail Maskの「Blending mask」をMaskMapとして出力するようにします。

2019 12 19 18 57 48

エクスポートすると、BaseColor、MaskMap、Normal、Metallic、Smoothness、DetailMaskが出力されます。

Substance Designerで各LODのテクスチャを作成する

LOD0は最初の手順と同じです。

LOD1とLOD2では、LOD0から転写する際に「Transferred Texture from Mesh」をさらにもう一つ追加してDetail Maskを転写します。

2019 12 19 19 05 38

2019 12 19 19 05 15

RGBA mergeでMaskMapを作成する際にDetail Maskをbに入れてやります。

2019 12 19 19 46 23

Substance DesignerでDetail Mapを作成する

アスファルトのsbsarファイルをベースにDetail mapを作成していきます。

DetailMapはrがアルベドのグレイスケール、gとaがnormalのyとx、bがsmoothnessとなっています。

Mask and detail maps | High Definition RP | 7.1.6

sbsarからアルベドとノーマル、Glossinessを引っ張ってきてテクスチャを作成します。

2019 12 19 19 14 49

アルベドがそのままグレイスケール化すると最終結果が暗くなりすぎたのでレベルノードを挟んで若干明るくしています。 これでよいのかは不明です……。

2019 12 19 19 25 52

できたマップを出力します。

UnityのHDRPでマテリアルにテクスチャを割り当てる

Detail mapをインポートしたらsRGBのチェックを外します。

2019 12 19 19 26 53

マテリアルのDetail mapのテクスチャスロットにDetailMapテクスチャを割り当てます。 するとタイリングの設定などが出てきます。

2019 12 19 19 49 22

今回のモデルは大きめなのでタイリングをさせて細かいディティールをよい感じにします。 Detail Mapのアルベド、ノーマル、スムースネスの強さも適当に設定します。

次のようになりました。

2019 12 19 19 50 30

天面に近づいても十分なディティールを保てていることがわかります。

2019 12 19 19 51 13

天面のUVには左下の水色の部分しか割いていないのですが、UV1でDetail Mapを与えることで十分なディティールが保ててよいですね。

2019 12 19 19 56 15

Detail mapは全LODで共通のものを使っています。 他のマテリアルでもDetail Mapだけ使いまわしていけますね。 その他のテクスチャの解像度を下げてもDetail Mapだけ解像度高くしておけばごまかせたりもします。

2019 12 19 19 58 35

2019 12 19 20 13 17

おわりに

HDRP向けLOD対応のテクスチャの作成手順メモでした。

正直、割と手間なのでLODモデルは自動生成したほうがよいのではという気分になってきました……。 Simplygonとか有名ですよね、使ったことないのでどんな感じなのかはわからないですが。 あの手の自動LOD生成ってどのくらいのクオリティなんでしょうね。気になります。

なにかこの記事で不明な点、気になる点があれば私のTwitterアカウントにどうぞ。