找回密码
 立即注册
查看: 246|回复: 0

深度缓冲与深度测试的原理

[复制链接]
发表于 2023-3-9 13:55 | 显示全部楼层 |阅读模式
前言

今天给大家分享的是深度缓冲与深度测试的原理,帮助大家对深度缓冲深度测试的理解
在开发渲染的过程中,我们少不了要进行深度缓冲和深度测试,通过这两个步骤我们可以更好的进行渲染,做出更加炫丽的效果,首先我们需要了解它们的原理,以更好的使用
点击观看
版权声明

本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源
完整文章合集

深度缓冲与深度测试原理
深度缓冲与深度测试应用
画家算法

如果你想了解计算机如何去绘图,就需要了解画家算法,在计算机图形学中,有一个很重要的问题需要解决,这个问题叫做可见性问题,我们需要将一个3D模型投影到一个2D的屏幕上,在这个过程中,哪些模型上的三角形是可见的,哪些是不可见的,都需要正确处理



如上图所示,当一个画家需要画出最右侧图片时,他一定是先从最远的开始画起,而图上从左到右的绘画顺序就是典型的画家算法

计算机图形学就是用画家算法进行绘图,首先将待渲染图形里面的多边形根据深度排序,之后按照顺序进行绘制,当我们从后往前进行绘制时,就不会造成后面遮挡前面的问题,也就解决了可见性问题
逐个像素点排序

但画家算法只能解决一些明显的可见性问题,如下图所示,当模型进行穿插时,你分辨不出图形的前后关系,这时候,就需要逐个像素点排序(即一个一个像素点比较)
为了能够确定每个像素点的深度(像素点靠摄像机的距离),我们就需要用到深度缓冲



深度缓冲



深度缓冲将上图像素的深度描绘成不同深浅的红色,我们可以看到上图两幅画面的对比,红色越深的像素,代表它离摄像头越近,也就是它的深度越近

假设物体A,B,C的深度为5,6,7;初始化深度缓冲区中数据为无穷,如果我们先画物体A,A的深度为5,此时5<无穷,因此把A物体的颜色值写入颜色缓冲区中,同时把5写入深度缓冲区中A物体占据的区域
A渲染完成,渲染物体B时,如果有区域重复的地方,则将A与B的深度比较,因为5<6,因此B的深度不会写入屏幕当中



当然,因为我们先绘制的物品不同,物品深度存在差异,深度缓冲的方式也不尽相同,绘制效率也会不同,那么是先渲染物体A,B,C的效率高,还是渲染C,B,A的效率高呢?

答案是渲染A,B,C的顺序效率高

当我们按照C,B,A的顺序进行渲染时,明显可以看出颜色写入和深度写入的次数远多于顺序A,B,C,并且在我们的手机图形硬件中,有一个Eerly-Z的机制,它会把深度测试的时机提前,我们不再进行fragment片源着色,然后进行深度比较,而是先进行深度比较,再进行图形像素点的渲染,因此我们节省的不仅仅是颜色写入和深度写入的时间开销,而是整个像素的渲染开销
Unity中的深度

实际上在unity中,并不是用整数表示的,而是用0~1之间的浮点数表示的,在传统的图形学中对于无穷远用1.0表示,而距离摄像机最近的则用0.0表示



为什么要用0.0、1.0表示呢,这跟三维图形变换有关,我们渲染的物件,是一个一个的3D模型,像图片左上角的立方体所示,它有本身的坐标空间,通过矩阵变换,将模型放在游戏世界的每一个角,落,如上图中第3个方框所示,以摄像机视角观察,得出上图第二排第一个方框所示,经过投影变换后,每一个物体都会经过透视替换,都可以看到这些物件,它的深度值对于opengl都是介于[-1,1]之间,对于D3D都是介于[0,1]之间,如何得到值呢?

就是把能在摄像机中看到的景物经过坐标变换,而变换矩阵会确保能看到的景物深度值在[0,1]区间中



图中near表示离摄像机近的距离,far表示离摄像机远的距离

我们在靠近摄像机的位置和远离摄像机的位置各取两个距离相同的像素点,可以看到它们之间的深度是不同的

可以看出unity中越靠近的物体越精确,距离远的物体的两个像素点的深度值差很小,很难看出它的深度值差



float4 frag(vert_output In)
{
    float depth=UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture),In.uv);
    //通过_CameraDepthTexture可取到右图深度纹理
    float linear01Depth=linear01Depth(depth);
    //调用linear01Depth(depth)转换为线性的深度值
    return float4(linear01Depth,0,0,1);
                //把取到的深度值通过绿色通道linear01Depth,蓝色通道0,红色通道0,设置为不透明得到右图所示深度图
}
写在最后

更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-16 16:24 , Processed in 0.091910 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表