Games101 第六章 Shading(着色)
Blinn-Phong Reflectance Model(布林-冯反射模型)
布林-冯反射模型将着色区域分为三个部分
分别为:高光,漫反射,环境光。
反射模型有三部分组成
- 反射参数:用来显示颜色
- 光照能量:到达这一点的光的能量
- 反射夹角:用来衡量光的发射量
我们可以从这个图中看到着色亮度和光照角度有关联。
该模型中假设在以光源为中心的球壳上能量相等。
高光反射
可以看到模型规定在对称方向的某个范围内都是高光。
我们在计算高光时用到了一个技巧,我们求的是平面法线(n)与出射入射方向的中线(h)的偏差,原因是计算更加方便。
说明一下p:这是用来控制高光区域大小的参数,原理如下:
由此看出,p的参数越大,高光允许的范围就越小。
漫反射区域
基本不用解释了,值得注意的是着色只与光照方向,光照距离与平面的法线有关,与观察方向与观察距离无关。
环境光照
添加恒定颜色并补充阴影。
效果
着色频率
Flat shading(三角形着色)
这种着色的方式是逐三角形着色
Gouraud shading(顶点着色)
分为两步:
- 第一步只对顶点着色(意味着要求顶点法线)
- 根据每个顶点组成三角形,用三个顶点的颜色对三角形内部进行插值。
Phong shading(逐像素着色)
Phong和Blinn-Phong Reflectance Model中的Phong是一个人,但这是两个不同的成果。
依然分为两步:
- 求出三角形顶点法线(和上面一样)
- 用插值的方法求出三角形内每个像素的法线,然后依次着色。
效果
定义顶点的法向量
- 通过几何体本身的几何性质定义
- 通过周围面的法向量的定义
图形学渲染管线
Shader Programs(着色器)
着色器定义了对每一个像素是如何着色的,修改这个程序,所有点的着色都会改变。
如上图所示,程序定义了法线,纹理,光照方向等信息,并且给出了如何计算这些信息得到颜色。
纹理映射
纹理一般会定义在一张正方形的矩阵上,而三维空间中表面多是曲面,因此,纹理无法无损的从二维空间映射到三维空间,其中必定有压缩,拉伸等问题。
一般的纹理映射方法是只建立三维空间中的点与二维平面上的点的映射关系(显示映射),而其他地方则用插值解决。
而我们是实现显示映射的方法是使用重心坐标。
重心坐标
重心坐标是用三角形的顶点来表示内部任意一点的方法。
如何计算坐标:
使用纹理
- 找出三维空间中投影到像素中心的点的重心坐标
- 将该重心坐标作用到三角形的三个顶点的纹理坐标上
- 去其对应纹理坐标位置纹理的颜色
问题太小时怎么办
双线性插值
在两个方向上分别做了线性插值,因此时双线性插值
当纹理太大了怎么办
在远处明显出现了摩尔纹(对高频信号进行了低采样)
提高采样率当然能解决问题,但这样的话消耗就太大了。
Mipmap
我们为纹理设计分辨率不同的层,用在距离不同的地方进行查询。
可以计算出,多消耗的存储空间为原来的1/3
每一层称为D
如何查询在那一层
每个像素查询它上方和右边的像素在纹理中的位置,比较这两个位置距离自己在纹理坐标中的距离,最大的哪个就是L。然后用L计算D(比如L = 4,像素的边扩大了4倍,即扩张了两次,所以在第2层)
为了使过度更加平滑,我们要使用三线性插值。
即对相邻两层的结果再进行插值(按距离)
结果出现了连续的贴图变化,但再远处又出现了问题
各向异性
我们发现不同位置像素的纹理映射成了不同的形状。但我们之前的方法总是只能采样一个正方形内的纹理。
由此我们引入各项异性的mipmap,能将正方形的像素区域映射为不同的形状。