Blender→PlayCanvasのLightmappingで室内3Dモデルのクオリティを上げよう

この記事はWebGLベースのゲーム開発エンジンPlayCanvasでシーンを構成する前提で書いています。
PlayCanvasアカウントをお持ちでない方は[**こちら**](https://playcanvas.jp/)

**PlayCanvasアカウントをまだ作成していない場合**は、3分でアカウント作成から3Dモデルビュワーまで体験ができるチュートリアルがございますので、まずはこちらから参照ください。
→ https://support.playcanvas.jp/hc/ja/articles/4404199480089

3Dモデルの室内シーンなどで、ライトや環境光の綺麗な入り込み等を表現しようとするとPlayCanvasのビジュアルエディター上でライトや環境光(CubeMap)を生成する必要があります。
しかし、web上でリアルタイムに光や影を表示すると、シーン全体の描画にそれなりの負荷がかかります。フレームレートが30を下回るとかなりカクカクした感じになってしまうので、回避したいですよね。

そこで、ライト(光)情報をテクスチャに焼き付け(ベイク)してしまおう！ということになりますが、デフューズマップ(カラー情報、Albedo)に光源情報を内包したテクスチャを生成すると、その後の変更がとっても面倒なことになります。
例えば、床のテクスチャをタイルから木の模様質感に変えたい、タイリングサイズ変えたい…なんてことが発生した場合、Blenderやその他のDCCツールで再度設定してベイク処理が必要になります。また、シャギーやチラつき、ディテールの再現性を考慮に入れるとテクスチャの解像度もかなりのサイズ(1024とか2048とか)になり、且つそれがオブジェクト毎に必要となると、テクスチャセットだけでもかなりの容量となります。

そこで、シーン全体のライトの情報(間接光と直接光)のみを取り出したテクスチャと、デフューズ等その他テクスチャを別にしてクオリティアップ ＆ 容量の削減 ＆ オブジェクトのテクスチャカスタマイズ性の向上を図っていきたいと思います。

Blenderでのテクスチャ生成とPlayCanvas上での設定方法を解説していきます。

# 目次
[PlayCanvas上でのLightMap ON/OFFシーンを見てみる](#playcanvas上でのlightmap-onoffシーンを見てみる)
[BlenderでのLightmapの生成手順](#blenderでのlightmapの生成手順)
[BlenderのUVチャンネルとPlayCanvasのUVチャンネル](#blenderのuvチャンネルとplaycanvasのuvチャンネル)

# PlayCanvas上でのLightMap ON/OFFシーンを見てみる
このシーンにはライトオブジェクトは配置していません。なので、**LightMapがOFFの状態**にすると画面がほぼ黒になります。

## LightMapがONの状態
![lightmap_on.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/ee06ab8e-b048-fac6-0708-5473c0a7ee3a.png)

## LightMapがOFFの状態
![lightmap_off.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/00963466-f513-f204-dcf6-76b8f43eec6b.png)
エミッシブで照明を表現している部分と、メタル部分はLightMapテクスチャを使用しません。
※照明はエミッシブ(自己発光)100％。メタル部分は環境光を反映させるため。

ここで、**LightMap**テクスチャをPlayCanvasのfloorマテリアルに適用してみます。
![lightmap_floor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/70634286-d536-9881-5d2e-6e4a698fcdc3.png)
これで、床部分にライト情報が入りました。
![lightmap_floor_editor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/048d7d29-d45c-4d88-4e89-6393ce40c41a.png)
この1枚の**LightMap**テクスチャを各オブジェクト毎に設定していきます。

因みに、PlayCanvas上でライトを設定するとこんな感じです。ポイントライト×1スポットライト×2
![lightmap_no.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/d75094ff-c637-5294-8c9d-aa9fe15ee2c6.png)
法線を内向きにしたPlaneポリゴンの閉じた空間になっているため、ディレクショナルライトは床面にしかあたりません。なので、代わりにポイントライトで全体を照らしていますが、間接光特有の柔らかい光の反射が再現出来ていません。そして処理が重いです。。。

# BlenderでのLightmapの生成手順
PlayCanvasに適用させる**LightMap**の生成手順を説明します。
ここではBlenderをベースに、この3Dモデルに対する設定を解説します。
![blender_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/c1a55411-47e7-4113-833b-70227c5ec4f3.png)
↓↓↓↓↓↓↓ あなたの記事の内容

1. 室内3Dモデルに対して間接光**ポイントライト**と**サン**でライティング。
2. 天井、壁、床のエッジを選択しシームをマークし、エッジを分離しておきます。
3. 作成した3Dモデルを**スマートUV投影**もしくは**ライトマップパック**でUVを展開。
4. レンダリングのベイク設定を下記画像の様に設定し、ベイクしてください。
───────

1. 室内3Dモデルに対して間接光"ポイントライト"と"サン"でライティング。
2. 天井、壁、床のエッジを選択しシームをマークし、エッジを分離しておきます。
3. 作成した3Dモデルを**"スマートUV投影"**もしくは**ライトマップパック**でUVを展開。
4. レンダリングのベイク設定を下記画像の様に設定し、ベイクしてください。

↑↑↑↑↑↑↑ 編集リクエストの内容
![blender_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/9758bf26-474c-27f9-b29b-f8fc52fb111b.png)

- ベイクタイプを"ディフューズ"に変更。
- **影響**項目の中の **Contributions** のカラーのチェックを外します。
- **出力**項目の**余白**の値が大きいと隣接するUV領域同士に影響が反映されてしまうので、小さ目な値に。

レンダリングのサンプル数が少ないと画像に多くのノイズやシャギーが入ります。サンプリング数を上げましょう。
(相対的にレンダリング時間が増えますが、その辺はPCのスペックと要相談ですｗ)

気合でPhotoshopで調整することも可能ですが、ここでは割愛します。
↓↓↓↓↓↓↓ あなたの記事の内容
ベイクが完了すると下記画像の様に出力されますので、画像を保存。
───────

↑↑↑↑↑↑↑ 編集リクエストの内容
![lightmap4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/3e351397-e451-18b0-62e5-d106127d816a.png)
サンライトの白系の色味とポイントライトの暖色系の色味が反映された画像になっているのが確認できます。

# BlenderのUVチャンネルとPlayCanvasのUVチャンネル
BlenderとPlayCanvasのUVマップのチャンネルを確認しましょう。
BlenderはUVマップのチャンネルをいくつでも作れますが、PlayCanvasは2つのUVマップチャンネルのみ指定できます。
blender上で2つ以上のUVマップチャンネルを保持した状態でFBXへエクスポートするとPlayCanvas上で予期しないUVが適用される場合がありますので、必ずblender上でのUVマップチャンネルを確認してください。
通常、デフォルトのプリミティブ形状からモデリングした際にUVは自動で展開された状態にはなりません。今回は**BlendereKit** というアドオンを使用し、テクスチャの質感を指定しています。
BlendereKid を適用したオブジェクトには **automap** というUVマップチャンネルが自動で生成されます。これがPlayCanvas上では UVChannel **UV1** に当たります。
LightMap以外(場合によってはアンビエントオクルージョンも)のテクスチャはこの **UV1** に設定します。
![blender_5_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/2b15050c-eb61-a4ed-cb4b-3f393cf088ac.png)

lightmap用のUVマップはPlayCanvas上では**UV0**となります。
![blender_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/8102dbe7-6ada-ac66-f1e3-ebe8fd1a10f2.png)

↓↓↓↓↓↓↓ あなたの記事の内容
これで、lightmapのテクスチャの生成とPlayCanvasでの設定は以上となります。あとは、個々のオブジェクトのマテリアルに対してlightmapテクスチャとその他のテクスチャを設定していけば完了です。
───────





# BlenderのUVチャンネルとPlayCanvasのUVチャンネル
テスト

↑↑↑↑↑↑↑ 編集リクエストの内容