ビルの制作記録

はじめに

ここ何日かの間、ビルのモデリングを行っていました。 残念ながら完成には至りませんでしたが、その作業記録を残すことにします。

ポリゴンを差し込んだ形状について

今回はポリゴンを差し込んだ形状を多用しています。 ハイポリのモデリングにおいてはポリゴンを差し込んだ形状は避けられるようです。 ポリゴンを差し込んだ形状はその境界面の不自然なのが目立ちます。

この不自然さを気にしないのであれば、ポリゴンを差し込んだモデルを作っても問題ないようです。

ポリゴン差し込みでモデルを作る利点は2つあります。 1つはポリゴン差し込みだとポリゴン数が減ること。 もう1つは構造が分離しているので作業がしやすいことです。

今回はそこまでアップにしてモデルを映すつもりはないので、 作業のしやすさを取ってポリゴン差し込みを多用しました。

アセットの作成

ビルを作り始める前に、必要になりそうな小物を使い回しできるように それぞれ別blendファイルで作成します。

窓や扉の作成

今回は窓をBooleanで作成します。

まずは原型を作ります。

CubeをSキーで拡大します。

次にCtrl-Rでループカットをします。

IキーのInsertとEキーのExtrudeで窓の形を作ります。

Booleanを利用して型をつくります。 新しいCubeのオブジェクトを作り、BooleanでDifferenceにします。 型のオブジェクトの原点がちょうど壁面の位置となるようにしておくと、 型を抜くときが楽です。

型のオブジェクトのエディットモードに入って2mmほどずらします。 Booleanを使ったときに余計な面が生成されるのを避けます。

この型を使ってBooleanを使えば窓が簡単に作れます。

Booleanを使ったあとは面がNゴンになるので、そこは注意が必要ですが。

同様にしてバリエーションを作っていきます。

角の場合も同様に作ります。

自動ドアのセンサー部分やドアの取手などは別オブジェクトで作成し、 型とは分離しておきます。

今回はポリゴンの差し込みで十分なので、これらのパーツは型には含めません。

ベランダ

Cubeを用意します。 壁に設置する面の面は不要なので削除します。

IキーのInsertとEキーのExtrudeとXキーでの不要な面の削除で形を作ります。

Iキーで面の挿入をしました。

Xキーで余計な面を削除します。

辺を選択して移動させました。

Eキーで押し出しします。

余計な面が生成されるので削除します。

横に広げます。 横の部分を選択して移動します。

このようになりました。

下側もIキーやEキーを利用して作ります。

次に手すりのオブジェクトを作ります。 シリンダーを縮小しCubeを拡大縮小したものを追加します。

Arrayモディファイアをつけます。

ベランダから手すりを配置する位置を削ります。 あとで調整できるようにBooleanモディファイアを使います。

屋外用コンセント

CubeをベースにExtrudeやループカットなどを利用して形を作ります。

つまみをシリンダーを追加して作ります。

スムーズシェーディングを適用します。 オートスムースの角度指定やシャープ辺で必要な角を残したままスムースにします。

ケーブルを作ります。 Cubeを拡大縮小します。

カーブオブジェクトを用意します。

FullにしてBevelに0.005程度を入れます。

Bevelでは断面形状を指定することもできますが、 断面が円形でよいならば指定する必要もありません。 Resolutionが低いので円になっていませんが。

パラボラアンテナ

まずは土台から作ります。 Cubeをループカット、拡大縮小、Extrudeを使ってH状の形を作ります。

余計な面を削除してFキーで面を貼ります。

Eキーで辺を押し出します。

グリッドフィルで面を埋めます。

引き伸ばしてループカットを適当に加えます。

カーブ変形モディファイアで曲げます。

Cubeを追加して拡大縮小します。

シリンダーを適当に追加します。

次にパラボラアンテナ本体を作ります。 円を追加します。

グリッドフィルを使います。

Eキーで押し出します。

プロポーショナル変形で中央の頂点を選択して移動します。

Cubeを追加して縮小します。

ループカットをします。

面を押し出しします。

押し出した部分を移動します。

反対側も同様にします。

押し出しをします。

次のようになりました。

カーブモディファイアを使って次のような形状を追加します。

Ctrl-Jで2つのオブジェクトを結合します。

Cubeを縮小して配置します。

ループカットします。

Jキーで面を分割していきます。

頂点ベベルを行います。

IキーとY軸方向の移動を使って形を作ります。

次のようになりました。

これまでと同様にしてCubeをループカットしたりEキーを使ったりして パラボラアンテナと土台を接続する部分を作成します。 シリンダーは差し込んでいるだけです。

