文章目录
Lec7 ~ Lec8 学习笔记:
Lecture 07 :Shading 1 (Illumination, Shading and Graphics Pipeline)
Lecture 08 :Shading 2 (Shading, Pipeline and Texture Mapping)
回顾前面我们学过的东西:
- Model:我们有了一个模型,空间中有了一个摄像机
- View:通过变换将摄像机放在原点
- Projection:三维空间的模型变换到屏幕上
- Rasterization:通过采样进行光栅化
在做完前面的步骤后,我们要开始深入了解像素以及像素的颜色。
着色的定义
-
字典定义
shading——The darkening or coloring of an illustration or diagram with parallel lines or a block of color.
用平行线或色块引起图像的明暗和颜色的不同。 -
图形学层面的定义
shading——The process of applying a material to an object.
对不同的物体应用不同的材质的过程。
基础着色模型 Blinn-Phong Reflectance Model
Blinn-Phong Reflectance Model 布林-冯反射模型可以称为着色模型,也可以称为光照模型。
着色模型主要关注如何计算物体表面每一点反射到相机的光线,从而确定该点的颜色。光照模型更侧重于描述光线与物体表面的交互方式,计算产生的颜色和亮度。他们是相互关联的,都是基于我们对光的物理特性的理解抽象出的数学模型。
Blinn-Phong光照模型的主要结构由3个分量组成:环境(Ambient)光照、漫反射(Diffuse)和镜面(Specular)光照。
Blinn-Phong光照模型是在Phong光照模型的基础上,对镜面反射做了改进。
Blinn-Phong光照模型更接近基于经验的简化模型,更严格符合物理规律的光照模型将在路径追踪部分详细了解
- 环境光照(Ambient Lighting):上图中,有些部分是背光面但是仍然有颜色,因为其接受了各种间接光照。
来自环境的反射光很复杂(后续会在路径追踪中详细研究)为了模拟这个,我们会使用一个环境光照常量,它永远会给物体一些颜色。 - 漫反射光照(Diffuse reflection):模拟光源对物体的方向性影响(Directional Impact)。
它是Blinn-Phong光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源,它就会越亮。 - 镜面光照(Specular highlights):模拟有光泽物体上面出现的高光处。
镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。
在详细了解这三组光照之前,我们还需要先定义一些东西:
在着色的过程中,目前我们的光照考虑在着色点上,着色点在局部上是一个平面,先定义这几个方向(单位向量):
- 平面上的法线n
- 观测方向v
- 光照方向l
- (表面材质)
我们只考虑每个点的着色情况,就只看它自己,不考虑其他物体的存在的影响,即不会出现阴影(shadow)
漫反射 Diffuse Reflection
光打到物体表面会均匀的散射到各个方向上,但是表面朝向和光照的夹角不一样的时候,物体的明暗程度就不一样。
光是一种能量
下图的紫色方块上的黑边代表一个着色点,光看成离散的光线,每根光线带着一样的能量。
一个着色点单位面积能接收到多少能量,表示着它能多亮。
角度不同,单位面积受到的光线“数量”不同,收到的能量也不同。
Lambert’s余弦定律定义了,着色点(面元)收到的能量与 法线和光照方向的余弦 成正比。
光强度的衰弱
我们假设光来自于一个点光源,点光源无时无刻不散发出能量,我们可以以球形的方式来看光能量的衰减。
在某时刻发出的光能量,在扩散的过程中,扩散的距离变化了,也就是变成球壳的表面积变大了,所以能量在单位点上就变得越来越少了。
(假设真空中不损耗)与点光源距离1的时候,我们定义此时的光源强度为I,传播到距离为r的时候,也就变成了I/r²。
也就是接收到的光源强度也和距离的平方成反比。
我们知道了距离,就知道了有多少光传到了这个附近,我们又根据角度知道有多少光被吸收,
进而我们可以得到漫反射的公式:
- L就是最终我们所求的漫反射光照
- 漫反射系数k表示该点对光的吸收效果,表面的材质效果
- 光源传播过程中会衰减,第二项项代表到达了着色点的光的强度
- 到达的光强并不是所有的都被接收,第三项代表接收到的光强(即入射方向和法线向量的接近程度)
- max函数的意义是,如果夹角超过90度我们就当做照不到了。
- 既然漫反射在各个方向上都是一样的,也就意味无论从哪个方向看漫反射的效果都是相等的(即公式中与观察方向无关)
着色点越亮,说明不吸收能量,能量都被反射出去 (法线方向与光照方向越平行)
着色点越暗,说明越多能量被吸收,越少被反射(法线方向与光照方向越垂直)
镜面反射/高光 Specular highlights
什么情况下能看到高光?
表面光滑的物体(镜面反射),观察方向接近镜面反射方向时能看到高光。材质不同,镜面反射有不同的夹角范围。
那么如何衡量两个向量接近呢?
在Phong模型中用观察方向和镜面反射方向做参考(但这个向量并不方便求)
而Blinn-Phong模型对这一点做了优化:用观察方向和入射方向的半程向量和着色点的法线向量,来等效判断高光。
- 镜面反射系数k通常认为是白色
- 理论上同漫反射光照一样,我们要考虑光到达的能量和吸收的能量
(但这是简化的模型,我们忽略了多少能量被吸收,主要关注我们能否看到高光) - 最后我们用半程向量和法线向量的接近程度来衡量是否能看到高光
- 对夹角余弦还要做p次幂指数,这是因为夹角余弦对高光范围容忍度太大。我们理想中的高光应该集中在一个点。
一般这个指数p会在100-200(p的影响如下图)
环境光 Ambient Lighting
在背光处,物体表面也并不是黑的,这是因为有环境光的存在。
但环境光是非常复杂的光照,在blinn-Phong模型中,我们做一个大胆的假设。将环境光简化为一个常数,即与入射方向无关,与观察方向无关,与法线方向也无关。
(详细的环境光模拟将在后续全局光照和路径追踪中探究)
合成光照
将上述3种光照,环境光照、漫反射光照、镜面高光叠加在一起,就得到了我们的Bilnn-Phong光照模型,一种简单的光照模型。
这只是一种简化的模型,实际上还存在诸多问题,我们后续会一一探索。
着色频率
在上一部分,我们深入探究了在一个着色点上应用Blinn-Phong光照模型,接下来我们要将它应用到整个场景。
这就涉及到了着色频率,即我们以什么为单位来应用着色。
- Flat shading :对每个面着色,求每个面的法线,面内颜色均匀分布
- Gouraud shading :对每个顶点着色,求顶点法线,面内颜色根据顶点颜色由插值算出
- Phong shading :对每个像素着色,先求顶点法线,由插值计算每个像素的法线,再对每个像素着色
着色频率越高效果越好?着色频率越低需要的计算量更简单?
- 实际上并不绝对。大部分情况Phong shading直观上给我们效果更好。
- 模型足够精细的情况下,用Flat shading就可以达到很好的效果。
- 但当模型过于精细,面足够多,面个数远超屏幕显示像素个数时,反而用逐像素着色计算量更小。
了解了着色频率,那么在实际操作中,我们要如何求顶点的法线?
操作很简单,将顶点关联的面的法向量做加权平均,就得到了顶点法线
如何根据顶点法线插值出像素法线?
这要用到重心坐标,会在下一章中详细介绍。
图形(实时渲染)管线
Graphics Pipeline / Real-time Render Pipeline
将我们前文中学到的所有东西矩阵变化、光栅化、着色的流程组合起来,从场景到屏幕上的一张图,即Pipeline管线。
详细流程可以结合OpenGL代码来理解
OpenGL图形渲染管线
针对着色过程,我们上文了解到了着色频率,有针对顶点着色,有针对像素着色。
渲染管线中,shading也会发生在顶点处理和片段处理两个阶段,对应了Shader的顶点着色器和片段着色器
shader是运行在gpu每个核中的(某种程度上,做渲染的大部分工作就是写shader)
在这里推荐:ShaderToy
在这个网站,我们只需要关注着色器怎么写。
随着GPU等硬件的发展,图形学研究也在快速发展。
shader作为一个运行在gpu每个核中的小程序,也不局限于顶点处理和片段处理。越来越多种类的shader也被开发出来,用于解决很多并行问题。