在OpenGL中进行深度测试的Z-fighting解决方案 - 它们如何工作?

时间:2014-06-10 13:17:43

标签: opengl graphics rendering glsl shader

描述

我在OpenGL中遇到Z-Fighting的主要问题,而且我花了很长时间才找到解决这个问题的方法。我发现的一些,我理解并且不喜欢:

  • 将多边形彼此远离(例如OpenGL中的glPolygonOffset)
  • 根据Z坐标划分场景,并使用单独的干净z缓冲区绘制场景的部分。

我不理解的那些:

我已经在我的程序中实现了第二个,只需将其放入球的顶点着色器(它与地面进行战斗):

float C = 1.0; 
float far = 2000.0; 
   gl_Position = u_projView * a_position;      
gl_Position.z = 2.0*log(gl_Position.w*C + 1.0)/log(far*C + 1.0) - 1.0;
gl_Position.z *= gl_Position.w;

它有效!

实际问题

  1. 任何人都可以解释一下如何在顶点着色器中更改顶点的Z坐标解决问题而不将顶点明显地移动到我身上? (场景看起来与人眼相同)。它是如何改变z深度值的分布的?我猜测我缺少一些关于渲染管道的知识。
  2. 有人可以向我解释我们如何使用 Projection Matrix 来解决问题?它是如何运作的?
  3. 还有其他同样有效的方法来解决z-fighting问题吗?
  4. 谢谢!

1 个答案:

答案 0 :(得分:2)

深度缓冲精度可能存在问题吗?使用16位缓冲区时,可能会发生z-fighting。您可以使用以下方式进行检查:

glGetIntegerv( GL_DEPTH_BITS, &depthBits);