2011-07-31 31 views
2

我正在寫一個飛行模擬器,並陷入了這個流派的經典問題:視錐體的近平面必須足夠近以使飛機駕駛艙可見,遠平面必須遠離以啓用可見距離長達40公里。如何擺脫OpenGL中的z戰鬥問題?

能見度距離或近/遠比例的確超出了opengl的z緩衝精度能力,而遠處的物體閃爍劇烈。這是一個花哨的3D引擎讓你獨自解決問題的地方,你需要真正的opengl知識:)。也許我找到了解決問題的正確方法(如果我錯了,OpenGL專家會糾正我),但是我的解決方案忽略了重要的一點。改變渲染器進行雙通道渲染:

    在第一遍遠處的物體
  1. 和背景必須顯示,近平面搬走,Z緩衝是幸福的,地形看起來不錯,但近對象剪裁掉。
  2. 在第二階段中,投影矩陣會針對近距離物體進行調整,並應顯示駕駛艙。

的未解決的問題:在第二遍所有遠處的物體和背景是不可見的,因此我有駕駛艙和它後面的黑色背景。第二輪的結果完全浪費了第一輪的結果。埃爾戈計劃重疊不會發生。問題: 如何強制opengl在第二遍中忽略背景顏色,這樣兩個通過結果都會創建所需的疊加?

P.S.這是現狀的圖像(近/遠飛機處於極端狀態,使所有細節都可見,單程無投影調整)。

http://www.flickr.com/photos/[email protected]/5995604542/sizes/l/in/photostream/

的緩衝器清除每渲染週期和只發生一次,而不是所涉及的2遍之間。這裏,清除碼:

JoglContext jctx = (JoglContext) ctx; 
GLContext context = context(ctx); 
GL gl = context.getGL(); 
// Mask of which buffers to clear, this always includes color & depth 
int clearMask = GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT; 
gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT); 
gl.glDepthMask(true); 
gl.glClearColor(r, g, b, jctx.getAlphaClearValue()); 
gl.glClear(clearMask); 
gl.glPopAttrib(); 

您所描述的方法也用在2次:1。「長途」投影和地形2「短距離」和駕駛艙之間沒有信息交換,但是第二後傳遞駕駛艙後面的背景是黑色的。也許glDepthRange功能幫助,必須檢查手冊。

zbuffer深度是24位。

回答

6

不要清除兩遍之間的屏幕。如果您只想清除深度緩衝區,則清除只需深度緩衝區。不要通過GL_COLOR_BUFFER_BITglClear

在任何情況下,更好的方法來做到這一點(這樣你就不必重新渲染所有東西)就是採用適當的深度範圍。由於您的駕駛艙無法與場景相交,因此沒有理由將其繪製到場景的深度範圍內。因此,首先,使用一個合理的透視矩陣(即:一個具有相當大的z-near,幾英尺左右的數量級)繪製場景。你的場景不包括你的駕駛艙。該渲染的glDepthRange應該是類似於[0.05,1.0]的東西。

之後,你繪製你的駕駛艙,使用合理的透視矩陣只是駕駛艙。 glDepthRange這是[0,0.05]。這應該會爲您提供場景和駕駛艙的深度精度。

哦,並確保你得到一個24位深度緩衝區。

+0

感謝您的及時響應,Nicol。我的評論過於冗長,不得不粘貼到原文中。請仔細看看glDepthRange。 – Paul

2

駕駛艙與外部是模板緩衝區的經典案例,很像HUD與場景。模板的優點是您根本不需要z,因此您可以將近平面設置得更遠。另外,你所看到的Windows不會改變(除非你在駕駛艙內旋轉你的虛擬頭部),所以這是一次畫一次重用 - 很多事情。

另外,logarithmic z可能是一個有趣的讀取你。

+0

謝謝達蒙,聽起來非常有用!如何應用模板緩衝區/ sb函數,然後提供OpenGL初學者的一些提示? – Paul

+0

模板有點令人困惑,因爲它不是很明顯,你需要做什麼,至少這是我第一次看到它。有很多選擇。主要功能[glStencilFunc](http://www.opengl.org/sdk/docs/man3/xhtml/glStencilFunc.xml)和[glStencilOp](http://www.opengl.org/sdk/docs/man3/ XHTML/glStencilOp.xml)。你使用'glStencilFunc'來做實際的測試(即丟棄陰影部分),'glStencilOP' _first_來真正地定義模板緩衝區中的內容。 – Damon

+0

您可能希望使用GL_REPLACE模板操作,使用盡可能便宜的着色器(禁用光照/紋理!),然後使用GL_EQUAL模板函數。如果您在繪製駕駛艙時使用z緩衝,則深度失敗的GL_KEEP也可能是一個選項(可能會節省一些帶寬)。 – Damon