z-fighting問題是三維渲染中常見的問題,本文根據實際工做中遇到的一些場景,進行了系統的總結spa
遇到深度檢測問題,最重要的是先搞明白是哪兩個面離得太近致使的問題。好比上面這個問題,一直以來我都覺得是柱子的面跟底圖基礎底面的問題。因此嘗試了各類解決深度檢測的問題都沒起做用。blog
直到後面一次偶然的嘗試,開啓了CULL_FACE後,這個深度碰撞正常了。思考了好久纔想到原來它發生深度碰撞的緣由不是跟地圖底面,而是柱子的上頂面跟下頂面離得太近發生的碰撞。恍然大悟!get
這張圖的表現頗有欺騙性,底面是黑色的,而恰好碰撞部分也是一部分藍,一部分發暗,因此很讓人想固然的認爲是底圖跟柱子之間的問題。這個緣由是由於默認沒有面剔除,致使底面也被繪製了,而底面的法線方向與光線方向夾角很大,致使最後計算的顏色發暗。因此碰撞部分一部分明亮,一部分發暗。it
最終這個問題的解決方式是,開啓CULL_FACE,剔除背面三角形,同時在着色中爲頂點增長一點偏移class
let parameters = { [GL.DEPTH_TEST]: true, [GL.CULL_FACE]: true, [GL.CULL_FACE_MODE]: GL.FRONT };
// 計算cube該頂點的位置, cube的X座標範圍是-1~1,(rotatedPosition.x * coverage + 1.0) / 2.0座標範圍在0~1之間 // cube的Z座標範圍是-1~1,(rotatedPosition.z * coverage - 1.0) / 2.0座標範圍在-1~0之間 // cubeTopLeftPosition在cube局部座標系的(-1, 0, -1)位置 vec4 vertexPosition = cubeTopLeftPosition + vec4( vec2( (rotatedPosition.x * coverage + 1.0) / 2.0 * useRadius, (rotatedPosition.z * coverage - 1.0) / 2.0 * useRadius ), 1.0, 1.0 );
因爲z-buffer的精度並非線性相關的,而是在靠近near平面是精度很是大,可是靠近遠平面時精度很是低,所若是平面離着相機很是遠,那麼就極可能出現深度檢測問題。基礎
1. 首先搞明白是哪兩個面發生的深度碰撞渲染
2. 數據層面永遠不要把兩個物體靠的太近,最好在用戶不太注意的地方稍微加一點偏移方法
3. 將near設置的大一些,這樣使得場景中的物體都在高精度範圍內,但這種方式也是須要調整,near設置的太大,會致使一些應當在視野範圍內的物體被裁切掉
6. 修改投影矩陣的第十位,增長一個小的偏移(http://note.youdao.com/noteshare?id=43a15cadb1afebb1b4ad24a4c159d1e0&sub=37ECF8DF031440D99B69D9CE60850F8A)