WebGL API を使用して、独自のレイキャスティングを実行する以外に、深度バッファーから値を取得したり、画面座標から 3D 座標を特定したり (つまり、クリックされた場所を見つける) するにはどうすればよいですか?
5 に答える
数年が経ち、最近ではWEBGL_depth_texture
拡張機能が広く利用可能になっています...IEをサポートする必要がない限り。
一般的な使用法:
準備:
- 拡張機能のクエリ (必須)
- 別の色と深度のテクスチャを割り当てる (
gl.DEPTH_COMPONENT
) - 両方のテクスチャを 1 つのフレーム バッファに結合します (
gl.COLOR_ATTACHMENT0
、gl.DEPTH_ATTACHMENT
)
レンダリング:
- フレームバッファをバインドし、シーンをレンダリングします (通常は簡略化されたバージョン)
フレームバッファのバインドを解除し、深度テクスチャをシェーダに渡し、他のテクスチャと同じように読み取ります。
texPos.xyz = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5; float depthFromZBuffer = texture2D(uTexDepthBuffer, texPos.xy).x;
WebGL 仕様のセクション5.13.12から、デプス バッファを直接読み取ることができないようです。そのため、FBO が必ずしも必要ではないかもしれませんが、おそらく Markus の提案が最適な方法です。
しかし、ピッキングのようなことをしたい場合は、他の方法があります。非常に頻繁に尋ねられているので、SOを参照してください。
2012年1月23日の時点で、深度バッファーの読み取りを有効にするドラフトWebGL拡張機能WEBGL_depth_textureがあります。実装での可用性についての情報はありませんが、この早い時期には期待していません。
実際には重複していませんが、以下も参照してください:マウス クリック座標から WebGL 3d 空間でオブジェクトを取得する方法
レイの投影を解除してキャストする (そして、必要に応じてそれに対して交差テストを実行する) 以外に、最善の策は「ピッキング」を確認することです。これは正確な 3D 座標を提供しませんが、どのオブジェクトがクリックされたかのみを気にし、ピクセル単位の精度を実際に必要としない場合、非投影の代わりに役立ちます。
WebGL でのピッキングとは、特定のシェーダーを使用してシーン全体 (または少なくとも関心のあるオブジェクト) をレンダリングすることを意味します。シェーダーは、青のチャンネルをキーとして使用して、赤と緑のチャンネルにエンコードされた異なる一意の ID で各オブジェクトをレンダリングします (青以外は対象のオブジェクトがないことを意味します)。シーンは、エンド ユーザーには見えないように、オフスクリーンのフレーム バッファーにレンダリングされます。次に、gl.readPixels() を使用して対象のピクセルを読み取り、指定された位置でエンコードされたオブジェクト ID を確認します。
それが役立つ場合は、WebGL ピッキングの私自身の実装を参照してください。この実装は、ピクセルの長方形領域を選択します。1x1 領域を渡すと、単一のピクセルが選択されます。146 行目、162 行目、175 行目の関数も参照してください。