本专栏内容整理了GAMES101的计算机图形学课程的主要内容,作为我学习计算机图形学的一份复习备份或叫做笔记。内容中如有错误,或有其他建议,欢迎大家指出。
附上GAMES101计算机图形学课程:GAMES101: 现代计算机图形学入门正在上传…重新上传取消https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html编辑https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html
回顾前面的光栅化内容。我们可以将场景中的一个三角形渲染到屏幕上。那么让我们思考下渲染一个复杂场景的情况。必然会有非常多的三角面。从摄像机出发。到场景中的-z方向延伸。这样一个方向上会有大量的三角面。这时候就会有光线遮挡的情况出现。也就是说靠近摄像机的物体会遮挡住远离摄像机的物体。要正确渲染出这一遮挡关系就是这篇文章的主要内容。
画家算法
上方图组中,左到右的顺序是在绘画一幅风景话的一般过程。即:先绘制远处的山峰作为背景,再在绘制好的山峰前覆盖上近处的草地,再在草地上添加上树林。这样的一个先后绘制的过程中,就自动处理好了场景中的一个遮挡关系。在图形学中的一些情况下也可使用这样的一个方法。
那么,让我们使用画家算法来绘制一个普通的立方体。
正常的绘制顺序应该是 后 > 下 > 左 > 右 > 上 > 前 。但是当我们先画 上 部再画左右的情况下,就会出现绘制错误,左边的面会遮挡上面的面。所以使用画家算法需要先计算好各个面绘制的先后顺序。
Z-BUFFER
思考:如何渲染以下的场景:
可以看到,这种情况下我们采用画家算法,一个面一个面去绘制就没有办法渲染出图中的样子。因为三个三角面相互交叠。
那么在我们无法对 空间 中交错的面排出一个正确的远近顺序的情况下。我们可以对每一个 像素 上可能渲染到的那些面的那一像素区域的部分做远近顺序的排序。渲染离相机最近的那一个部分就行。
这就是 Z-Buffer。
•在每个样本(像素)存储当前最小z值 。(为了简单,我们假设Z总是正的。小z ->近,大z ->远)
在每一次渲染时我们都会得到两张图,一张是我们要的结果图像(左),一张是深度缓存图(右)。
深度缓存图只缓存每隔像素的深度信息。深度缓存图中离相机越远,颜色越浅,越近越深.
记录过程:
在上图的物体是由很多的三角面组成。每个三角面都有可能覆盖到几个像素。我们先盯着一个像素来看。在一开始我们先画了一个地板。然后我们把地板的三角面在这个像素上的深度先记录到这个像素中。然后我们把物体放上去。这时候在这个像素中物体的三角面深度 小于 地板的三角面深度,那么我们更新像素中记录的深度为这个物体的显示在这个像素上的面的深度。
实现深度缓存:
1.最开始我们记录像素中的所有像素的深度缓冲值为无限大。
2.我们渲染一个各个位置深度为5的红色三角面,因为5小于无限大,所以将红色三角面覆盖到的像素深度缓冲值设置为5.
3.场景中又出现了一个蓝色的三角面。这个三角面各个位置的深度缓冲值不相同。是一个倾斜的三角面。对比蓝色三角面覆盖到的像素的深度缓冲:蓝色三角面的覆盖的像素中,大于该像素原本记录的深度缓冲(比如前面更新的红色的深度5)情况下不更新深度缓冲,渲染结果图依旧渲染红色三角面。小于该像素原本记录的深度缓冲的则更新该像素的深度缓冲。于是我们就能得到两个三角形交叉的画面。
并且,先绘制蓝色三角形,再绘制红色三角形,结果是不变的。
存在问题:记录的深度值是浮点数,存在可能相同或者参与计算后精度丢失导致深度冲突。导致渲染前后顺序出错。