光栅化补充部分
在前几章讨论过,将场景的中的坐标,压缩到一个小方块中,然后进行光栅化,当时跳过了一个环节,就是区分物体的前后(Z轴坐标)的关系,这一章来解决这个问题。
画家算法
先把远处的东西画完,再画近处的东西,就会把应该覆盖的东西覆盖掉。在某些情况下是可行的,但是在下图的情况就无法判断三个三角形的深度关系:
Z-Buffer 深度缓存
虽然我没有办法排每一个三角形的深度顺序,但是我可以排每一个像素的深度。可以在像素内保存像素所在的几何最浅的深度,离我们最近的距离。
渲染最后的成品图像的同时,会生成另外一个图像,这个图像只存任何一个像素,它所看到的几何物体的最浅的深度的信息。
这个图就叫 Z-Buffer 深度缓存
因为相机是朝向-Z的,值都是负的很讨厌,干脆就取Z的绝对值作为物体的深度
另外:RGB(0,0,0) = 黑 值越小颜色越深,越近
先把所有像素的深度值都初始化为无限大
前两个for循环:遍历任意一个三角形覆盖的任意一个像素,
如果这个深度小于之前深度缓存记录好的此像素的深度,则就替换为这个小深度。
示例图:
n个三角形,时间复杂度为O(n)
另外:Z-Buffer处理不了透明物体
还有一个坑:深度相同如何解决(Z-fighting)
着色
前几章的总结,
1,先移动摄像机位置到原点,并且朝向-Z方向,这一步是改变了所有物体的位置,使它们的相对位置不变。
2,然后压缩到一个小方块中,投影到屏幕上
3,光栅化
然后可以做出这样一张图
然后我们知道下一步的操作是 着色 Shading
着色需要计算光照,计算光照,需要的的输入有:
观察者的方向向量 (Viewer direction , v)
着色点所在表面的法向量(Surface normal , n)
光线照射的方向向量(Light direction , I)
着色点表面的一些参数(颜色,材质,反光度等)
目前着色先不考虑其它物体的存在(阴影等)
则这个物体现在被分为三个部分:高光,环境光,漫反射
漫反射
一束光打在物体的某个点上,这个点朝着四面八方反射出能量相同的光束
为什么斜着的面颜色显得要暗一些:
上图解释的很明白了,相当于面斜着的时候,单位面积接收到光的能量更小。
可以通过光线的向量(反)和接收面的法线的向量的夹角,来计算一个面的亮度
漫反射计算的公式,可以看到公式中是不考虑V的
就是在任意位置看物体的某个位置,效果都是一样的
Kd 表示这个点吸收光的系数,若Kd=1 则表示该点完全不吸收光,若=0,则无光反射出去,若表示为一个RGB的值,则会给这个点表现为某种颜色
Kd变大的示例图: