OpenGL 浅析深度测试

362 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情


  1. Swift Optional
  2. Swift Enum
  3. iOS开发 做一个三角形
  4. Swfit 指针类型
  5. Swift 属性(下)
  6. Swift 属性
  7. Swift 小结
  8. Swift 类与结构体(下)
  9. Swift 类的生命周期
  10. Swift 类的初始化器
  11. Swift 类与结构体
  12. OpenGL 压缩纹理
  13. OpenGL 隧道坐标计算
  14. 0penGL 像素格式及数据类型
  15. OpenGL 纹理对象
  16. OpenGL 纹理
  17. OpenGL 模型变化
  18. OpenGL 视图
  19. OpenGL 矩阵
  20. OpenGL 向量
  21. OpenGL 颜色混合
  22. OpenGL 深度测试的潜在风险
  23. OpenGL 浅析深度测试
  24. OpenGL 浅析隐藏面消除
  25. OpenGL 图元连接方式
  26. 记WKWebView与HTML完成交互两三事
  27. OpenGL 渲染流程图解析
  28. OpenGL 控制你的正方形
  29. OpenGL 专业名词解释
  30. OpenGL 环境搭建 - MacOS

接着上一篇 OpenGL 浅析隐藏面消除 ,今天我们继续来整理下上一片最后使用正背面剔除后,甜甜圈绘制中存在的问题:

正背面剔除 问题.gif

可以看到在使用正背面剔除后,甜甜圈的背面不再渲染,但是,当旋转之后,会存在外圈的正面和内圈的正面同时对着观察者,这个时候OpenGL的处理就存在问题。

如何解决呢? 我们先来了解一下什么是深度。

  • 深度就是该像素点在3D世界中距离摄像机的距离,Z值

  • 深度缓冲区 就是一块内存区域,专门存储着每个像素点(绘制在屏幕上的)深度值,深度值越大,则离摄像机就越远

为什么需要深度缓冲区呢?

  • 在不使用深度测试的时候,如果我们先绘制一个距离比较近的物体,再绘制一个距离比较远的物体,则距离远的位图因为后绘制,会把距离近的物体覆盖掉,有了深度缓冲区后,绘制物体的顺序就不那么重要了;实际上,只要存在深度缓冲区,OpenGL就会把像素的深度值写入到缓冲区中,除非调用 glDepthMask(GL_FALSE),来禁止写入。

深度测试

  • 深度缓冲区 (DepthBuffer)和颜色缓冲区(ColorBuffer)是对应的。颜色缓冲区存储像素的颜色信息,而深度缓冲区存储像素的深度信息。在决定是否绘制一个物体表面时,首先要将表面对应的像素的深度值与当前的深度缓冲区中的值进行比较。如果大于深度缓冲区中的值,则丢弃这部分内容。否则,利用这个像素对应的深度值和颜色值分别更新深度缓冲区和颜色缓冲区。这个过程称为 深度测试

开启了深度测试,则在绘制每个像素之前,OpenGL 会把它的深度值与目前像素点对应存储的深度值,进行比较.如果 像素点新对应深度值 <像素点对应的深度值.(意思比较当前2个图层时,那个图层更加接近于观 察者, 那么此时就会将该像素点的深度值进行取而代之;反之,如果像素点上的新颜色值如果距离观絮者更 远,则应该会遮挡. 那么此时它所对应的深度值与颜色值就会被抛弃. 不进行绘制;

清空深度缓冲区

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

开启深度缓冲区

glEnable(GL_DEPTH_TEST);

关闭深度缓冲区

glDisable(GL_DEPTH_TEST);

深度缓存区的默认值为1.0;表示最大的深度值, 深度值的范围是[0,1]之间。

我们可以通过 gIDepthFunc(GLenum func) 来修改 深度测试的测试规则.那么测试的规则主要在于该函数中的枚举值。

image.png