2008-10-08 91 views
1

我需要從紋理中獲取特定座標的顏色。有兩種方法可以做到這一點,通過獲取並查看原始png數據,或者通過對我生成的opengl紋理進行採樣。是否有可能在一個給定的UV或XY座標上採樣opengl紋理來獲取顏色(RGBA)?如果是這樣,怎麼樣?Open GL中的紋理採樣

回答

2

關閉我的頭頂,你的選擇是

  1. 取使用glGetTexImage(整個紋理),並檢查你感興趣的紋理像素
  2. 平局。您感興趣的紋理元素(例如,通過渲染GL_POINTS基元),然後使用glReadPixels獲取從幀緩衝區渲染它的像素。
  3. 方便地保留紋理圖像的副本,並將OpenGL保留在其外面。

選項1和2的效率非常低(儘管通過使用像素緩衝區對象並異步執行副本,速度可能會有所提高)。所以我最喜歡的是FAR選項3

編輯:如果有GL_APPLE_client_storage擴展名(即您是Mac或iPhone上。)那麼這就是選擇4這是一個很長的路要走贏家。

+0

外保持PixelData取出方便(浪費內存雖然)

  • 做它的副本,你需要一個基於texcoords的抽樣方法,但這是一個很難的部分 - 這在我的答案中有所描述。 – 2008-10-08 08:39:06

  • 2

    我發現最有效的方法是訪問紋理數據(您應該將我們的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 
    } 
    
    0

    正如其他人所建議的,從VRAM回讀紋理效率非常低,如果您甚至對性能感興趣,應該像瘟疫一樣避免。據

    兩個可行的解決方案,因爲我知道:

    1. 使用着色器選項2的