テクスチャから特定の座標の色を取得する必要があります。生のpngデータを取得して見るか、生成されたopenglテクスチャをサンプリングするという2つの方法があります。特定の UV または XY 座標で色 (RGBA) を取得するために、opengl テクスチャをサンプリングすることは可能ですか? もしそうなら、どのように?
3 に答える
私の頭の上から、あなたのオプションは
- glGetTexImage()を使用してテクスチャ全体をフェッチし、関心のあるテクセルを確認します。
- 関心のあるテクセルを描画し(たとえば、GL_POINTSプリミティブをレンダリングすることにより)、glReadPixelsを使用してフレームバッファーからレンダリングしたピクセルを取得します。
- テクスチャ画像のコピーを手元に置いておき、OpenGLを除外します。
オプション1と2は、ひどく非効率的です(ただし、pixel-buffer-objectsを使用し、非同期でコピーを実行することで、2をいくらか高速化できます)。ですから、FARで私のお気に入りはオプション3です。
編集:あなたがGL_APPLE_client_storage
拡張機能を持っている場合(つまり、あなたがMacまたはiPhoneを使用している場合)、それは長い道のりで勝者であるオプション4です。
私が見つけた最も効率的な方法は、テクスチャ データにアクセスし (PNG をデコードしてテクスチャにする必要があります)、自分でテクセル間を補間することです。texcoords が [0,1] であると仮定すると、texwidth u と texheight v を乗算し、それを使用してテクスチャ上の位置を見つけます。それらが整数の場合は、ピクセルを直接使用するだけです。それ以外の場合は、int 部分を使用して境界ピクセルを見つけ、小数部分に基づいてそれらの間を補間します。
HLSL に似た疑似コードを次に示します。かなり明確なはずです:
float3 sample(float2 coord, texture tex) {
float x = tex.w * coord.x; // Get X coord in texture
int ix = (int) x; // Get X coord as whole number
float y = tex.h * coord.y;
int iy = (int) y;
float3 x1 = getTexel(ix, iy); // Get top-left pixel
float3 x2 = getTexel(ix+1, iy); // Get top-right pixel
float3 y1 = getTexel(ix, iy+1); // Get bottom-left pixel
float3 y2 = getTexel(ix+1, iy+1); // Get bottom-right pixel
float3 top = interpolate(x1, x2, frac(x)); // Interpolate between top two pixels based on the fractional part of the X coord
float3 bottom = interpolate(y1, y2, frac(x)); // Interpolate between bottom two pixels
return interpolate(top, bottom, frac(y)); // Interpolate between top and bottom based on fractional Y coord
}
他の人が示唆しているように、VRAM からテクスチャを読み戻すことは非常に非効率的であり、パフォーマンスに少しでも関心がある場合でも、疫病のように避ける必要があります。
私が知る限り、実行可能な2つの解決策:
- ピクセルデータのコピーを手元に置いておきます(ただし、メモリを浪費します)
- シェーダーを使って行う