OpenGL学习日志之深度测试
创始人
2025-05-31 06:00:19
0

为什么需要深度缓冲区?

当绘制一个四边形的时候,由于我们绘制的时候是一个三角形一个三角形的绘制的,因此会导致一个像素后面的片元覆盖掉前面物体的显示。从而导致显示混乱,这个时候我们就要加入一个值来判断这个这个片元是否是在前面,根据这个来断定是否需要覆盖颜色缓冲区存储的值,这个存储这个判定顺序位置值的地方就是深度缓冲区。
并且当我们绘制存在遮挡关系的前后物体时,当物体都是不透明时,前面的物体一定会遮挡后面物体的显示,其实后面物体就不需要经过昂贵的片段着色器进行着色计算,我们可以在片段着色器着色以前就把后面的片元丢弃掉,从而提高效率和性能。

什么是深度测试?

当开启深度测试,OpenGL会读取当前片段存储的深度值,与当前片段的深度缓冲区的深度值进行比较。比较是按照我们设置的运算操作符,如果测试通过,则会把片元数据传入下一个阶段,如果测试不通过,丢弃该片元,不再传入下一个阶段。

OpenGL开启深度测试的方法

glEnable(GL_DEPTH_TEST);

一旦启用深度测试,如果片段通过深度测试,OpenGL自动在深度缓冲区存储片段的 z 值,如果深度测试失败,那么相应地丢弃该片段。如果我们深度测试通过,但是也不想写入深度缓冲区新的值,我们也可以通过指令关闭深度写入。
OpenGL允许我们通过将其深度掩码设置为GL_FALSE禁用深度缓冲区写入

glDepthMask(GL_FALSE);

一旦启用深度测试,在每个渲染之前还应使用GL_DEPTH_BUFFER_BIT清除深度缓冲区,否则深度缓冲区将保留上一次进行深度测试时所写的深度值。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

我们可以通过调用glDepthFunc来设置比较运算符 (或叫做深度函数(depth function)):

glDepthFunc(GL_LESS);

该函数接受在下表中列出的几个比较运算符:
在这里插入图片描述
默认情况下使用GL_LESS

当我们没有开启深度测试时,显示如下图,存在后面像素覆盖掉了前面像素,因此显示非常奇怪。在这里插入图片描述

当我们开启深度测试,使用默认GL_LESS运算符,显示如下图,由于深度关系,后面的片元就不会覆盖掉前面的片元的颜色信息,后面的片元由于深度值大于前面的值,会被丢弃掉。
在这里插入图片描述
深度测试的顺序
当片段着色器计算完以后,需要经历各种测试。
裁剪测试(Scissor Test),透明度测试(Alpha Test),模板测试(Stencil Test),深度测试(Depth Test)
在这里插入图片描述

深度值精度

深度缓冲区包换的深度值范围为0.0f到1.0f。视图空间的z值可以是近平面和远平面之间的任何值,我们要将这个Z转换到范围0.0f到1.0f下,简单的转换就是线性转换。
在这里插入图片描述
然而,在实践中是几乎从来不使用这样的线性深度缓冲区。非线性深度方程是和1/z成正比的 ,即离近平面越近,精度越高。
.
在这里插入图片描述
对应非线性曲线如下图
在这里插入图片描述
只要记住深度缓冲区的值不是线性的屏幕空间。
将深度可视化
片段渲染器的内置gl_FragCoord向量的 z 值包含那个片段的深度值,因此可视化就是把这个z值作为颜色显示值显示出来。

void main()
{color = vec4(vec3(gl_FragCoord.z), 1.0f);
} 

当我的近平面设置为0.1f,远平面设置为100的时候,我的物体z值为-2时,显示基本就是白色了。即1
在这里插入图片描述

但我设置为-0.15f时接近于黑色,但是不是全黑,如下图。
在这里插入图片描述

如果要把非线性转换为线性则
先将[0,1]的深度值空间转换到NDC[-1,1],把我们所得到的 z 值应用逆转换来检索的线性深度值:

#version 330 coreout vec4 color;float LinearizeDepth(float depth)
{float near = 0.1;float far = 100.0;float z = depth * 2.0 - 1.0; // Back to NDCreturn (2.0 * near) / (far + near - z * (far - near));
}void main()
{float depth = LinearizeDepth(gl_FragCoord.z);color = vec4(vec3(depth), 1.0f);
}

EarlyZ技术

现在大多数 GPU 都支持一种称为提前深度测试(Early depth testing)的硬件功能,允许深度测试在片段着色器之前操作,这样就可以筛选掉那批原本会被深度测试丢弃的片段,从而减少片元着色器的着色阶段,提高效率。

但Earlyz在有些情况下会失效
1、开起透明度测试或在片段着色器中手动discard片段
因传统的管线,透明度测试应该在深度测试之前,这样我们提前深度测试就会发生问题,我们无法预知片段是否能够通过透明度测试,因此无法判断提前深度测试的时候,深度信息是否应该写入。
比如一个物体A,透明度为0.3,深度为0.1,另一个物体B,透明度为0.7,深度为0.6

