今天我们来聊聊一个很重要的概念--深度缓冲区,OpenGL中的深度缓冲区,也叫Z缓冲区,接下来我们来大概了解一下。
其他缓冲区简要介绍
在了解深度缓冲区之前,我们先来聊聊其他相关的一些缓冲区的介绍。
颜色缓冲区
颜色缓冲区(COLOR_BUFFER)就是帧缓冲区(FRAME_BUFFER),你需要渲染的场景最终每一个像素都要写入该缓冲区,然后由它在渲染到屏幕上显示。
深度缓冲区
- 深度缓冲区(DEPTH_BUFFER)与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确。
- 作用:深度缓冲区的作用就是区分颜色所在的层次,防止把被遮挡住的颜色显示出来。
模板缓冲区
模版缓冲(STENCIL_BUFFER)与深度缓冲大小相同,通过设置模版缓冲每个像素的值,我们可以指定在渲染的时候只渲染某些像素,从而可以达到一些特殊的效果。实际开发使用中,我们很少使用到。
深度缓冲区的原理介绍
隐藏面消除
隐藏表面消除就是消除实心物体被其他物体所遮挡的那部分。实现隐藏表面消除最简单方法就是使用深度缓冲区(又叫Z缓冲区)。
深度缓冲区原理
深度缓冲区原理就是把一个距离观察平面(近裁剪面)的深度值(或距离)与窗口中的每个像素相关联。
- 首先,使用glClear(GL_DEPTH_BUFFER_BIT),把所有像素的深度值设置为最大值(一般是远裁剪面)。
- 然后,在场景中以任意次序绘制所有物体。硬件或者软件所执行的图形计算把每一个绘制表面转换为窗口上一些像素的集合,此时并不考虑是否被其他物体遮挡。
- 其次,OpenGL会计算这些表面和观察平面的距离。如果启用了深度缓冲区,在绘制每个像素之前,OpenGL会把它的深度值和已经存储在这个像素的深度值进行比较。新像素深度值<原先像素深度值,则新像素值会取代原先的;反之,新像素值被遮挡,他颜色值和深度将被丢弃。
为了启动深度缓冲区,必须先启动它,即glEnable(GL_DEPTH_TEST)。每次绘制场景之前,需要先清除深度缓冲区,即glClear(GL_DEPTH_BUFFER_BIT),然后以任意次序绘制场景中的物体。
深度测试
在OpenGL中,经常会出现深度测试,那么什么是深度?为什么需要深度?怎么启用深度测试?接下来,我们就来把它弄清楚。
什么是深度?
- 深度其实就是该象素点在3d世界中距离摄象机的距离(绘制坐标),深度缓存中存储着每个象素点(绘制在屏幕上的)的深度值!
- 深度值(Z值)越大,则离摄像机越远。
- 深度值是存贮在深度缓存里面的,我们用深度缓存的位数来衡量深度缓存的精度。
为什么需要深度?
- 在不使用深度测试的时候,如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这样的效果并不是我们所希望的。而有了深度缓冲以后,绘制物体的顺序就不那么重要了,都能按照远近(Z值)正常显示,这很关键。
- 实际上,只要存在深度缓冲区,无论是否启用深度测试,OpenGL在像素被绘制时都会尝试将深度数据写入到缓冲区内,除非调用了glDepthMask(GL_FALSE)来禁止写入。这些深度数据除了用于常规的测试外,还可以有一些有趣的用途,比如绘制阴影等等。
启用深度测试
- 使用
glEnable(GL_DEPTH_TEST)
- 在默认情况是将需要绘制的新像素的z值与深度缓冲区中对应位置的z值进行比较,如果比深度缓存中的值小,那么用新像素的颜色值更新帧缓存中对应像素的颜色值。
- 但是可以使用
glDepthFunc(func)
来对这种默认测试方式进行修改。其中参数func的值可以为GL_NEVER(没有处理)
、GL_ALWAYS(处理所有)
、GL_LESS(小于)
、GL_LEQUAL(小于等于)
、GL_EQUAL(等于)
、GL_GEQUAL(大于等于)
、GL_GREATER(大于)
或GL_NOTEQUAL(不等于)
,其中默认值是GL_LESS
。- 通常情况下,使用
glDepthFunc(GL_LEQUAL)
;来表达一般物体之间的遮挡关系。
注意:启用了深度测试,那么这就不适用于同时绘制不透明物体。绘制半透明物体时,需注意:在绘制半透明物体时前,还需要利用
glDepthMask(GL_FALSE)
将深度缓冲区设置为只读形式,否则可能出现画面错误。为什么呢,因为画透明物体时,将使用混色,这时就不能继续使用深度模式,而是利用混色函数来进行混合。这一来,就可以使用混合函数绘制半透明物体了。
--
总结:上面我们提到了关于混色函数进行混合处理,我们在后面的学习中会讲讲关于混合的处理。
--
系列连载
OpenGL入门(一)-- 图形API简介与作用
OpenGL入门(二)-- 快速了解OpenGL下的专业名词
OpenGL入门(三)-- OpenGL坐标系解析与坐标变换
OpenGL入门(四)-- OpenGL坐标系与坐标变换
OpenGL入门(五)-- OpenGL渲染流程图解析
OpenGL入门(六)-- OpenGL 固定存储着色器的理解使用
OpenGL入门(七)-- 图形图像渲染中的深度缓冲区
OpenGL入门(八)-- OpenGL向量和矩阵简介
OpenGL入门(九)-- OpenGL 纹理简单介绍