Babylon.js:日食/ダイヤモンドリング
この記事のスナップショット

ダイヤモンドリング
(上記のURLにおいて、ツールバーの歯車マークから「EDITOR」のチェックを外せばウィンドウいっぱいに、歯車マークから「FULLSCREEN」を選べば画面いっぱいになります。)
ソース
ローカルで動かす場合、上記ソースに加え、別途 git 内の 104/js を ./js として配置してください。
概要
Volumetric Light Scattering Post Process にある サンプル Basic Example を改修して日食を再現しました。更にダイヤモンドリングになるよう、光源を追加してみたり、レンズフレアを追加してみました。
やったこと
- 日食をつくる
- 光源を追加してダイヤモンドリングをつくる
- レンズフレアでダイヤモンドリングをつくる
- ブラッシュアップ
日食をつくる
サンプル Basic Example のドクロを球に置き換えれば、簡単に日食が再現できます。
Ver.1.0
マウス操作で回転させたり、ズームイン/ズームアウトしていると、金環日食のときにダイヤモンドリングっぽくならないことに気が付きます。
babylon.js 的には精一杯表現しているのかもしれませんが、物足りないので次に示す細工を施します。
光源を追加してダイヤモンドリングをつくる
「光が足りないなら足せばいいじゃないか」という発想で光源を追加します。
追加するといっても、配置した位置によっては影?をつくってしまうので奥に配置します。

第二光源を適当に配置して影ができている様子
Ver.2.0
試作品を動かしてみると、(月-太陽-カメラ)の角度が大きくなった時に、余計な主張をしていることがわかります。光源をそのまま配置しているので仕方ないのですが目ざわりです。

第二光源の余計な主張
そこで(月-太陽-カメラ)の角度/内積および(月-第二光源-カメラ)の角度/内積を確認して、所定の範囲内に角度が収まっていれば第二光源を表示、外れていれば表示しないようにします。光源を表示しない方法として dispose以外に見当たらなかったので、太陽と座標を重ねることで隠すようにします。
Ver.2.1
即席の対応で完ぺきではないですが、まぁまぁの出来と思います。

完璧でない例(日食のリングと光源がずれているケース)
レンズフレアでダイヤモンドリングをつくる
レンズフレア Lens Flares で同様にダイヤモンドリングを作れないか試してみます。リング状のダイヤ(宝石)にあたる部分を表現したいので、レンズフレアは大きく1つのみにします。
Ver.3.0

理想的なレンズフレアの位置
試作品を動かしてみると、期待していないとき(太陽が隠れているときなど)にレンズフレアが表示されていることがわかります。

期待していないレンズフレアの表示(内側に)

期待していないレンズフレアの表示(外側に)
なので、ここでも(月-太陽-カメラ)の角度/内積を確認して、範囲内ならレンズフレアを表示、範囲外ならレンズフレアを非表示(サイズを0)にします。
Ver.3.1
ブラッシュアップ
最後の仕上げとして、月もどきの球に「月」のテクスチャを張ります。適当にテクスチャを張り付けているので、月の裏側が見えているかもしれません。
また、skyboxを宇宙っぽくします。ただし、日食と背景がけんかしないよう、暗めの宇宙 CubeTexturesにある space を使います。

金環日食時(背景が黒に)

カメラを回転させて月が見える様子(2倍速)
まとめ・雑感
理科の教材(小学校高学年向け?)に使えそうなものがお手軽にできました。
ダイヤモンドリングになるよう、光源を配置したり、レンズフレアを使ってみたりしました。「光源」による方法は位置が固定なうえ、想定しない挙動(思ったタイミングで光源が表示されてしまう)があります。その点、「レンズフレア」の方法はダイヤの部分を任意に発生させられる上に、コードが簡素になる分、こちらがよいかもです。
太陽といえば、こちら ParticleSystemSet にある Particle Sun Demo を連想する人もいるかもしれません。こちらを使って「太陽のみを隠してプロミネンスのみを観測」といったことを期待しても、なぜか常に最前面に太陽が表示されるため、他のメッシュで隠すということができません。以前、Babylon.js で物理演算(havok):SpringConstraintで太陽系でこの太陽を使ったデモ重力あり・平板あり(木星まで、彗星あり)で、他の惑星よりも前面に表示されてて困った覚えがあります。出来が良いだけでに他に活用しづらいのは残念です。
最後に1つだけ。
まちがっても、太陽は直視しないでください。危険です。
Discussion