カーブオブジェクトを追加します。

すべてのオブジェクトをEmptyの子にしておきます。 こうすることですべてのオブジェクトを一括で動かせて便利です。

パラボラアンテナが完成しました。

看板の作成

CubeやCylinderの拡大縮小やEキーIキーなどを利用して作りました。

次の看板の角の丸みは辺のベベルを使って作りました。

のぼり

Clothを利用してみます。

Planeを拡大縮小し適当にループカットをします。

新しい頂点グループを作成し、ピンどめする頂点を選択して割り当てます。

Clothシミュレーションのモディファイアをつけます。

ピンどめする頂点を設定します。

再生するとシミュレーションが実行されます。 よい感じの形になったフレームでClothをApplyすることで形状を確定できます。 そのままClothシミュレーションにかけるとあまりにも動かなさすぎたので 微妙に斜めに傾けてからシミュレーションを開始しました。

あまり大きく変形するわけでもないし、Clothを使うまでもなかった気もします。

残りの部分を作ります。

ライト

シリンダーを縮小しループカットします。

押し出しをします。

底を拡大します。

ループ選択して押し出しします。

拡大します。

先端を縮めて全体を移動します。

キューブを追加します。

薄く縮小してループカットをします。

押し出しをします。

ループカットをします。

丸くなるように持ち上げます。

シリンダーを配置します。

電球の部分に球体を配置します。

ベースの部分を複製します。

反転して縮小します。

別オブジェクトに分離します。

底の部分を拡大します。

押し出しします。

原点の位置を調整します。

ベースとライトの部分に親子関係を作りました。

カーブオブジェクトでコードを作って完成です。

排気口

Cubeを縮小し、IとEで凹ませます。

壁に設置する側の不要な面を削除し薄くなるように縮小します。

別オブジェクトでCubeを縮小回転します。

Arrayモディファイアを利用します。

その他

その他いろいろ作りました。

IDマップ用のマテリアルの割り当て

IDマップ作成のため材質ごとにマテリアルを割り当てていきます。 IDマップ用なので適当にディフューズカラーを割り当てただけの適当なマテリアルです。

今回はテクスチャを全体で1つにまとめる予定のため、 個別にテクスチャの割り当てはしていません。 後で全部まとめてUV展開します。

ビルのモデリング

Cubeを拡大します。

ループカットをします。

押し出しをします。

ループカットを加えます。

重なってしまった面を削除します。

重複頂点を削除します。

さらに押し出しをします。

Cubeの不要な面を削除したものを配置します。

ポリゴン差し込みで作ると楽でいいですね。

同様にポリゴンを差し込みます。

Cubeを拡大します。

直方体をBooleanで抜きます。

窓をBooleanで抜きます。

別blendファイルのオブジェクトを読み込むにはapendを使います。

階段を配置します。

階段の先は外からはあまり見えないので作っていません。

次に看板や排気口などを設置していきます。

上に少し伸ばしてベランダを追加します。

窓を抜きます。

上面を複製して別オブジェクトに分離します。

余計な面や頂点を削除します。

引き伸ばして直方体にします。

余計な面を削除します。

Cubeの余計な面を削除したものを追加していきます。

ベランダになる部分も追加します。

窓を抜きます。

底面を少し凹ませます。

さらに窓を抜きます。

ベランダの手摺を追加します。

排気口を追加します。

手すりや排気口を結合してひとつのオブジェクトにします。

複製をして上に配置します。

こちらは下とくっついているため底面のディティールは必要ないので削除します。

Arrayモディファイアで一気に上に伸ばします。

裏側にも小物を付けていきます。 裏側はあまり使うつもりないので適当です。

てっぺんを作ります。 適当にCubeを配置しました。 下からはほとんど見えないのでこれで十分でしょう。

パラボラアンテナと看板を追加でいくつか配置しました。

IDマップ用にマテリアルを割り当てていきます。

全オブジェクトを選択してUV展開を行います。

今回は実験的に建物ひとつを一枚のテクスチャにまとめてみます。 今回のモデルはゲーム用ではありませんが、 ゲームなどではテクスチャの枚数やテクスチャサイズを減らすことが重要になるそうです。 今後ゲーム向けのモデリングも挑戦したいと思っているので、 今回はそれの実験を兼ねてテクスチャ一枚に収めてみることにします。 あとで詳しく書きますが、残念ながらこの試みは失敗しました。

複数オブジェクトをひとつのUVにまとめるのにはTexture Atlasというアドオンを利用します。 UV展開は自動展開にすべてを任せることにします。

まずはTexture Atlasのタブから「+」ボタンを押します。

