2013-03-31 80 views
10

我在OpenGL ES中繪製行星,並遇到一些有趣的性能問題。一般問題是:如何最好地在一個球體上渲染「非常詳細」的紋理?在OpenGL ES中繪製非常高分辨率的紋理對象(球體)

(球體保證;我感興趣的特定領域的優化)

基例:

  • 窗口是約。 2048×1536(例如iPad3的)
  • 紋理地圖爲地球是24000 X 12000像素(美國的一半大小適合屏幕的整個寬度的區域)
  • 環球在一切顯示從放大(USA填滿屏幕) (全球可見)
  • 我需要最少3個紋理圖層(1個用於行星表面,1個用於晝夜差異,1個用於用戶界面(高亮不同區域)
  • 某些圖層是動畫的(即它們必須在運行時迅速加載和放下紋理)

Limitati附件:

  • 高端片劑被限制爲4096×4096的紋理
  • 高端片劑被限制爲8個同步紋理單元

問題:

  • 總共,這是天真地500萬像素的紋理數據
  • 拆分成較小的紋理效果不佳,因爲設備只有8個單元;只有一個紋理圖層,我可以分成8個紋理單元,並且所有紋理都小於4096x4096 - 但僅允許單個圖層將圖層渲染爲單獨的幾何圖形效果不佳,因爲它們需要使用基於片段的圖元進行混合,着色器

......此刻,唯一的想法,我有一個聽起來可行的是:

  1. 分裂球成N×M的「球塊」和渲染每一個作爲獨立的幾何
  2. 縮小時使用mipmap來渲染低分辨率紋理
  3. ...依靠簡單剔除削減了大部分放大時,並mipmap以使用小型(ER)的紋理時,他們不能被剔除

...但它似乎應該有成爲更簡單的方式/更好的選擇?

+0

將在這裏使用球體騙子的幫助:http://stackoverflow.com/questions/10488086/drawing-a-sphere-in-opengl-es/10506172#10506172?這極大地簡化了幾何圖形,但是需要片段着色器中的查找功能將方形紋理映射到球面。它還提供了在所有縮放比例下都非常平滑的內容。 –

+0

這不是指扔掉所有的OpenGL和編寫軟件光線跟蹤庫嗎?你說「一個球體從各個角度看起來都差不多」,但實際上它看起來與每個角度都有獨特的不同 - 這是紋理貼圖! – Adam

+1

從任何方向看,無紋理的球看起來都是相同的,這就是讓你擺脫幾何形狀並計算一組每像素法線,高度等的方法。對於紋理來說,球體在給定幀中的旋轉與像素位置可以被饋送到片段着色器中的每像素紋理映射函數中。你會注意到,我的答案中的所有上述內容都是在OpenGL ES中完成的,所以除了幾何圖形生成外,你什麼也不扔掉。我之前用這種方式做了這個紋理化的工作,它運行良好。 –

回答

0

似乎沒有辦法在移動GPU的內存中嵌入如此巨大的紋理,即使是iPad 3也是如此。

所以你必須流紋理數據。你需要的東西叫clipmap(通過擴展megatexture技術的id軟件推廣)。

請閱讀有關此這裏,有鏈接的文檔描述的技術:http://en.wikipedia.org/wiki/Clipmap

+0

這聽起來像是一種錯誤的技術,因爲它會涉及更多的努力並且性能比我之前描述的要低。如果我錯過了某些東西,請解釋它如何起作用。 – Adam

+0

另請:請重新閱讀我的問題。問題不是「不能將巨大的紋理放入記憶中」。我們*可以*將巨大的紋理放入記憶中 - 我已經完成了這個工作並且它可以工作。 – Adam

0

這不是在ES容易做到,因爲沒有虛擬紋理擴展(還)。您基本上需要實現虛擬紋理(一些ES設備實現ARB_texture_array)並以可能的最低分辨率(取決於視圖)爲您的球體進行流式處理。這樣,就可以在片段着色器中完成所有操作,不需要幾何細分。有關詳情如何實施,請參閱this presentation(和論文)。

如果你做數學題,這是根本不可能實時數據流1 GB(24,000 X 12000像素×4 B)。而且這也是浪費,因爲用戶永遠不會同時看到這一切。