The origin of depth and depth buffers

If drawn away from the observer object first, then draw near objects, but observers see nearby objects, only the distance will be obscured, need not appear on the screen, do not necessary apply colours to a drawing and drawing, if drawing near the observer object first, then draw the object, because far objects after the draw, would take nearly cover object, So OpenGL uses a value to record the distance from the observer, the depth, so that it can be drawn in any order, draw only the closest objects,

The relationship between depth and Z coordinate is as follows:

Figure 1 The observer is in the positive direction of the Z axis. The larger the Z value, the closer the observer is. When the Z value of the object is greater than the Z value of the observer, the object is out of view and cannot be displayed

FIG. 2 The observer is in the negative direction of the Z axis. The smaller the Z value is, the closer it is to the observer. When the Z value of the object is less than the Z value of the observer, the object is out of the field of view and cannot be displayed

When the observer is in the plane z=0, the z value is the depth value.

Depth values are generally represented by 16 -,24 -, and 32 – bit values. Usually 24 bits. The higher the number, the better the depth accuracy.

All the pixels of the image, corresponding to the depth value, the video memory to open up a memory area to save, this memory area is called the depth buffer

In video memory, the DepthBuffer corresponds one-to-one to the ColorBuffer. The ColorBuffer stores the color information of the pixel, while the DepthBuffer stores the depth information of the pixel. When determining whether to draw an object surface and what color to draw, only pixels close to the observer (with a small depth value) will be displayed under the default depth comparison rule after the depth test is enabled.

Before rendering, we will empty the color buffer and depth buffer. The depth buffer values are all cleared to 1.0, indicating the maximum depth value (the depth buffer values are in the range of (0,1)).

Rendering begins by comparing the depth value of the corresponding pixel on the surface of the object to the value in the current depth buffer. If it is greater than the value in the depth buffer, it means that it is far away from the observer. Such pixel points do not need to be displayed on the screen. Therefore, the data in the depth buffer and color buffer remain unchanged, and the pixel points are ignored. If the pixel value corresponding to the surface is less than the value in the depth buffer, indicating that the surface is closer to the observer, update the values in the depth buffer and color buffer with the depth value and color value of the pixel on the object surface. This process is called depth testing

  1. First, before rendering, as shown in Figure 1, the color cache is cleared, the depth buffer is set to 1,

  2. When rendering a red rectangle, a depth test is performed for each pixel of the red rectangle. Since all the values in the depth buffer are 1 and the depth value of the red rectangle is less than 1, in Figure 2, the color and depth values of the red rectangle region are updated to the color buffer and depth buffer

  3. In figure 3, figure 2 fold a blue rectangle, on the basis of all the pixel depth test again, will close the viewer (smaller values of the depth of the depth of the pixel value and color value in the depth buffer, buffer and color pixels in superposition part, due to blue observer closer, so the buffer updated blue color values and depth

  4. After rendering, the color buffer data is submitted for display on the screen

OpenGL allows you to modify the comparison operators used in deep testing (which are rarely set by developers, so use the default mode)

Void glDepthFunc(GLEnum mode); // Specify the depth test mode.Copy the code

Mode can be set to one of the following parameters. By default, GL_LESS,

OpenGL allows you to open/block writes to the depth buffer

void glDepthMask(GLBool value); //value: //GL_TURE enables deep buffer writing; GL_FALSE Disables deep buffer writingCopy the code

The program uses an in-depth testing process

ZFighting flashing

Due to the limitation of the depth buffer accuracy, when two shapes are almost in a Z plane, the depth buffer does not have enough accuracy to determine whether the two shapes are closer together (with less depth), resulting in the two shapes constantly in order before and after the switch, and the screen flickers. This phenomenon is called z-fighting **, which is shown in the figure below

A common solution is to create Polygon offsets between depth values –> resolve ZFighting flickering

GL_POLYGON_OFFSET_FILL (GL_POLYGON_OFFSET_FILL) GL_POLYGON_OFFSET_POINT: GL_POLYGON_OFFSET_FILL: GL_FILL glPolygonOffset(-1,-1); //GL_POLYGON_OFFSET_LINE: corresponds to the raster mode: GL_LINE //GL_POLYGON_OFFSET_FILL: corresponds to the raster mode: GL_FILL glPolygonOffset(-1,-1); // Specify the offsetCopy the code

GlPolygonOffset requires two parameters: factor, units. Offset = (m * factor) + (r *units); Offset = (m * factor) + (r *units); M refers to the maximum slope of the depth of the polygon, and the more parallel a polygon is to the near-cutting surface, the closer m is to 0. R refers to the minimum discernable difference in the depth values that can be generated in the window coordinate system, which is a constant specified by the specific OpenGL platform. An Offset greater than 0 will push the model further away from you, and a corresponding Offset less than 0 will pull the model closer. In general, simply assigning values such as -1.0 and -1 to glPolygonOffset will suffice.

Close polygon offset after use

glDisable(GL_POLYGON_OFFSET_FILL)
Copy the code

Prevent ZFighting flickering, but not completely avoid it

  1. Do not place objects too close together to avoid overlapping triangles. Depth conflicts between two objects can be avoided by setting a small to offset value between them.
  2. Set as far away from the plane as possible. The depth accuracy is very high near the clipping surface, so if we approach the clipping surface away from the observer, we will have greater accuracy for the entire truncated head body. However, setting the near plane too far will cause the near objects to be clipped off, usually requiring the Teo is to determine the distance of the near plane that best suits the scene.
  3. Use more precise depth buffering. Most depth buffering accuracy is 24 bit, but most graphics cards now support 32 bit depth buffering, which will greatly improve accuracy. So, by sacrificing some performance, you can get more accurate depth testing and fewer deep collisions.