OpenGLは2.0読み取り深度バッファをES
-
25-09-2019 - |
質問
私の知る限りでは、我々は、OpenGL ES 2.0のZ(深さ)の値を読み取ることができません。 だから私たちは、2D画面上の点から3Dの世界座標を取得することができますどのように疑問に思って?
実際に私が持っているいくつかのランダムな思考が働くかもしれません。我々は深度バッファを複製し、カラーバッファに格納する方法については、glReadPixelsを使用してRGBA値を読み取ることができるので、(ColorforDepthを言います)。もちろん、我々はデプスバッファのいずれかの情報を失わないように、いくつかの素晴らしい大会があるようにする必要があります。そして、我々はポイントのワールド座標を必要とするときに、我々はフレームバッファにこのColorforDepthカラーバッファを添付し、それをレンダリングします。だから我々は、このフレームの奥行き情報を読み取るためにglReadPixelsを使用する場合。
colorbufferはデプスバッファから翻訳された奇妙なバッファであるため、しかし、これは1つのフレームフラッシュにつながります。 OpenGLは2.0をESで深さを得るためにいくつかの標準的な方法があれば、私はまだ疑問に思って?
事前にThxを!)
解決
FBOを使用して、結果を表示せずにレンダリングすることができます。あなたはES 2.0にしている場合は、カラーバッファに、使用glReadPixelsが結果を取り戻すと、続行することを書くことができますので、あなたのフラグメントシェーダは、gl_FragCoordの一部として(ウィンドウ座標で)現在のフラグメントの深さにアクセスすることができます。また、あなたは周りの簡単な方法だ場合には、そのあなたのフラグメントシェーダで変化し、書き込みとして世界的に空間zを読み込むことができます。
プットが低精度で急いで出てgl_FragCoord.zという迅速なシェーダを書いてみてください、自分を納得させるために、例えばただ
gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0);
あなたは深さを表す色の強さとグレースケールを取得する必要があります。あなたはウィンドウ座標にしているので、強度が0.0(最も近いクリップされていないフラグメント)から1.0(最も遠い可能クリップされていないフラグメント)の範囲であろう。あなたのベンダーがほぼ確実浮動小数点ターゲットバッファをサポートしていないとして、精度のかなり多くを失わないようにするために、それは、コンポーネント間の値を分割するためにおそらくより便利です。
他のヒント
私は、画面タッチから3Dオブジェクトを選ぶための基本的なレイキャスティングを使用します。実際に私はタッチポイントで通常画面と私のオブジェクトを含む球の交点を計算します。非常に正確なピッキングや複雑な形状のためには、いくつかの球を使用する必要があります。
また、あなたのいくつかの重要なポイントは、あなたの2次元空間内のオブジェクトに投影することができる(私はあなたの変換行列によって、あなたの3D点を乗算)をスクリーニングして、あなたがポイントに触れています。
で、いくつかの2D比較(距離)を作りますは私も同様に、深度バッファ内の値を読み取ることができるようになります しかし、研究は、それが実行することはできませんを示している。
ヴィンセントとしては球のような単純な形状を持っている場合は、レイキャスティングは、おそらく優れている、提案します。
カントーより複雑な形状のため、 私は、オフスクリーンバッファ(潜在的に小さい)にオブジェクトをレンダリングすると思っています 手動でその頂点の深さであると、各頂点の色成分のいずれかを割り当てます その後、色の値を読み取ります。これは、やや洗練と迷惑カントーで、(私は行列を駆動するために自分の四元数を使っていますので、それの世話をすること)画面スペースにオブジェクト空間を変換できるようにする必要があります。色またはステンシルバッファに深度情報書き込むシェーダと方法があるかもしれない(GL ESにもステンシルバッファを持っていないか?)
誰もがクリーンなアプローチを持っている場合は、私はそれを聞いてみたい。