次に「StartManualUnwrap」ボタンをクリックします。

するとすべてマージされたオブジェクトが生成されます。 このオブジェクトのUV展開を行ってから「FinishManualUnwrap」をクリックすると すべてのオブジェクトをひとつのUVにUV展開ができます。

今回は自動展開で全部済ませます。

OKを押してから少しの間blenderが応答なしになりましたが、 問題なくUV展開できました。

壮観ですね。

下からは見えない屋上にUVの大きな面積を使っているのが気になりますが、 修正するのも面倒なのでこれでよしとします。

TexToolsのマテリアルIDのベイク機能を使ってIDマップを作成します。

ベイク時にまたBlenderが応答なしになりましたがベイクできました。 ベイクした結果を保存します。

拡大してみると細かい部分では色が溢れています。

全部をひとつのテクスチャにまとめるのは無謀だったのかもしれません。 このまま作業を進めてみて問題が発生したらUVの展開をやり直すことにします。

マテリアルの作成

いくつかのマテリアルをSubstance Designerで作成してSubstance Painterへ持ち込みます。

壁のマテリアルの作成

メインの壁のマテリアルを作りました。 タイルっぽいパネルがはられているイメージです。

Heightを「Tile Generator」と「Levels」で作成しました。

NormalにはHeightを引っ張ってきます。

Hightから作成したNormalに「Fractal Sum Base」から作ったザラザラしたNormalを 「Normal Blend」で重ねています。

Base Colorは「Fractal Sum Base」と「Perlin Noise」に「Levels」と「Gradient Map」を かけたものを最初の「Tile Generator」でマスクしてブレンドしています。

MetallicにはHighetに「Curvature Smooth」と「Levels」をかけたものです。

エッジの部分が明るく光を反射するようにしてエッジを強調しているつもりです。

Roughnessも「Curvature Smooth」と「Levels」を使いました。

ノード全体は次のとおりです。 ただのタイルでひび割れとかもないので非常にシンプルですね。

壁のマテリアル2つ目作成

もうひとつ壁のマテリアルを作りました。

ザラザラした壁です。

「Fractal Sum Base」からNormalとBase Colorを作成しています。 HeightとRoughness、Metallicは「Uniform Color」です。

Base Colorには「HSL」ノードを挟んでexposeすることで色合いを調整できるようにしました。

大理石のタイルのマテリアルの作成

大理石のタイルのマテリアルを作りました。 大理石のつもりです。

Substance Designerに入っているノイズにすでに大理石っぽいものがあるので それをベースにしています。

最初に「BnW Spots 1」と「Grunge Map 008」をブレンドモードMinで混ぜています。

「Cell 3」に「Directional Wrap」をかけます。 「Directional Wrap」には「Crystal 2」を斜めにしたものを与えています。

上記ふたつをMaxでブレンドします。

「Gradient Map」をはさみます。 大理石の写真から色を取りました。

「Cells 1」から大理石の白い部分を作ります。 「Gradient Map」で白と黒をはっきりさせて「Directional Warp」で歪めています。 なぜ「Gradient Map」を使ったのか覚えていません。謎です。 「Histogram Scan」とかでよかった気がします。

これらをまとめて大理石の色としました。

「Tile Generator」からタイルを作ります。 「Warp」で縁を微妙に歪めました。

「Flood Fill」と「Flood Fill to Random Grayscale」をつかって タイルごとにランダムなグレースケールを用意します。

「Directional Warp」にグレースケールを入れてIntensityを思いっきり大きくして 大理石のカラーをタイルごとにばらばらにします。

タイルの隙間の部分を白っぽい色にします。 これでベースカラーを完成とします。 「HSL」ノードを挟んでexposeすることで色味を調整できるようにしました。

「Curvature」ノードでタイルのエッジの部分を取り出します。

このエッジの部分をラフネスやメタリックに利用します。 エッジの部分の光の反射を強くすることでタイルのエッジを目立つようにします。

「Flood Fill to Gradient」でタイルごとのグラデーションを作って ハイトマップを作ります。

完成したタイルは次のようになりました。

地面のタイルのマテリアルの作成

次の動画を参考にしながらひび割れのあるタイルを作ります。 タイルの形状は動画とは変えています。

次にタイルのエッジが欠けているのを作ります。

最初に「Tile Sampler」で「Shape」を配置します。 「Size」のXとYを調整して縦長の形を配置します。 タイルと同じ感覚を開けたマスク画像を用意して「Shape」を配置する場所を 縦方向のタイルとタイルの隙間に制限しています。

