🌇

Babylon.js で空を作る

2022/05/02に公開

こんにちは。やまゆです。

https://www.babylonjs.com

ブラウザのリアルタイム3Dレンダリングエンジンである Babylon.js で、シーンに Skybox(つまり、空) を加える簡単な方法を紹介します。


完成予想図

Playground で簡単に加える

https://playground.babylonjs.com/

Babylon.js にはユーザーがブラウザ上で自由にスクリプトを定義してリアルタイムにシーンを構築出来る Playground が用意されています。今回はこちらで使える Assets を利用します。

Assets でアクセス出来るテクスチャやメッシュは、ドキュメントに書いてある通り CC-BY 4.0 ライセンスの上で利用することが可能です。全て GitHub で公開されています。

空を描画するには、箱のすべての面に割り当てる 6 枚のテクスチャが必要です。

https://doc.babylonjs.com/start/chap5/sky

このテクスチャは Cubemap と呼ばれることもあります。探せば、 Babylon.js 用ではないテクスチャでも利用できます(playground で公開するのであれば著作権は気を付けておきましょう)。

このテクスチャを CubeTexture として生成します。

さらに StandardMaterialreflectionTexture に先ほどのテクスチャを渡します(反射用のテクスチャ枠ですが、 Skybox としても利用できます)。

実際のコード

// テクスチャ生成(prefix を指定すれば自動で6枚読んでくれる)
const skyTexture = new BABYLON.CubeTexture(Assets.skyboxes.skybox_nx_jpg.path.replace('_nx.jpg', ''), scene);

// マテリアル生成
const skyMaterial = new BABYLON.StandardMaterial("cube_mat", scene);
skyMaterial.reflectionTexture = skyTexture;
skyMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE; // テクスチャを skybox 用にする
skyMaterial.disableLighting = true; // ライティングを無視する
skyMaterial.backFaceCulling = false; // 背面も表示する

// メッシュ生成
const skyMesh = BABYLON.MeshBuilder.CreateBox("cube_mesh", { size: 1000 }, scene);
skyMesh.infiniteDistance = true; // カメラからの距離に依存しないメッシュとみなす
skyMesh.material = skyMaterial;

https://playground.babylonjs.com/#UPAD6P


プレイグラウンドの初期要素に上記を加えた形

Assets.skyboxes.skybox_nx_jpg の所を変えれば、他のテクスチャを使うこともできます。

現在利用可能な Assets の skybox

2022/05 現在は下記のテクスチャを指定可能です。

Assets.skyboxes.skybox

Assets.skyboxes.skybox2

Assets.skyboxes.skybox3

Assets.skyboxes.skybox4

Assets.skyboxes.toySky

Assets.skyboxes.TropicalSunnyDay

SkyMaterial

Assets に公開されている Cubemap の他に、 @babylonjs/materials という別の npm パッケージとして配布されている特殊なマテリアルを使う手もあります。それが SkyMaterial です。 playground では BABYLON.SkyMaterial で利用することが出来ます。

SkyMaterial は、 Skybox のダイナミックでテクスチャフリーなエフェクトを作成することができます。
このマテリアルは、"A Practical Analytic Model for Daylight"(昼光に対する実用的な分析モデル) に基づいています。最初の実装は Simon Wallner、改良は Martin Upitis、最後に zz85 が Three.js に実装しました。
スカイボックスの課題は、大気の状態を考慮して空を再現し、設定することです。言い換えれば、例えば、(太陽からの)光が粒子によってどのように散乱されるかを決定することです。
DeepL にて翻訳+一部加筆
https://doc.babylonjs.com/toolsAndResources/assetLibraries/materialsLibrary/skyMat

これは先ほどの Cubemap とは違い、テクスチャを利用しません。代わりに、リアルタイムで光の散乱を計算し、疑似的に現実の空のようなレンダリングを行うカスタムシェーダが組み込まれた Material です。

ここで、私はこれらの Cubemap skybox や SkyMaterial を簡単に表示・比較するための playground を作りました。実際にクリックして訪れてみてください!

https://twitter.com/akai_inu/status/1520732167940104193

詳しい実装はわかりませんが、パラメータをスライダーでいじることで、太陽の位置を動かしたり、ミー散乱やレイリー散乱のパラメータを調節して青の度合いを変更したりすることが可能です。非常に綺麗な空を作れますのでオススメです。うまくロジックを書けば、昼夜の表現もできます。

Discussion