OpenGL学习笔记十二(深度测试)
需要深度测试的原因
当我们渲染多个物体时,这多个物体之间存在互相遮挡的关系,被遮挡的物体的部分将不可见,也就是它离相机更远,为了告诉计算机被遮挡的物体不需要渲染,我们就需要对物体上的点做深度测试,检测它是否需要渲染。
为了实现上述的检测,就需要深度缓冲,简单而言就是存储物体上点深度值的数组,这个数组一开始值为0,当目前渲染的物体的深度值大于缓冲区中存储的深度值时,就将这个值写入缓冲区,同时通过深度测试,如果与此相反,深度值小于缓冲区中的深度值,就是未通过深度测试,且不写入缓冲区,淘汰掉这个点(不做渲染)。
当然,比较函数可以自己定义,接下来会做介绍。
深度测试函数
深度测试主要有两个步骤,
- 对比缓冲区中的值,判断是否通过测试(Z Test)
- 是否将该值写入缓冲区(Z Write)
深度测试函数默认关闭,开启深度测试函数的方法:
glEnable(GL_DEPTH_TEST);
深度写入函数的控制开关:
glDepthMask(GL_FALSE);
glDepthMask(GL_TRUE);
比较函数
通过比较函数,我们可以自定义刷新缓冲区的方式
glDepthFunc(GL_ALWAYS);
函数 | 描述 |
---|---|
GL_ALWAYS | 永远通过深度测试 |
GL_NEVER | 永远不通过深度测试 |
GL_LESS | 在片段深度值小于缓冲的深度值时通过测试 |
GL_EQUAL | 在片段深度值等于缓冲区的深度值时通过测试 |
GL_LEQUAL | 在片段深度值小于等于缓冲区的深度值时通过测试 |
GL_GREATER | 在片段深度值大于缓冲区的深度值时通过测试 |
GL_NOTEQUAL | 在片段深度值不等于缓冲区的深度值时通过测试 |
GL_GEQUAL | 在片段深度值大于等于缓冲区的深度值时通过测试 |
清除深度缓存
我们每次渲染一遍之后需要将缓存值清空,不然可能会出现画面错误情况
清除方式和清楚颜色缓存一样
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
深度测试精确度及深度冲突
计算深度值的函数:
深度值往往有16位,24位和32位,其值位0-1。
出现的问题:
- 当大量物体离摄像机极远时,会出现深度值错误的现象,因为太过集中在1这个值处了
- 当大量物体在同一平面时,会出现深度值相同(因为是float,所以可能每次渲染的结果都不同,造成抖动现象)
对于以上两类问题,应该设置其渲染顺序,相机的近平面和远平面,来达到最佳效果