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)