The concept of deep correlation

The depth of the

Depth is simply the distance from the observer. Different vertices of the same object may not be the same distance from the observer, so depth is a concept relative to pixels. The depth is the pixel’s distance from the camera in the 3D world, which is essentially the pixel’s Z coordinate.

Depth buffer

A depth buffer is an area of memory dedicated to storing the depth value of each pixel (drawn on the screen). The greater the depth value (z-value), the further away you are from the camera.

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

The depth of the test

The DepthBuffer (DepthBuffer) and the ColorBuffer (ColorBuffer) are corresponding. The ColorBuffer stores the color information of the pixel, while the DepthBuffer stores the depth information of the pixel. When deciding whether to draw an object surface, the depth value of the corresponding pixel on the surface is first compared to the value in the current depth buffer. If it is greater than the value in the depth buffer, it is discarded. Otherwise, use the depth value and color value corresponding to this pixel. Update the depth buffer and color buffer separately. This process is called deep testing.

For example, suppose we have A scenario where object A is partially obscured by object B, that is, A and B have the same x and y coordinates of part of the pixels, except for z. As shown in figure:

                                  

Assuming that there is no depth buffer or depth testing is not enabled, if we draw a close object (B) first and then draw a distant object, the distant bitmap will cover the close object because it is drawn later. With a depth buffer and depth testing enabled, the order in which objects are drawn is not so important. In fact, whenever a depth buffer exists,OpenGL writes the depth value of the pixel into the buffer. Unless glDepthMask(GL_FALSE) is called.

Specifies the depth test comparison operator

OpenGL allows you to modify the comparison operator used in depth testing to control when OpenGL passes or discards a fragment and when it updates the depth buffer. We can call the glDepthFunc function to set the comparison operator.

glDepthFunc(GL_LESS);
Copy the code

This function accepts the comparison operators in the following table:

                     

The default depth function used is GL_LESS, which will discard all fragments with a depth value greater than or equal to the current depth cache value.

The depth of the conflict

Due to the precision limitations of the depth buffer, a common visual error occurs when two planes or triangles are arranged very closely parallel to each other, and the depth buffer does not have enough precision to determine which of the two shapes comes first. The result is that the two shapes constantly switch back and forth, resulting in strange patterns. This phenomenon is called z-fighting because it seems like the two shapes are fighting over who should be at the top.

Depth conflicts are a common problem with depth buffering, which is more pronounced when objects are far away (because depth buffering has less precision when z values are large). A common solution is to create Polygon offsets between depth values, as shown below:

GlEnable (GL_POLYGON_OFFSET_FILL) // Enable polygonoffset glPolygonOffset(-1,-1); // Specify the offsetCopy the code

There are three parameters for enabling polygon offset:

  • GL_POLYGON_OFFSET_POINT: corresponding rasterization mode: GL_POINT
  • GL_POLYGON_OFFSET_LINE: corresponding rasterization mode: GL_LINE
  • GL_POLYGON_OFFSET_FILL: corresponds to the rasterization mode: GL_FILL

GlPolygonOffset takes two parameters: factor, units. The depth value of each Fragment increases the Offset shown below :Offset = (m * factor) + (r * units); M refers to the maximum slope of the depth of a polygon, and the more parallel a polygon is to the near clipplane, the closer m is to 0. R refers to the minimum discernable difference in the depth value that can be generated in the window coordinate system, and it is a constant specified by the specific OpenGL platform. An Offset greater than zero pushes the model farther away from you, and a corresponding Offset less than zero pulls the model closer. Generally speaking, simply assigning -1.0 and -1 to glPolygonOffset can meet the requirements.

Since OpenGL is a state machine, don’t forget to turn off polygon offset when you use it:

glDisable(GL_POLYGON_OFFSET_FILL) Copy the code

Deep conflict cannot be completely avoided, but there are techniques that can help mitigate or completely avoid deep conflict in your scenes.

The first and most important trick is never to place multiple objects so close together that some of their triangles overlap. By setting an offset between two objects that the user will not notice, you can completely avoid deep conflicts between the two objects.

The second tip is to set as close to the plane as possible. We mentioned earlier that the accuracy is very high near the plane, so if we are near the plane away from the observer, we will have greater accuracy for the whole frustum. However, setting the near plane too far will cause objects close to it to crop out, so it usually takes experimentation and fine-tuning to determine the near plane distance that best suits your scene.

Another good trick is to sacrifice some performance and use a more precise depth buffer. Most depth buffering is 24-bit accurate, but most graphics cards now support 32-bit depth buffering, which can greatly improve accuracy. So, by sacrificing some performance, you get more accurate depth testing and fewer depth conflicts.

The three techniques we discussed above are the most common and easily implemented anti-deep conflict techniques. There are more sophisticated techniques, but they still don’t completely eliminate deep conflict. Deep conflicts are a common problem, but if you use a combination of the techniques listed above, you probably won’t need to deal with deep conflicts anymore.

Related articles:
  1. OpenGL first lesson — Name explanation
  2. OpenGL is introduced in lesson 2 – The common fixed storage shader

  3. OpenGL introduction third lesson — matrix transformation and coordinate system

  4. OpenGL entry lesson 4 — Depth

  5. OpenGL entry lesson 5 — front and back elimination

  6. OpenGL entry lesson 6 — Clipping and Blending

  7. OpenGL entry lesson 7 — Texture

  8. OpenGL is in class 8 — a supplementary case

  9. OpenGL ES que

  10. The application of GLKit

  11. GLSL met

  12. How to use custom shaders written in GLSL in iOS

  13. Precision qualifier in GLSL

  14. Use OpenGL to write a rotating stereo album for your girlfriend