OpenGL 中的深度偏移

Depth offset in OpenGL

在 OpenGL 中偏移深度的最佳方法是什么?我目前有每个多边形的索引顶点属性,我正在将其传递给 OpenGL 中的顶点着色器。我的目标是在深度上抵消多边形,其中最高索引始终位于较低索引的前面。我目前有这种简单的方法修改 gl_Position.z.

gl_Position.z += -index * 0.00001;

设置深度自动偏移的常用方法是glPolygonOffset(GLfloat factor,GLfloat units)

When GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, or GL_POLYGON_OFFSET_POINT is enabled, each fragment's depth value will be offset after it is interpolated from the depth values of the appropriate vertices. The value of the offset is factor * DZ + r * units, where DZ is a measurement of the change in depth relative to the screen area of the polygon, and r is the smallest value that is guaranteed to produce a resolvable offset for a given implementation. The offset is added before the depth test is performed and before the value is written into the depth buffer.

glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( 1.0, 1.0 );

如果您想手动操作深度,则必须在片段着色器中设置 gl_FragDepth

gl_FragDepth, Fragment Shader:

Available only in the fragment language, gl_FragDepth is an output variable that is used to establish the depth value for the current fragment. If depth buffering is enabled and no shader writes to gl_FragDepth, then the fixed function value for depth will be used (this value is contained in the z component of gl_FragCoord) otherwise, the value written to gl_FragDepth is used.

一般来说,gl_FragDepth的计算方式如下(见GLSL gl_FragCoord.z Calculation and Setting gl_FragDepth):

float ndc_depth = clip_space_pos.z / clip_space_pos.w;
gl_FragDepth    = (((farZ-nearZ) * ndc_depth) + nearZ + farZ) / 2.0;

为获得最小差异而需要添加或减去深度的最小偏移量取决于深度缓冲区的格式。

深度缓冲区格式GL_DEPTH_COMPONENT16GL_DEPTH_COMPONENT24GL_DEPTH_COMPONENT32是规范化的整数格式, 其中 16、24 或 32 位整数范围映射到深度值 [0, 1].

另一方面,格式 GL_DEPTH_COMPONENT32F 是 IEEE 754 标准的 32 位浮点格式。