Mask Randomをexposeしました。 これによってエッジの欠けている量を調整できるようにします。 「edge_damage」という0から1までの値を入力として受け取るようにします。

「One minus」ノードを使ってMask Randomに与える値を反転します。 これでedge_damageが大きいときにMask Randomが小さくなり、 Shapeの配置数が多くなってエッジが欠けている量が増えます。

「Slope Blur Grayscale」に「Fractal Sum Base」と合わせて ガタガタの形状にします。 「Levels」ノードを挟んで白よりにします。

同じもので横方向のものを作成してBlendノードのMaxで合わせます。

これをハイトマップからSubtractで合成します。

タイルとタイルの隙間の部分にコンクリートっぽいざらつきを与えるために 「Fractal Sum Base」をブレンドしています。

タイルのエッジが欠けている部分に欠ける前のタイルの隙間の幅を少しだけ盛り上げて タイルが欠けてなくなったようにします。

タイルそのものがなくなるようにしました。 このタイルがなくなる量もパラメータで調整できるようにexposeしました。

「Fractal Sum Base」に「Gradient Map」をかけたものをベースにして ベースカラーを作りました。 「Dirt」ノードに「Gradient Map」で茶色くしたものを薄く混ぜています。 「HSL」ノードを挟んで色をパラメータで調整できるようにしました。

RoughnessやMetallicについては上で作った別のタイルとほとんど変わらず エッジの部分をちょっと反射を強くして適当な値を与えてあります。 ちょっとエッジを強調しすぎた気もします。

できあがったマテリアルは次のようになりました。

パラメータを変えることで次のようになります。

地面の四角いマンホールのマテリアル

マンホールのマテリアルを作りました。 これはリピート無しで配置して使う予定です。

適当にShapeなどをつなげて金属部分のマスクを作成しました。

タイルにはさきほど作ったタイルのプロパティを適当に設定したものを使っています。

マスク用の画像も出力に加えました。

Substance Painterでマテリアルを割り当てる

まずはBlenderでIDマップ用に割り当てていたマテリアルを削除して 1つのマテリアルだけを割り当てます。

BlenderはNormalマップがOpenGL系らしいのでそのように設定してプロジェクトを作ります。

早速IDマップを使ってマテリアルを割り当ててみます。

マテリアルを割り当ててみるとすぐに解像度が不足していることに気が付きます。 パターンを思い描いたスケールにするとパターンが判別できないほど潰れてしまいます。 パターンが潰れない程度のスケールにすると今度はパターンが大きすぎます。 これでもSubstance Painterの最大サイズの4096×4096のテクスチャを利用しています。

これはUV展開を見直す必要があります。

UVを見直す

全部を一枚のテクスチャに収めるのは無理があることがわかりました。 どう考えても解像度が足りません。 いくつかのテクスチャに分割することにします。

特に壁のタイルが潰れてしまうのは普通にUV展開するとどうしようもない感じです。 そこで地面や壁などの繰り返しているテクスチャはタイリングのリピートを利用してみることにします。 次のようにUVをはみ出すように展開するとテクスチャのリピートが効いてよい感じになります。

Substance Painterの投影方法はTri PlanarではなくUVにする必要があります。

この方法だとベイクしたテクスチャもリピートしてしまうので、 ベイクしたテクスチャは正常に利用できなくなります。 次の画像はベイクしたPositionです。 リピートしてしまって正常にベイクで来ていないことがわかります。

Substance Painterではベイクしたテクスチャをもとに汚れなどを与えることができますが、 このようにリピートさせる場合にはそのようなことはできなくなります。 本当に単純なパターンで十分な、細かい書き込みが必要ない部分のみ、 このリピートの方法をつかいます。 今回のモデルでは、壁や地面などの単純なリピートでよい 面積の広い部分はこのテクスチャのリピートを使うことにします。 地面と壁2種類、そして屋上に乗っている直方体は、 どれも面積が広いけれども細かい書き込みも必要ありません。 同じパターンが繰り返すだけでよいのでこれらの部分に 本体とは別のテクスチャをそれぞれ割り当てることにします。

壁2種類と地面、屋上に乗っかってる直方体、 そしてその他窓や看板などの5つのテクスチャに分割します。

最初は1つのオブジェクトにUVを複数用意して作業を進めていましたが、 Substance Painterでは1つ目のUVしか見てくれないようで失敗しました。

Substance PainterでTexture Setごとに異なるUVを割り当てたい場合は、 それぞれを別オブジェクトに分離してからUV展開する必要があるようです。 1つのオブジェクトに付きUVは1つだけになるようにします。 今回はテクスチャをリピートさせたい壁は別オブジェクトに分離してUV展開することにしました。 次の画像を見ると壁と窓は別オブジェクトに分離していることがわかります。

