本页目录

【GAMES101】Shading

Blinn-Phong光照模型

将环境光分为:

漫反射(diffuse reflection):一根光线打过来,反射到四面八方

高光(specular highlights):一根光线打过来,反射方向与镜面反射方向相近

环境光(ambient lighting):环境中经过多次反射叠加的结果,认为是常量

模型定义和说明

img

着色模型考虑一个点,在这个点处小范围表面被近似看作平面:

模型的输入(向量均为单位向量):

观察方向

法线方向

光照方向

这一点处表面的固有性质(颜色等)

img

着色是局部的,计算每一点的着色结果时,不会考虑其他物体的存在,不会产生影子。

例如红色框部分是有些反直觉的。

漫反射

光线衰减

我们认为点光源发出的光的能量集中在一个球壳上,根据能量守恒,光强应与距离平方成反比。

如果在与中心距离处光强为,则在与中心距离处光强为

朗伯着色模型

img

考虑一个点的着色,其漫反射部分可以接收到的光线占光源的比例为

漫反射部分的计算公式为:

其中的是漫反射常量,表示着色点对能量的吸收率,取决于物体材质。如果定义为具有3个分量的常向量,则可以表示不同的颜色。

当光照方向和法线方向余弦值为负数的时候,认为光线不可到达此点,按考虑。

注意到漫反射是与观察方向无关的。

高光

高光的反射方向是接近镜面反射方向的。

img

我们观察到:如果反射方向与观察方向相近时,半程向量应该与法线方向也相近,是归一化后的观察方向与光照方向的和:

高光部分的计算公式为:

其中的通常接近

指数使得向量夹角增大时,使快速衰减。

环境光

img

我们假设在每一点处,来自环境中各处散射叠加而成的光强是相等的

环境光部分的计算公式为:

结果

img

最后的计算结果为:

纹理映射

纹理映射希望能够定义一个物体上面任意一点的不同属性(等)。认为3D物体的表面是一张2D的图,纹理映射需要建立起3D物体表面上一点与纹理表面上的一点的一一对应关系。

img

通常都取值。模型的每一个顶点都对应一个

纹理表面是如何得到的?美工画的!

重心坐标

imgimg

三角形所在平面上任何一点都可以用三角形顶点来表示:

如果在三角形内部,则有均非负。

时,是三角形重心。

重心坐标的作用是给三角形内部任意一点线性插值。可能是位置、颜色、深度等等。

重心坐标插值并不具有投影不变性。

利用重心坐标插值,就可以查询任意一点对应的纹理

纹理的应用

凹凸贴图

img

纹理不止可以表示颜色,也可以表示物体的模型。例如,一个球的表达是非常容易的,通常几百个三角形就能很好的描述,但是左图所示的表面有复杂纹理的球体如果用三角形表示,则很麻烦。可以用像描述表面纹理一样的方法去描述每一点的相对高度。

img

凹凸贴图(bump mapping)用一张灰度图存储高度的相对变化值。

法线贴图

法线贴图(normal mapping)直接将法线存储在贴图中。

img

如图,改变后的法线方向垂直于,应为。不过,上述是在平面上的简单示意图,实际情况下纹理是一个平面,计算改变后的法线方向需要:

以原本的法线为建立一个局部坐标系

计算

归一化即为所求

位移贴图

位移贴图(displacement mapping)会实际上真的移动顶点!

img

由于凹凸贴图和法线贴图(左图)并不会真正的改变顶点,在一些细节上会与位移贴图(右图)有出入,例如物体的边缘和凸起部分的阴影。

位移贴图要求原图三角形的定义足够细致,也就是原物体顶点的采样率要高于凹凸纹理的采样率,否则就没办法通过移动顶点来实现纹理(就像很低分辨率的屏幕上不能很好的显示出高分辨率的图片)。

3D纹理

img

之前讨论的纹理都是2D的,但纹理也可以定义在3D空间中,例如上图的纹理是定义在3D空间中的噪声,空间中每一个点都有值(把花瓶切开,其内部也是有纹理的)。

图中使用的是柏林噪声