前言
在学习光栅化时,我们说有个三角形,通过向量的叉乘来判断哪些像素在三角形内,然后将这些像素填充上三角形的颜色。但是如果三角形里不是简单的纯色,而是渐变色或者带花纹图案的,该怎么处理?
此外前面讲的颜色都是三角形本身带有的颜色,然而事实上我们一般拍摄物体时都是在有光照条件下拍摄的,那么当光线照射到一个三角形时,会导致产生不同的亮度。那么针对这样的情况,我们又该怎么显示在像素上呢?
还有就是物体的材质不同时应该怎么显示,例如同样一个黄色的小球要显示,小球是金属做的还是塑料做的或者其他材质做的,显示的结果肯定也都不一样。
举个例子,例如下图:
图中的杯子或者盘子本身肯定是纯白色的,我们可以当做它们的表面由不同的白色三角形组成。但是我们可以发现渲染出来后,这些杯子盘子的各个部位在图片上并全是一模一样的颜色,而是有明有暗,这便是光照的影响。如果杯子不是陶瓷的,而是磨砂的杯子,显示出来的肯定又会是另外的样子,这就是材质的影响。除此之外,我们还可以发现更复杂的现象,杯子上会倒映出其他物体的样子,那么这又应该怎么实现?
着色(Shading)
假设我们现在场景中有一堆立方体。那么在前面的学习中,我们可以把它们通过视图,投影,视口变换,摆到图像的对应位置上。然后通过光栅化把它们填充到每个像素上。那么我们就可以得到如下一幅图像:
注:如果使用过unity,我们知道每个cube会有一个对应的material,然后每个material里会预设置一些颜色,光栅化时三角形的颜色就可以从中获得。
看着怪怪的,对不对,但是好像又没错,每个立方体确实每个面都是这个颜色啊。这就是因为现实生活中往往存在着不同的光照,而光照就会很大程度的影响到我们看到的效果。
假设在上面的结果中,我们加上光照效果,会怎么样呢?如下图,看着是不是真实了很多。
因此通俗来说,我们要使我们最终得到的图像和所看见或者所拍摄的东西,每个位置所对应的颜色都相同,即为每个像素填充上正确的颜色,这个过程我们就称之为着色。同时着色不仅仅只考虑物体本身的颜色,还要考虑物体的材质,环境的光照等等。
在图形学中,我们可以把着色定义为在不同物体上应用不同材质的过程。因为不同材质和光产生的相互作用就会不同,例如反射率,折射等。和光的不同作用就会显示出不同的结果,因为我们知道我们能看见物体都是因为光线进入了人眼。
一些相关知识点
想要更好的理解光照和物体的作用,来模拟出相对真实的效果,我们需要知道一些相关的知识,在这里做一些介绍。
着色点(Shading Point)
对于整个物体受到光照的结果,我们依旧进行细分,将其理解成物体表面每一块极小区域受到光照的结果,这一小块区域我们称之为Shading Point。因为是极小一块区域,因此即使物体表面是曲面,我们也可以把一个着色点当作是一个平面,如下图:
根据每个着色点,我们可以有如下一些定义:
- 既然是平面,那么我们就可以定义其对应的法线(图中的 n向量)。
- 光源对应着色点的方向(图中的 l向量,光源位置减去着色点位置,然后归一化下即可),若多个光源,则每个光源有一个对应的方向。
- 摄像机/人眼对应着色点的方向(图中的 v向量,摄像机位置减去着色点位置,然后归一化)。
- 表面的一些属性,例如颜色(color),亮度(shininess)等等。
注:上面提到的三个向量代表的都是方向,因此它们都为单位向量。
同时我们在考虑着色时,不需要考虑阴影,即不用考虑某个着色点的光照被其他物体遮挡的问题。我们只考虑该着色点本身的各个属性即可,这也是着色的局部性,因此着色过程中也不会产生阴影。至于阴影是怎么实现的,后续我们再介绍。
物体为什么有颜色?
通过物理的学习,我们知道可见光是由不同颜色的光波所组成的,物体之所以有颜色是因为对光线不同程度的吸收所导致的。例如物体把所有光线都吸收了,那么它就是黑色,反之如果都不吸收,那么就是白色,而红色就是吸收了除了红色以为所有的光。
因此我们可以假设着色点有一个属性,我们可以通过调整这个属性来达到显示不同的颜色,即吸收或反射哪些光。
Lambert's 余弦定率
我们知道光是有能量的,同时物体也会吸收这些能量,例如光照下东西会变热,四季变换也是这个原理。
那么我们来看下不同方向的光照对于着色点(着色点面积不变)的影响,如下图:
假设