Direct3D中的光照
在游戏中,为了增强游戏的真实感和物体的立体感,可为场景增加光照。使用光照时,我们不需要指定顶点的颜色值,Direct3D会将顶点送入光照计算引擎(light engine),依据光源类型、材质以及物体表面朝向计算出每个顶点的颜色值。
1. 光照类型
在Direct3D中,光源发出的光有3种类型,分别如下:
1)环境光(Ambient Light),这种类型的光是指光源发出的光经过其他物体表面反射而到底该物体表面的光。物体没有被光源直接照射。
2)漫射光(Diffuse Light),这种类型的光沿特定方向传播,到达某一表面时将沿着各个方向均匀反射(即物理中的漫射)。
3)镜面光(Specular Light),这种类型的光沿特定方向传播,到达一个表面后将严格地反射,所以只能在某一个角度内看到高亮度照射。
2. 材质
在现实世界中,我们观察到物体的颜色实际上由该物体反射出的光的颜色决定的。因此,当一个红色的球体受到红光(只要包含红光成分即可)的照射,则呈现出红色;但是如果用蓝光照射该红色球体,则我们无法观测到这个球体,因为它吸收了全部的蓝光而不反射任何光,它对于我们而言是“黑色”的。
Direct3D通过定义物体的材质(materials)来模拟同样的现象。材质允许我们定义物体表面对各种颜色的光的反射比例。在代码中,材质用D3DMATERIAL9结构来表示,如下:
//
//D3DMATERIAL9结构
typedef struct D3DMATERIAL9{
D3DCOLORVALUE Diffuse; //对漫射光的反射率
D3DCOLORVALUE Ambient; //对环境光的反射率
D3DCOLORVALUE Specular; //对镜面光的反射率
D3DCOLORVALUE Emissive; //用于增强物体的亮度
float Power; //指定镜面高光点的锐度
} D3DMATERIAL9,*LPD3DMATERIAL9;
通常,在d3dUtility.h文件中添加如下代码以便于初始化:
//
D3DMATERIAL9 d3d::InitMtrl(D3DCOLOR a, D3DCOLOR d,
D3DCOLOR s, D3DCOLOR e, float p)
{
D3DMATERIAL9 mtrl;
mtrl.Ambient = a;
mtrl.Diffuse = d;
mtrl.Specular = s;
mtrl.Emissive = e;
mtrl.Power = p;
return mtrl;
}
namespace d3d{
D3DMATERIAL9 InitMtrl(D3DCOLOR a, D3DCOLOR d,
D3DCOLOR s, D3DCOLOR e, float p);
const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE,
WHITE, BLACK, 8.0f);
const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED,
RED, BLACK, 8.0f);
const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN,
GREEN, BLACK, 8.0f);
const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE,
BLUE, BLACK, 8.0f);
const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW,
YELLOW, BLACK, 8.0f);
}
顶点结构中不含有材质属性,但绘制时必须对材质进行设置。呼叫函数IDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9* pMaterial)即可。
3. 顶点法线
Direct3D需要确定顶点法线方向,一边确定光线到达表面的入射角。光照是对每个顶点进行计算的,所以每个顶点都需要知道法线方向。基于此,需要在顶点结构中增加表示顶点法线的属性。
4. 光源
Direct3D支持3中类型的光源:
1) 点光源(Point Lights) 该光源在世界坐标系有固定的位置,向所有方向发射光线。
2) 方向光(Directional Lights) 该光源没有位置信息,发射的光线相互平行地沿某一个特定方向传播。
3) 聚光灯(Spot Lights) 该光源有位置信息,发射的光呈锥形并沿着特定方向传播。
在代码中,用D3DLIGHT9来表示。如下:
//D3DLIGHT9结构
typedef struct D3DLIGHT9{
D3DLIGHTTYPE Type; //光源类型
D3DCOLORVALUE Diffuse; //漫射光颜色
D3DCOLORVALUE Specular; //镜面光颜色
D3DCOLORVALUE Ambient; //环境光颜色
D3DVECTOR Position; //光源在世界坐标系中的位置
D3DVECTOR Direction; //光在世界坐标系中传播的方向
float Range; //光在“消亡”前所能达到的最大光程
float Falloff; //用于聚光灯
float Attenuation0; //衰减变量,定义了光强随距离衰减的方式
float Attenuation1;
float Attenuation2;
float Theta; //用于聚光灯,指定内部锥形的圆锥角
float Phi; //用于聚光灯,指定外部锥形的圆锥角
} D3DLIGHT9, *LPD3DLIGHT;
本章结束。
————Josh 2012年10月25日