7

私の知る限り、OpenGL ES 2.0ではZ(深さ)値を読み取ることはできません。では、2D画面上のポイントから3Dワールド座標を取得するにはどうすればよいのでしょうか。

実際、私はいくつかのランダムな考えがうまくいくかもしれないと思っています。glReadPixelsを使用してRGBA値を読み取ることができるので、深度バッファーを複製してカラーバッファー(たとえばColorforDepth)に格納するのはどうでしょうか。もちろん、デプスバッファの情報が失われないように、適切な規則が必要です。そして、ポイントのワールド座標が必要な場合は、このColorforDepthカラーバッファをフレームバッファにアタッチしてからレンダリングします。したがって、glReadPixelsを使用して、このフレームの深度情報を読み取る場合。

ただし、カラーバッファはデプスバッファから変換された奇妙なバッファであるため、これにより1フレームのフラッシュが発生します。OpenGL es 2.0で深さを取得するための標準的な方法があるかどうかまだ疑問に思っていますか?

事前にThx!:)

4

3 に答える 3

9

FBOを使用すると、結果を表示せずにレンダリングできます。ES 2.0を使用している場合、フラグメントシェーダーはgl_FragCoordの一部として現在のフラグメントの深さ(ウィンドウ座標)にアクセスできるため、それをカラーバッファーに書き込み、glReadPixelsを使用して結果を取得して続行できます。または、ワールドスペースzを可変としてロードし、フラグメントシェーダーから書き込むこともできます。これは、より簡単な方法です。

自分を納得させるには、gl_FragCoord.zを低精度で急いで出力するクイックシェーダーを作成してみてください。

gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0);

深さを表す色の強度でグレースケールを取得する必要があります。ウィンドウ座標を使用しているため、強度は0.0(可能な限り最も近いクリップされていないフラグメント)から1.0(可能な限り最も遠いクリップされていないフラグメント)の範囲になります。ベンダーはほぼ確実に浮動小数点ターゲットバッファをサポートしていないため、かなりの精度を失わないようにするには、コンポーネント間で値を分割する方がおそらくより役立ちます。

于 2011-05-26T14:59:20.800 に答える
0

スクリーンタッチから3Dオブジェクトを選択するには、基本的なレイキャスティングを使用します。実際、タッチポイントでの画面法線とオブジェクトを含む球との交点を計算します。非常に正確なピッキングや複雑な形状の場合は、いくつかの球を使用する必要があります。

また、オブジェクトのいくつかの重要なポイントを画面の2D空間に投影し(3Dポイントに変換行列を掛ける)、タッチポイントとの2D比較(距離)を行うこともできます。

于 2010-04-12T20:18:41.930 に答える
0

デプスバッファの値も読み取れるようにしたいのですが、調査によるとそれはできません。

vincentが示唆しているように、球のような単純な形状の場合は、レイキャスティングの方がおそらく優れています。

より複雑な形状の場合、オブジェクトを(潜在的に小さい)オフスクリーンバッファにレンダリングし、各頂点の色成分の1つをその頂点の深さに手動で割り当ててから、色の値を読み取ることを考えています。これはややエレガントで面倒なことであり、オブジェクト空間を画面空間に変換できる必要があります(私は自分のクォータニオンを使用して行列を駆動しているので、それで対処できます)。シェーダーを使用して、深度情報をカラーまたはステンシルバッファーに書き込む方法がある場合があります(GL ESにはステンシルバッファーもありますか?)

誰かがよりクリーンなアプローチを持っているなら、私はそれを聞きたいです。

于 2010-10-31T21:55:13.393 に答える