2014-08-30 87 views
2

我在Java中使用LWJGL和GLSL着色器渲染Master Cheif時出現了一些問題,其中有些閃爍,消失了多邊形和奇怪的着色。而對於我的生活,我無法弄清楚爲什麼。OpenGL - Java - 渲染問題,多邊形閃爍和消失

它應該是什麼樣子: enter image description here

它是什麼樣子,當我移動相機一點: enter image description here

着色器: https://github.com/marko5049/LucidEngine/tree/master/src/res/shaders

MainShaders: LightingMain ShdaowMapping Smapler 篩選器

所有代碼: https://github.com/marko5049/LucidEngine

靜態網格​​:

public void addVertices(Vertex[] vertices, int[] indices, boolean calcNorm) { 
    if(calcNorm) { 
     vertices = calcNormals(vertices, indices); 
    } 

    handler.setSize(indices.length); 
    EngineCore.polycount += indices.length/3; 

    glBindBuffer(GL_ARRAY_BUFFER, handler.getVbo()); 
    glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_STATIC_DRAW); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handler.getIbo()); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, Util.createFlippedBuffer(indices), GL_STATIC_DRAW); 
} 

private void finalDraw(int typeIndex) { 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glEnableVertexAttribArray(2); 
    glEnableVertexAttribArray(3); 

    glBindBuffer(GL_ARRAY_BUFFER, handler.getVbo()); 
    glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0); 
    glVertexAttribPointer(1, 2, GL_FLOAT, false, Vertex.SIZE * 4, 12); 
    glVertexAttribPointer(2, 3, GL_FLOAT, false, Vertex.SIZE * 4, 20); 
    glVertexAttribPointer(3, 3, GL_FLOAT, false, Vertex.SIZE * 4, 32); 
    glVertexAttribPointer(3, 3, GL_FLOAT, false, Vertex.SIZE * 4, 44); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handler.getIbo()); 
    glDrawElements(typeIndex, handler.getSize(), GL_UNSIGNED_INT, 0); 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
    glDisableVertexAttribArray(2); 
    glDisableVertexAttribArray(3); 
} 
+0

從外觀上看,它看起來可能是深度戰鬥。你可以嘗試將近平面遠離,還是遠平面靠近? RenderingEngine.java中的第54行。例如,嘗試1.0和100.0而不是0.1和1000.0。 – 2014-08-30 14:06:06

+0

@ReetoKoradi Totaly修復它非常感謝! – marko5049 2014-08-31 02:25:01

回答

3

你描述的,在你的樣品圖像顯示是一個問題的典型症狀通常被稱爲「深度戰鬥」或「z-fighting」 。這是由深度緩衝區的精度限制造成的。

如果深度緩衝區覆蓋的範圍很大,並且場景包含深度值非常相似的多邊形,則這成爲問題的最常見情形是。

例如,在世界空間中多邊形B的前面略微畫一個多邊形A.在應用了所有變換後,多邊形A和多邊形B中的像素可以以相同的深度值結束,並將結果深度舍入到可用的深度緩衝區精度。根據繪圖的順序,在這種情況下,可以看到多邊形A或多邊形B的像素。典型的結果是由多邊形A和多邊形B像素的組合將現身其中多邊形A應覆蓋面B.

有許多的方式來解決這個問題:

  • 減少深度範圍。在標準透視投影中,這由近平面和遠平面距離控制,其中相對遠/近值是臨界量。哪些值導致深度戰鬥嚴重取決於場景和深度緩衝精度。最安全的選擇是儘可能保持相對的價值。在大多數情況下,高達約100的值往往很少會導致問題,並且1000和更高的值可能導致問題。
  • 增加深度緩衝精度。最常見的深度緩衝區大小是16位和24位,許多GPU都支持這兩種。如果事情有問題,至少選擇24位。根據硬件和OpenGL版本的不同,可能會提供更高分辨率的深度緩衝區。
  • 避免渲染具有幾乎相同深度的多邊形。要麼刪除與可見多邊形深度非常接近的隱藏多邊形,要麼至少將其移動得更遠。

如果上述不夠,解決方案會變得更加複雜。有一些場景確實存在深度範圍很大的幾何圖形,因此必須同時顯示。處理這些(相對罕見的)情況的方法包括對數深度緩衝區和多通道渲染方法。

請注意,我的答案純粹是關於世界空間中的原始多邊形具有不同深度的情況。如果繪製深度完全相同的多邊形(即共面多邊形),則深度對抗幾乎總是結果,而這種情況需要用其他方法避免。由於這看起來不像這裏的情況,我故意沒有掩蓋它。

+0

非常感謝,是的,我的zNear是0.01而不是0.1,完全拋棄它! – marko5049 2014-08-31 04:01:36