文章目录
-
- 1 照明和阴影
-
- 最基础的模型:Blinn-Phong反射模型
-
- 漫反射
- 高光
- 环境光
- 最终的Blinn-Phong 模型
- 着色频率
-
- 如何知道逐顶点的法线是什么?
当这些物体都变成三角形之后,变成屏幕上的一个个像素点之后,这些像素的值和颜色应该是什么呢?这个就是着色的功能。下一步操作为着色。
挪动一下光源后,物体并没有发生变化,但是物体的颜色却发生了变化。这个问题应该如何解决,就是着色的作用。
这门课中着色的定义:对不同的物体应用不同的材质这样一个过程。
因为不同的材质肯定和光线的相互作用有不同的方法,可通过这种不同的表现形式来展示材质的特性。
1 照明和阴影
最基础的模型:Blinn-Phong反射模型
Blinn-Phong 模型是一个经验模型,并不是一个完全符合物理规律的模型。
(下图的所有向量都是指的单位向量。)
- 镜面高光 Specular:一束光打到比较光滑的表面上,这束光就会在这镜面反射的附近被反射出去。
- 漫反射光 Diffuse:一束光打到比较粗糙的平面上,光会向四面八方反射出去。
- 环境光 Ambient:并不是一种直接光照,是间接光照。通过四面八方的物体反射得到的光。
我们此处考虑的这个 shading point,就只考虑这个点和其他的几个不同的方向,不考虑这个点是否在阴影内。考虑这个点的着色情况就只看它自己,不考虑其他物体的存在。
着色有局部性。着色可以看到物体的明暗变化,但是看不到阴影。阴影如何生成稍后再讲~
漫反射
- 知道了有多少能量会被传播到当前的 shading point
光线在传播的过程中,在单位面积的情况下,在任何一个位置上所能接收到的能量和光线传播的距离是成平方反比的。(也就是,光线传播的距离越长,单位面积上所接收到的能量是逐步衰减的。)
- 也知道了有多少能量在这个 shading point 上会被吸收
Lambert 余弦定律
“接收到的能量”和“光照方向与法线方向之间夹角的余弦”是成正比的。
将以上两者结合到一起,就可以知道 diffuse 的表示方法了。

shading point 到点光源的距离为 r;点光源到单位距离上的能量强度是 I,那么我们就能够知道这个点光源通过 r 这个距离传播到shading point的能量有多少。能量到达了物体之后会被物体表面吸收,而吸收多少取决于Lambert 余弦定理。最终计算的结果 L d L_d Ld就表示我们可以看到有多少能量,对应的就是物体的明暗。
有一个地方需要注意的是,$ max(0, n · I) $ 这里为什么要做一个点乘?表示的是当点乘结果是负值的时候,表示光从下面打过来才可能出现,此时并没有什么物理意义,就把值取为 0。
shading point 为什么会有颜色?因为它自己本身会吸收一部分能量,反射出去的是它不吸收的能量。由于不同的点对能量有不同的吸收率,定义一个系数 K d K_d Kd 来表示这个点本身吸收多少。(当 K d = 1 K_d = 1 Kd=1 意味着不吸收任何能量, K d = 0 K_d = 0 Kd=0 意味着吸收了所有的能量,我们看到的是个黑的。)不同的漫反射系数 K d K_d Kd 决定了它的亮度和颜色。
漫反射光打到shading point 上去,会被均匀地反射到各个方向上去,就意味着我们不管从哪个方向上观察这个点,所看到的结果应该是一样的。(因为能量是被均匀反射出去的。) 最终看到的结果和 v (观察方向)完全没有关系。
高光
什么情况下看得到高光?比较光滑的物体的反射都具有一定的特性,反射方向非常接近镜面反射的方向。**当观察的方向和镜面反射方向接近的时候,就能看到高光了,**其他时候看不到高光。
v 和 R 接近,就说明了 h 和 n 接近。它们两个有一定关系。可通过衡量 n 和 h 是否接近来判断我们是否可以看到高光。如何衡量两个向量是否接近呢?点乘。两个向量很接近的话,那么点乘结果接近 1,离得很远的话,点乘结果接近 0。
多少能量到达了shading point 还是和上面一样考虑。但是没有考虑有多少能量被吸收了,因为它毕竟还是一个经验模型,它在这里没有考虑这部分。
为什么要用半程向量和法线来近似 R 和 v 是否接近呢(这个是 blinn-Phong 模型)?为什么不直接计算 r 和 v 的夹角是否接近(这个就是 phong 模型。 )?这是一个改进,因为反射向量 R 不好计算。近似可以简化很多的计算量。
环境光
环境光来自四面八方,强度都是相同的。这里的环境光其实是一个常数。它的作用就是保证物体并非完全是黑的。(环境光是间接光照,计算起来十分复杂,这里用一个合理的常数来近似代替实际的环境光。)
最终的Blinn-Phong 模型
下一步就是对所有的像素点做一个着色操作。
着色频率
着色频率指着色要应用在哪些点上。
三种着色模型:
- Flat shading
- 每一个三角形是一个平面,对每个三角形的面求出一条法线。(对三角形的两个边做个叉乘即可求得)
- 不适用于光滑表面。
- Gouraud shading
- 对每个三角形的每个顶点求各自法线,求得之后做一次着色,那么每个顶点就有颜色了,三角形内部的颜色就可通过插值计算出来。
- 如何对顶点求法线?答案在这里~
- Phong shading
- 对每个三角形的每个顶点求各自法线后,可以对三角形内部的每个像素都插值出一个独特的法线方向。对每个像素进行一次着色,就可以得到一个相对比较好的结果。
- 区分一个概念,之前的是Phong着色模型,这个是指的着色频率,是不一样的。
由下图可以看出,当模型足够复杂时,其实可使用相对简单的着色模型,因为效果差不多。这时用更小的开销,得到近乎一样的效果。因此着色频率取决于面、点出现的频率,当面出现的频率已经很高的时候,就可以用相对简单的着色模型。
如何知道逐顶点的法线是什么?
理想情况:知道它近似的是什么形状,因此直接求得法线。比如近似的是球,那么直接连接这个点和球心就好了,延长线就是该点的法线。
很多三角形往往会共用一个顶点,那么这个顶点的法线可以认为是这相邻所有面的法线的平均。做加权的平均,相邻三角形面积越大认为它对顶点法线的贡献的越大。
又如何真正地去定义一个逐像素的法线呢?
已知两顶点的法线,如何插值出中间的法线呢?这个就需要用到重心坐标。(稍后会讲到。)