开启EarlyZ,使用默认的Less,不开启透明度测试
EarlyZ阶段就会丢弃掉B的片元,只显示出A
关闭EarlyZ,开启透明度测试,小于0.4则丢弃
则透明度测试阶段会丢弃A,只显示出B.
若透明度测试和EarlyZ都开启
则由于在Early会丢弃掉B,A的深度信息写入深度缓冲,而透明度测试又会丢弃掉A,因此什么都不显示
这样按道理肯定是不对。

我们想要的肯定是显示出B,这就是当开启了透明度测试,我们无法预测通过EarlyZ深度测试的物体是否应该深度写入。因为他可能在透明度测试或者片段着色器阶段就被手动丢弃。
2、手动修改深度值,也是因为无法提前预知修改的深度值
3、开启透明度混和,因为透明度混和会关闭深度写入

深度冲突

两个平面或三角相互平行且靠的很近,深度缓冲区不具有足够的精度去分辨哪一个靠前,就会出现两个物体不断切换顺序的情况,这个就是深度冲突。
深度冲突无法完全避免,只能预防和减轻。

减轻深度冲突的方法
1、让物体之间不要离得太近,以至于他们的三角形重叠。
2、修改近平面,让物体离近平面近一点,获得更高的深度精度。
3、放弃一些性能来得到更高的深度值的精度。大多数的深度缓冲区都是24位。但现在显卡支持32位深度值,这让深度缓冲区的精度提高了一大节

相关内容

热门资讯

iPhone手机怎么玩安卓系统... 你有没有想过,你的iPhone手机竟然也能玩安卓系统?没错,就是那个一直以来让你觉得遥不可及的安卓世...
平板删安卓系统更新不了,原因及... 最近是不是你也遇到了这样的烦恼?平板电脑上的安卓系统更新不了,是不是让你头疼得要命?别急,今天就来给...
苹果组装机安卓系统卡,卡顿背后... 你有没有发现,最近用苹果手机的时候,有时候系统有点卡呢?这可真是让人头疼啊!你知道吗,其实这背后还有...
安卓系统原生浏览器,功能与体验... 你有没有发现,每次打开手机,那个小小的浏览器窗口总是默默无闻地在那里,陪你浏览网页、搜索信息、看视频...
安卓机如何上苹果系统,跨平台体... 你是不是也和我一样,对安卓机和苹果系统之间的切换充满了好奇?想象你的安卓手机里装满了各种应用,而苹果...
安卓导入系统证书失败,原因分析... 最近在使用安卓手机的时候,你是不是也遇到了一个让人头疼的问题——导入系统证书失败?别急,今天就来给你...
安卓原生系统有哪些手机,盘点搭... 你有没有想过,为什么有些手机用起来就是那么流畅,那么顺心呢?这背后可大有学问哦!今天,就让我带你一起...
安卓系统关机了怎么定位,安卓系... 手机突然关机了,是不是有点慌张呢?别担心,今天就来教你一招,让你的安卓手机即使关机了,也能轻松定位到...
安卓系统游戏加速器,畅享无延迟... 你有没有发现,手机游戏越来越好玩了?不过,有时候游戏体验可能并不那么顺畅,是不是因为手机性能不够强大...
安卓4系统天气功能,尽在掌握 安卓4系统天气功能大揭秘在当今这个数字化的世界里,手机已经不仅仅是一个通信工具,它更是一个集成了各种...
安卓系统如何玩碧蓝幻想,攻略与... 你有没有想过,在安卓系统上玩《碧蓝幻想》竟然可以这么酷炫?没错,就是那个让你沉迷其中的二次元大作!今...
安卓系统搜不到图朵,图朵生成之... 最近是不是你也遇到了这样的烦恼?手机里明明有那么多美美的图片,但是用安卓系统搜索的时候,却怎么也找不...
魁族8刷安卓系统,系统升级后的... 哇,你知道吗?最近在安卓系统圈子里,有一个话题可是引起了不小的轰动,那就是魁族8刷安卓系统。你是不是...
微信正版安装安卓系统,畅享沟通... 你有没有想过,你的微信是不是正版安装的安卓系统呢?这可不是一个小问题哦,它关系到你的微信使用体验和隐...
电视能刷安卓系统吗,电视也能刷... 电视能刷安卓系统吗?揭秘智能电视的无限可能想象你家的电视不再只是用来观看节目的工具,而是变成了一个功...
安卓系统开通通知功能,畅享智能... 你知道吗?最近安卓系统更新后,新增了一个超级实用的功能——开通通知功能!这可是个大喜事,让咱们的生活...
苹果系统安卓爱思助手,系统兼容... 你有没有发现,手机的世界里,苹果系统和安卓系统就像是一对欢喜冤家,总是各有各的粉丝,各有各的拥趸。而...
安卓系统占用很大内存,揭秘内存... 手机里的安卓系统是不是让你感觉内存不够用,就像你的房间堆满了杂物,总是找不到地方放新东西?别急,今天...
安卓系统p30,安卓系统下的摄... 你有没有发现,最近安卓系统P30在手机圈里可是火得一塌糊涂呢!这不,我就来给你好好扒一扒这款手机的那...
siri被安卓系统进入了,智能... 你知道吗?最近科技圈可是炸开了锅,因为一个大家伙——Siri,竟然悄悄地溜进了安卓系统!这可不是什么...