2015-10-04 74 views
3

所以我最近觀看了Z戰的視頻,並且學會了一種簡單的方式來照顧它 - 主要是。給出的解決方案是實際上歪斜投影,以便爲更精確的深度測試提供更多空間(因爲浮點只能如此精確),並且將更遠的物體塞入投影的一小部分區域。現在,我對OpenGL和圖形編程還很陌生(只是慢慢地開展工作),實際上我沒有做出任何足夠複雜的工作,但這對我來說是個問題,但我將來可能需要知道這一點。無論如何,上述解決方案帶來的新問題更加嚴重的是在遠距離的Z-戰鬥(例如,天際山,鐵鏽山等)。是否有更好的解決方案,即使它具有性價比,也不涉及圖形折衷?假設地說(因爲我對OpenGL管線還不是很舒服),程序中的Z值在進行深度測試之前是否可以加倍加倍?如何避免Z距離戰鬥?

讓我澄清。想想天際。注意山脈有時會閃爍嗎?當使用OpenGL渲染場景時,所有對象都會被擠壓或「夾」到Z值爲-1.0到1.0的小座標平面中。然後對每個物體進行深度測試 - 樹木,雪,山脈,動物,房屋,您可以對其進行命名,以便在被其他物體覆蓋時不會繪製任何物體。然而,浮點只能達到一定的精度,因此將數百個物體夾在一個小空間中不可避免地會導致某些物體具有完全相同的Z座標,並且這兩個物體在屏幕上一起閃爍,稱爲「Z -戰鬥」。我在問每個對象的深度(z-)座標是否可以轉換爲雙精度,以便它們具有足夠的精度(值得爲可忽略的一段時間使用可忽略的額外內存),以便按正確的順序精確繪製對象,而不會相互剪切。

+0

不錯的問題,但「鑄造」到一個更大的類型不會自動增加細節。如果您將Pi的值存儲在float中並稍後將其轉換爲double,則它不會自動獲得更有意義的數字。 – usr2564301

+0

不會,只有在z值被強制調整之前,它們纔會使z值增加一倍 - 這樣當它們夾在-1.0和1.0之間時,精度就會高得多,而且不會像重複的Z值那麼容易。 –

+1

您必須記住OpenGL的深度緩衝區需要爲每個像素*存儲深度值*。增加其保真度的唯一方法是將其深度設置爲使用更多字節。 (並且請注意,一些OpenGL實現對此大小有限制。)您可能需要閱讀https://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm。 – usr2564301

回答

3

當使用OpenGL渲染場景時,所有對象都會被擠壓或「夾」到Z值爲-1.0到1.0的小座標平面中。

這只是故事的一部分。另一部分是z以非線性方式存儲:具有最高「保真度」的部分是接近Z平面的部分,保真度隨着您向後移動而降低。有關公式,請參閱this page

OpenGL常見問題解答12. The Depth Buffer中討論了這個問題12.070爲什麼在深度緩衝區的前端有更高的精度?12.080提出了針對不同z距離的多遍渲染。

您可以使用glGetIntegerv(GL_DEPTH_BITS, &bits);查詢當前深度緩衝區大小,但(搜索後)似乎沒有標準方法將其更改爲使用更大(或更小)的深度。

Z戰鬥在遙遠的物體可以通過不繪製他們作爲3D對象反擊。例如,如果你的例子中的山脈很遠,任何視差效果都將看不見。所以在那種情況下,你可能會更好地將遠處的物體拖到天空盒上。

+2

默認幀緩衝區的深度緩衝區的位深度不由GL控制,而是由操作系統控制。它是窗口的一個屬性(或者任何可用的drawable),因此必須使用平臺的GL接口API(如windows上的wgl,unix/X11上的glX等)來設置它。儘管如此,不要期望在普通硬件上看到超過24位(整數)的廣泛支持。但是,在使用FBO時,通常可以使用32位浮點深度緩衝區。 – derhass

1

您可以解決。通常,您通過從最近到最近進行排序來一次渲染所有對象。

您可以改爲根據距離分成兩組,分別稱爲FarGroupNearGroup

如果應用程序沒有一定的限制,如:

  • 你不使用模板緩存的東西
  • 你不需要特殊效果(屏幕空間環境光遮蔽,景深等深度)

您可以使用模板緩衝區來解決Z-fight問題。

  • 清除模板,顏色的深淺和緩衝區
  • 您設置一個模板功能,使每個對象繪製設置有點

    glStencilOp(GL_KEEP,GL_KEEP, GL_INCR);

    glStencilFunc(GL_ALWAYS, 1, 0x01);

  • 然後你渲染NearGroup

  • 清除深度緩衝器
  • 設置模板測試只畫出其中模版位未設置

    glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP);

    glStencilFunc(GL_NOTEQUAL, 1, 0x01);

  • 渲染FarGroup

你可以通過反轉渲染順序來調整不使用模具(由於像素透支性能penality),也許你可以限制SSAO只到NearGroup,並使用烘焙AO值遠的對象,但你明白了,你獲得了一些東西但是你失去了做別的事情的能力(有很多解決方法來限制性能和頭腦風暴的成本)。

的相機,你只安裝2個不同的視錐至極只是原來的截錐2

切片如果你沒有太多的限制,你可以使用上面的tecnique你既沒有Z-鬥爭並且還比使用32位Z緩衝器更快地渲染(由於GPU的內部優化)

0

首先,一個重要細節:頻繁的錯誤是讓近平面真的太接近於零。由於z映射是非線性的,因此大部分動力學都位於最前面,並且在距離處缺失。

0

對所有幾何體進行排序以繞過Z緩衝區的成本很高。 一個典型的折衷辦法是將場景分爲2層或3層(如前方(駕駛艙/角色/武器),近地形和遠景),併爲其中的每一層定製znear/zfar(將Z in之間)。