壁のUV展開は次のとおりです。

UVの1×1の正方形から大幅にはみ出す形にしています。 UVの正方形部分にリピート可能なパターンを配置すると 壁のタイルがテクスチャの解像度によって潰れることを避けられます。

地面のUVも同様に展開しています。 これで地面のタイルが潰れることはなくなりますが、 そのかわりこのままではマンホールを配置できなくなりました。 マンホールを配置するとそれがリピートしてしまいます。 マンホール部分だけ別のオブジェクトにするということが考えられますが、 今回はマンホールの配置を見送ることにします。

同様にしてもうひとつの壁のUVもUVの正方形からはみ出す形で展開しました。

屋上の直方体のUV展開は次のとおりです。 タイル地にするつもりはないのでテクスチャのリピートを前提にしたUV展開は必要なさそうです。

その他、壁や地面以外の窓や看板などをまとめたUVは次のとおりです。

なんだかこれは解像度が足りなさそうな気がしますが、 とりあえずこのまま作業を進めることにします。

とりあえず壁と地面タイルを割り当てて窓にもマテリアルを割り当ててみました。 Substance Painterだとmipmapが効いていないような見た目になっていますね。 何かここらへんの設定がどこかにあるのでしょうか。

看板などはまだマテリアルを割り当てていませんが、 とりあえず途中のものを書き出ししてBlenderに持ち込んでみます。

今回はBlenderのCyclesを利用します。 PBR向けのノードとして「Principled BSDF」というノードが用意されています。 このノードにSubstance Painterから書き出したテクスチャを与えます。

テクスチャは「Non-Color Data」として読み込みます。

フリーのIBL画像を読み込みます。

ビルのような大きいものに対して普通のIBL画像でよいものか気になりますが。

Hemiライトも適当に配置しました。

レンダリングをしてみると次のようになりました。

壁のタイルのパターンは潰れていないことがわかります。 テクスチャがリピートしていることが分かるような気もしますが許容範囲内ということにします。

タイルの向きが一部食い違っている部分があります。 タイルの向きを揃えるためにUVを調整します。 UVエディタと3DエディタをSyncさせるとUVエディタの選択と 3Dエディタでの選択がリンクします。 これによって3Dエディタでの面がUVエディタではどこに当たるのかがわかります。

タイルの向きがおかしかった部分のUVを回転させてタイルの向きを合わせます。

タイルの向きが正しくなりました。

この調子で他のマテリアルを割り当てていこうとするとうまくいかないことがわかりました。 マテリアルがきっぱりと別れてほしいのに滲んでしまっています。

IDマップを見てみると確かに色が滲んでいて、どうやらIDマップの解像度が足りていないようです。

やはり看板や窓などを全部ひとまとめに「その他」へ割り当てたのは無理があったようです。 もう少し細かくオブジェクトごとにテクスチャを割り当てる必要がありそうです。

そうなるとビルのモデリングを最初から作り直したほうが楽な気がします。 このまま作業するとなると、 1つに結合してあるオブジェクトから選択して分離してUV展開をして個別にテクスチャを割り当てて、 といった作業が必要でとても面倒です。 配置する看板などのオブジェクトごとにあらかじめ展開とテクスチャの割当を済ませておいて、 その完成したオブジェクトを置いていくといった形で作業をしたほうがよさそうです。 すでに全部結合してしまった状態からリカバリーするより、 そうやって作り直したほうが楽そうな気がします。


気力が尽きて作業にも飽きてきたので 今回のビルのモデリングはここでいったんお蔵入りにすることにします。 また後日気力が湧いたらもう一度リベンジしてみるかもしれません。


ゲームなどのリアルタイム用のモデルはテクスチャのサイズや数を減らすことが重要だそうです。 今回のモデルは特にゲームに使うつもりはありませんでしたが、 今後ゲーム用のモデリングを行うときのために実験的な意味で 建物ひとつを一枚のテクスチャに収められるか試してみました。

結果は、ビルのような大きな建物を一枚のテクスチャにまとめるのは無理そうだ ということが分かりました。 描画負荷云々といった以前に解像度が圧倒的に足りなくなってしまうということが わかったのは今回のひとつの収穫です。

今後モデリングをする際はためらうことなくテクスチャセットを分けていくことにします。

おわりに

残念ながら今回のモデルの作成は未完に終わりました。 しかしその過程でいろいろと知見は溜まった気がします。 次回以降はきっと素晴らしいモデルをスムースに作れることでしょう。 次回の自分に期待することにします。