ドラッグでカメラ動かせます。
マウスカーソルをロボにホバーすると、近い点や辺にスナップします。
(スマホやタブレットではできません。)
今日は初めてのWebGL 2 第2版 ―JavaScriptで開発するリアルタイム3Dアプリケーションを読み終わりました。
学習の整理のためにピッキング・スナッピングについてまとめました。
間違いなどあればご指摘いただけると大変うれしいです。
ピッキングについて
ピッキングとは、スクリーン座標値から、3D空間で対応するオブジェクトと位置を特定すること。主にマウスカーソルが当たっているオブジェクトと位置を特定する用途で使う。
ピッキングの手法は以下の2つに大別できる。
- ラスタイズ結果(GPUの描画結果)を利用する方法
- 幾何計算によって交差判定を行う方法
ラスタイズ結果(GPUの描画結果)を利用する方法
カラーピッキング
まず、各オブジェクトに一意のIDをRGB値として割り当てる。描画に使うフレームバッファとは別に、ピッキング用のフレームバッファにIDをレンダリングして、マウス位置の1ピクセルを読むことでオブジェクトの特定を行う。
利点は画面上で見えている結果とピッキングの結果が全く同じになること。 欠点は、1回のカラーピッキングでは最前面のオブジェクトしか取れないということと、オブジェクトのIDしか取れず、そのオブジェクトのどの部分かという詳細な位置情報が取れないこと。
深度バッファピッキング
深度バッファのマウス位置の1ピクセルを読み、カーソルが指す3D空間上の位置を計算する手法。
深度バッファの性質上、カメラから遠くなるほど精度が落ちる。
やはり最前面しか取れない。
幾何計算によって交差判定を行う方法
レイピッキング
マウス位置からカメラ方向と逆にレイを飛ばして、幾何的に交差するオブジェクトを調べる方法。
利点は最初に当たったオブジェクト以外も取れること、オブジェクトのどの部分かという位置情報も取れること。
描画結果とは独立して計算される。
各WebGLライブラリが採用している手法
| ライブラリ | 手法 | 実装場所 |
|---|---|---|
| Three.js | レイピッキング | Raycaster.js |
| Babylon.js | レイピッキング | scene.ts |
| CesiumJS | カラーピッキング + 深度バッファピッキング | Picking.js |
CesiumJSのピッキング
- CesiumJSはカラーピッキングを採用しているが、drillPick(奥のオブジェクトも含めて複数ピッキング)を提供している。どうやっているのか?
- 一度ピックして、最前面のオブジェクトを隠し、再度ピックを繰り返している。
- ここで実装されている。
スナッピングとは
スナッピングとはマウスカーソルをどこに吸着させるかを決めること。
ピッキングで候補を取得して、点・線・面を評価して最も条件にあう位置へ吸着させる。
所感
技術について発信してくださる人への尊敬と感謝が深まりました。