在三维图形程序中使用光照效果能够有效地增强场景的真实感。在Direct3D中,通过计算场景中的光线和物体表面材质反射光线颜色的数学交互,可使光线模型接近于真实世界的照明系统。
光照计算模型
在真实世界中,光线在到达眼睛之前经过了物体表面的多次反射,每次反射时,物体表面都会吸收一些光,有些被随机反射扩散出去,其余的到达下一个物体的表面或眼睛。真实世界中光线反射的效果就是光线跟踪算法需要模拟实现的。尽管光线跟踪算法能够创建非常逼真的与自然界中观察到极为相似的景象,但是还没有实时程序能够完成这些运算。考虑到实时渲染的需要,Direct3D使用更简单的方法进行光照计算。Direct3D光照计算模型包括4种:环境光、漫反射光、镜面反射光和自发光。它们的结合能灵活高效地解决三维图形程序中的光照问题。
1、环境光
一个物体即使没有直接被光源照射,但只要有光线通过其他物体的折射、反射到达该物体,它也能被看见。在基本光照模型中,可以在一个场景中设置一个基准光亮度,可简单地模拟一种从不同物体表面所产生的反射光的统一照明,称为环境光(ambient
light)或背景光。环境光没有位置或方向上的特征,只有一个颜色亮度值,而且不会衰减,所以在所有方向和所有物体表面上投射的环境光的数量是恒定不变的。
在Direct3D中可以通过设置渲染状态为整个场景添加环境光。方法很简单,具体的代码如下:
g_device->SetRenderState(D3DRS_AMBIENT,
D3DCOLOR_X#404040);
2、漫反射
漫反射在现实生活中最为普遍,太阳的直射、日光灯的照射都可以用漫反射光照模型来近似。不同于环境光,漫反射光的空间位置和方向对物体的照明有很大的影响。图形系统中物体表面顶点P的漫反射颜色值Idiffuse的计算公式为:
Idiffuse = k * Ilight * cosθ
其中k为物体表面材质的反射系数,Ilight为灯光颜色,θ为物体表面顶点指向光源位置的方向向量L和顶点法线N之间的夹角。如果L和N为单位向量,由几何知识可知,cosθ等于L和N的点积,所以Idiffuse的计算公式可变为:
Idifffuse = k * Ilight * (L . N)
在Direct3D图形系统中,物体表面顶点处的漫反射颜色值就是利用上式计算的,需要说明的是,在Direct3D中颜色值是由红、绿、蓝三个颜色分量表示,在具体计算时也是按照三个分量分别计算。
3、镜面反射
当观察金属物品或玻璃制品的表面时,改变观察点的位置,可以发现玻璃杯表面的亮度也在发生变化,这种现象往往发生在光滑物体表面,称之为镜面反射。物体表面顶点的镜面反射颜色值的计算方法由下图所示:
设物体表面顶点指向观察点的单位向量为V,反射光线为R,R和V之间的夹角为θ,顶点P的镜面反射颜色值可由下式近似计算:
Ispecular = Ks * Ilight * (cosθ)n
= Ks * Ilight * (V . R)n
其中,Ks和n为物体表面材质的镜面反射系数。
从上面的计算公式中不难看出,镜面反射的计算量比较大,因此在默认状态下,Direct3D不对物体进行镜面反射计算,如果要激活Direct3D镜面反射光照计算,需要设置相关的渲染状态,代码如下:
g_device->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
4、自发光
自发光是指对象自己发出的光。自发光其实就是通过对象的自发光材质实现的。用结构D3DMATERIAL9的成员Emissive描述自发光的颜色和透明度。自发光可以影响一个对象的颜色,例如通过设置灰暗材质的自发光颜色属性可以使其变得明亮一点。可以使用材质的自发光属性实现发光的对象,而不用在场景内添加灯光,从而缩小了计算量。例如,可以通过具有蓝色自发光属性的材质实现一块蓝色水晶,而不在场景内添加其他灯光。
用自发光属性创建的材质并不发射出能被场景内其他对象反射的光,也就是说,它发出的光不参与光运算。为了实现反射光,必须在场景内添加额外的灯光。
5、对光照计算模型的说明
环境光所实现的实际上是一个定值,没有方向属性,所以它使物体对象的所有像素都呈现同样的颜色。它能很快完成计算,但这时的物体看上去不真实。
漫反射由光的方向和物体表面的法向量决定。如果改变了光的方向或者物体表面的法向量,物体表面的漫反射值就发生变化。因为每个物体顶点都不相同,所以它的计算时间会较长,使用这种光照计算模型的优点在于用它渲染物体时能够体现出物体的三维深度。
镜面反射发生在光滑物体表面,它比漫反射光更强烈并沿着对象表面迅速衰减,它的计算时间比漫反射更长,但优点在于它为表面添加了重要的细节。
现实中的光照效果可以通过这些光照类型进行近似模拟。通过选择合适的光照计算模型,能使最终显示的图形具有逼近真实世界景物的真实感,同时保持图形程序的执行效率。在图形程序中对物体顶点进行光照计算时,具体采用哪种或哪几种光照计算模型,是由物体表面材质决定的。这也和实际情况比较吻合,如果物体表面粗糙,则当光线照射到物体上时,发生漫反射;如果物体表面很光滑,光线照射到物体上时将发生镜面反射。
环境光、自发光、漫反射光的计算结果作为顶点的漫反射颜色输出,镜面反射光的计算结果作为顶点的镜面反射光颜色输出。