我有一個GLSL着色器,它給出一組貝塞爾曲線(點的三維座標)繪製3D曲線。繪圖本身是按照我想要的方式完成的,除非遮擋不能正常工作,即在某些視點下,應該位於最前面的曲線看起來仍然被遮擋,而相反:假定的曲線部分被遮擋仍然可見。GLSL着色器:遮擋順序和剔除
爲了說明,這裏是屏幕截圖的幾個例子:
我是新來的GLSL,可能不知道這種效果正確的術語,但我相信它是遮擋剔除(更新:它實際上表明與深度緩衝,術語混亂問題)。我的問題是:如何在使用GLSL着色器時處理遮擋?我是否必須在着色器程序或其他地方對待它們?
關於我的代碼,這是一個有點長(加上我使用OpenGL包裝庫),但主要步驟是:
- 在頂點着色器,我計算
gl_Position = ModelViewProjectionMatrix * Vertex;
,並進一步通過顏色信息的幾何着色器。 - 在幾何着色器中,我取4個控制點(
lines_adjacency
)及其相應的顏色,並生成一條跟隨貝塞爾曲線(我使用Bezier段之間的基本顏色插值)的三角形條。 - 片段着色器也很簡單:
gl_FragColor = VertexIn.mColor;
。
關於OpenGL設置,我啓用GL_DEPTH_TEST
,但它似乎沒有任何我需要的東西。另外,如果我在場景上放置任何其他非着色器幾何圖形(例如四邊形),則無論視點如何,曲線總是呈現在其頂部。
任何有關如何解決它的見解和提示,以及它爲什麼發生的讚賞。
更新解決方案
所以,最初的問題,因爲我瞭解到,是不是發現了撲殺算法,但我沒有正確處理z值的計算(見接受的答案) 。我還了解到,在正確的深度緩衝區設置下,OpenGL自己正確處理遮擋,所以我不需要重新發明輪子。
我搜索了我的GLSL程序,發現在將頂點座標轉換爲屏幕座標(vec2(vertex.xy/vertex.w) * Viewport;
)時,我基本上在我的幾何着色器中將z值設置爲零。我已經通過分別計算z值(vertex.z/vertex.w
)並將它們分配到發射點(gl_Position = vec4(screenCoords[i], zValues[i], 1.0);
)來修復它。這解決了我的問題。
關於深度緩衝區設置,我沒有必要明確指定它們,因爲我使用的庫默認情況下正確設置了它們。
使用像apitrace或renderdoc這樣的調試器來查看深度緩衝區中的深度值。 – pleluron
如果我無法在理論層面弄清楚,我會嘗試。 – vicrucann
你有深度緩衝區嗎?根據用於設置上下文和渲染表面的窗口系統工具包/框架,這可能是默認設置,或者您可能需要專門請求它。 –