光栅化3(Rasterization)-深度缓冲(Z-buffer)
Visibility/Occusion(可见性/遮挡)
空间中多个互相遮挡的三角形,经过MVP变换与视口变换后,在光栅化过程中如何处理前后的可见性与遮挡问题。解决办法——深度缓冲(z-buffer)。
Painter's Algorithm(画家算法)
- 类比油画,先画远处的物品,再画近处的物品,覆盖之前画的内容。
- 计算机实现:定义内容的深度,按照深度进行排序(复杂度nlogn),按照排序后顺序从远到近进行绘制。存在问题:
- 定义深度不容易
- 排序有一定算力消耗
- 无法解决循环遮挡问题。无法定义深度关系和排序。
因此无法使用画家算法解决遮挡问题。
Z-Buffer (深度缓冲)
Z-buffering相较画家算法而言更加适用,因为它是按像素的深度大小进行排序。(实际上并无进行排序计算,只是通过记录的方式效果上实现了排序)
- 深度: 物品上的某一点与相机的距离,数值越大,距离相机越远。
算法主要思想:
对屏幕中的每一个像素P
- 初始定义深度值为无穷大(距离相机无限远)。
- 在对每个物体的每一个像素A进行光栅化时
,判断A的深度值(DepthA)与同一位置P(DepthP)处存储的深度值的大小关系:
- 如果比”当前已绘制像素记录的深度值“小,则绘制像素,同时更新深度值,并用DepthA更新当前DepthP的值
- 如果比”当前已绘制像素记录的深度值“大,则不绘制像素,也不操作深度值DepthP
如果应用msaa算法,则不是在一个像素内,而是在一个像素内取多个采样点,然后每一个采样点进行深度缓冲,效果会更好
结果
- 离摄像机越近,深度值越小,画面上越黑
- 离摄像机越远,深度值越大,画面上越白
例子:
- 首先定义屏幕上所有像素的深度为无穷大
- 渲染红色像素,由于初始为无穷大,所有红色像素都需要渲染。
- 渲染蓝色像素时,需要判断深度大小关系来决定是否渲染。
优点
- 算法没有进行排序,只是记录当前所绘制像素的最小值,因此算法复杂度为O(n)
- 对绘制顺序无要求。
说明: 无法处理透明物体,需要特殊处理。
总结
一个空间中的三角形:
- 1.经过MVP变换后,视锥变成了的标准立方体(Canoniacal Cube),视锥内的三角形同步变换。
- 2.再经过视口变换,立方体变换为(0,0)为原点,长宽为(width,height)的屏幕空间下的矩形,三角形同步应用变换。
- 3.最后在屏幕上的每一点进行采样,则可以将空间中的三角形在屏幕上显示出来了。
以上过程是绘制一个三角形的过程。当绘制多个三角形时,则需要处理它们的前后关系,采用”深度缓冲“处理是非常好的方法。深度缓冲其实就是对每个像素求最小值。
福利
关注公众号“羽毛不会飞”,后台回复“计算机图形学”,获得虎书第二版中文版,虎书第四版英文版,games101课件
更多
现代计算机图形学入门-L5-光栅化.1-视口变换与光栅化过程
CocosCreator3.4.2原生二次开发的正确姿势——手把手教你接SDK
关于作者
我是羽毛,一名游戏研发工程师,一名野生摄影同学。我的公众号主要分享自己的一些游戏项目开发过程中的功能总结及日常开发笔记。也希望能通过平台的交流,与更多有想法的同学交流认识,共同成长。
欢迎大家在日常开发过程中,如果觉得有需要讨论解决、分享或者探讨的内容,在公众号后台或者文章留言处给我反馈,提供写作的方向,从另一个角度也尽量让写作内容更贴近大家的需求以及痛点,在此谢谢各位同学.