2017-06-13 68 views
1

如果所有頂點都保留在透視投影中的屏幕上,我會看到一個問題,即我可以正確繪製紋理多邊形,但是如果我縮放足夠大的四邊形以致多一個頂點落在「觀察體積太遠」後面,導致OpenGL繪圖不正確(請參閱截圖)。紋理映射變得歪斜,看起來好像離屏頂點「移動」並變得扭曲。我在符合GLES 3.0的驅動程序上使用GLES 2.0代碼(詳細信息在底部)。我現在將更詳細地解釋我的測試 -OpenGL透視投影裁剪多邊形與頂點外部Frustum =錯誤的紋理映射?

我正在繪製一個由兩個簡單多邊形組成的GL_TRIANGLE_STRIP'方形',並在四邊形上應用了簡單的紋理貼圖(紋理貼圖僅在四邊形上完全貼圖,沒有UV302座標0-> 1如你所期望的那樣映射

另外,我使用GLM函數爲我提供了矩陣轉換的助手,隨後使用glm :: PerspectiveFov()來設置查看體積(平截頭體),結果是相機看起來略微向四邊形方向延伸,從而形成一個「地面」,其表面上帶有格子圖案的紋理圖案

correctly drawn view of quad screenshot

從這裏,如果我進一步增加四邊形上的比例因子,或者旋轉相機以使屏幕角頂點離觀看區域更遠,我會看到突然出現的極度奇怪的行爲,紋理映射的變化,或者多邊形的一個頂點錯誤移動。在這裏看到:

polygon texture mapping becomes wrong

對於我使用GLM相機旋轉::的lookAt() - 有效地我動「眼」位置,同時在現場維持目標在0,0(中心多邊形)。

另請注意,當我越過這個閾值時,我看到我繪製的紅色調試線連接所有頂點突然將其方向從它應該在的位置移開。

有誰知道這個問題是怎麼產生的?有沒有辦法解決它,所以我可以繪製一個巨大的四邊形,並且沒有這些問題/工件的頂點離屏?謝謝!!!

GPU信息:

GL廠商:芯公司

GL渲染:Vivante的GC2000

GL版本:OpenGL ES的3.0 V5.0.11.p8.41671

GLSL版本:OpenGL的ES GLSL ES 3.00

+0

冒着聽起來沒有幫助的風險:不要畫出一個巨大的四邊形。分開來。 – Rook

+0

聽起來像是我的驅動程序錯誤。特別是因爲你正在處理一個不知道OpenGL實現質量最高的移動GPU。您是否曾嘗試在另一個供應商的GPU上運行您的代碼? – PeterT

+0

我看起來像Vivante部分未能糾正三角形深度投影的頂點插值,所以您得到的是平面插值而不是透視校正的插值。不太可能有很多你在這裏做錯了... – solidpixel

回答

0

對我原來的問題的一些研究和評論讓我相信觀察到的效果是ab ug在Vivante GPU GC2000上的OpenGL驅動程序實現中。顯然,這些錯誤在嵌入式GPU硬件驅動程序中很常見 - 由於這種ES實現的源代碼永遠不可用,這個問題更加惡化。

要通過解決方法解決這個問題,我可以採用原始方形的尺寸,而是創建一個網格紋理方塊數組,以便所有多邊形最終都小到足以「適合」足夠接近觀察角度區域(或者可以完全剪切,避免錯誤行爲)。在C++中的代碼:

// measurements we will add as we move along the grid 
float tile_size = 1.0/num_grid_subdivisions; // square width 1 
float tile_uv_dist = 1.0/num_grid_subdivisions; // assume 0->1 texture mapping 
XY curr_bl = XY(-0.5, -0.5); // quad from -0.5 to 0.5 in x and y (1x1) 
float cu = 0; //current texture coordinates in x dimension 
float cv = 0; //current texture coordinates in y dimension 
for (int row = 0; row < num_grid_subdivisions; ++row) 
{ 
     for (int row_item = 0; row_item < num_grid_subdivisions; ++row_item) 
     { 
      // GL_TRIANGLES to keep simple, but could use STRIP later 
      VertXYUV bl(curr_bl, cu, cv); // bottomleft 
      // if we know bottomleft, we know the rest of the points of the square 
      VertXYUV tl(XY(curr_bl.x, curr_bl.y + tile_size), cu, cv + tile_uv_dist); 
      VertXYUV br(XY(curr_bl.x + tile_size, curr_bl.y), cu+ tile_uv_dist, cv); 
      VertXYUV tr(XY(curr_bl.x + tile_size, curr_bl.y + tile_size), 
      cu + tile_uv_dist, cv + tile_uv_dist); 
      // our square tile is two triangle polygons 
      AddVert(bl); AddVert(tl); AddVert(br); // triangle 1 
      AddVert(br); AddVert(tl); AddVert(tr); // triangle 2 

      // current info should always be tracking 'bl' of current tile 
      // increment row item, moving across to the right (+x) 
      cu += tile_uv_dist; 
      curr_bl.x += tile_size; 
     } 

     // current info should always be tracking 'bl' of current tile 
     // incrementing row, moving up (+y) 
     cv += tile_uv_dist; 
     cu = 0; // reset x space texture coordinate back to left side (0) 
     curr_bl.y += tile_size; 
     curr_bl.x = grid_bl.x; 
}