前回の続きです。
今回はBlenderでライトマップベイクをするところから説明します。
試した環境
Blender 2.93
Babylon.js 5.5.5
1. ライトマップベイクとは?
3DCGで綺麗な質感を表現する手段は色々ありますが、その中の1つがライティングです。光を当てた時の陰影や、強めの光による反射などがあるとフォトリアルな雰囲気が出ます。ライトマップベイクとは、当たった光の状態をテクスチャに上書き (ベイク) することで、常に照明が当たったテクスチャを再現するものです。
これにより、常時ライトを当てて計算をする処理負荷が減るので、綺麗な表現を低負荷で実現できることになるなどのメリットがあります。
その辺りは、この記事に書かれています。
なお、「pre-baked lightmapping」、「ライトマップベイク」、「ライトマップをベイクする」など、呼び方はいくつかあるようです。
2. ライトマップベイクを実行する前にUV展開しておく
UV展開とは、3DCGオブジェクトのそれぞれの面にテクスチャを割り当てることです。単一テクスチャであればUV展開をしなくても割り当てはできますが、今回のライトマップベイクにはUV展開をしている必要があります。
UV展開の方法は色々な記事がすでにあります。たとえば以下が参考になります。
3. ライトマップベイクを実行する
色々と情報収集したところ、まずはレンダリングエンジンがEeveeになっていたらCyclesに変更する必要があります。Cyclesでしかライトマップベイクができないためです。
EeveeにしてみるとBakeのメニューが存在せず、Cyclesに変更するとBakeのメニューが表示されます。
次に、先ほど配置した3DCGのうち、ライトマップベイクを当てたいオブジェクトを選択して下記の画像の枠で囲った箇所を選択します。わかりやすいように番号をつけましたが、多少前後しても大丈夫なはずです。
(1) Render properties
(2) Bakeのオプション。全部チェックをつけておきます
(3) Bake実行ボタン
(4) Texture coordinateでは、UVからmappingに接続します。こうするとUV展開したテクスチャが割り当たります。
これにより、影がついたテクスチャが割り当たります。よい例のスクリーンショットが撮れなかったのですが、右側で赤枠で囲った場所に影がついているのが確認できます。
あとは、床にはテレビ棚の影をベイクしています。こちらの方がわかりやすいですね。
あとは個別のテクスチャについて、この操作を繰り返します。ソファとテレビ棚には後述のように光沢を出すようにしました。
glb形式で出力してBabylon.js Sandbox (3DCGモデルの表示を簡単に確認できるサイト) で表示させたのがこちらの動画です。
4. Tips
4.1 テクスチャが存在しないとライトマップベイクができない
ライトマップベイクの対象には、テクスチャをつけておく必要があります。たとえば先ほどの部屋にある椅子はMaterialのPrinclpled BSDFのcolorで青色にしており、Image Textureは使っていません。この場合、椅子の上部分 (Chair_up) を指定してbakeボタンを実行しても以下のエラーが出てベイクはできません。
No active image found in material "ChairUp" (0) for object "Chair_up"
これを解消するには、こちらで解説されているように空っぽのImage Textureを作ってからベイク処理をするのがよいようです。
しかし、試したところのっぺりした影しか付かず、微妙な陰影にはなりませんでした。まだ自分の理解が十分でないのでもう少し調べてわかったら追記します。
4.2 さらに光沢を出して質感を向上させる方法
すでに色々な方が記事を公開されていますが、金属の質感の場合はたとえばこちらが参考になります。
私はこれらの情報を調べつつ、ソファの光沢を出すために、SpecularとRoughnessを少し変更しました。
4.3 ライトマップベイクしたら真っ黒になる場合
よいスクリーンショットが残っていないのですが、ベイクをしたら真っ暗になってしまうことが何度かありました。
そのようなときは、Image Textureを指定してからベイク処理を実行すると解決しました。こちらの記事のおかげで解決できて助かりました。
4.4 ライトマップベイクしたらテクスチャの模様がおかしくなった場合
たとえばこのようになる場合です。
色々調べたところ、mappingノードのscaleを1に戻したら正しい表示になりました。これが正しい方法であるかはわかりませんが参考までに書きました。
ちなみに、mappingノードのscaleを変えていた理由は以下の方法を使ったためです。
5. おわりに
今回はほとんどBlenderの話でした。Blenderで作った内容がBabylon.jsできちんと再現されるのは安心ですね。
最近色々と試したいことが多いので次回の内容がどうなるかわかりませんが、きれいな表現についてまとめる場合、次回はBabylon.js側の処理できれいな表現をする方法について書きたいと思っています。