第14章 绘制出质感的世界——光照与材质
1. 光照与光源
在Direct3D中的光源类型和光照类型是不同的两个概念,光照模型描述的是光线的反射特征,而光源类型主要强调的是能够产生这些光照模型的方式以及光线的位置,方向,强度等特征。
四大光照类型
环境光:基于整个自然界环境的整体亮度,称为环境光或者背景光,没有位置或者方向上的特征,只有一个颜色亮度值,不会衰减,在所有方向和所有物体表面上投射的环境光的数量是恒定不变的(有点像我们白天的自然光)。在Direc3D中设置环境光可以直接使用setRenderState方法:
pd3Device->setRenderState(D3DRS_AMBIENT, D3DCOLOR_XRB(36, 36, 36));
第一个参数代表环境光的设置,第二个参数填一个颜色值就可以了。
漫反射光:太阳的直射,日光灯的照射都可以看成漫反射的近似。这种类型的光沿着特定的方向传播。
镜面反射光:沿着特定的方向传播,当此类光到达一个表面时,将严格地沿着另一个方向反射,从而形成只能在一个角度范围内才能观察到的高亮度照射。这种光照模型模拟了从光滑发光面如镜子等材料来进行光线反射的情形。如果移动一个光源的话,就会发现镜面亮光的变化,这意味着镜面反射取决于观察者的角度。漫反射与视觉无关,而镜面反射与视觉相关。
如果想启用镜面反射的话,可以使用如下代码,设置相应的渲染状态即可:
pd3Device->setRenderState(D3DRS_SPECULARENABLE, true);
自发光:就是对象自己发出的光,根据通过对象的自发光材质来实现。
三大光源类型:点光源,方向光和聚光灯。
在Direct3D 9.0c中,涉及到光源的结构体是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;
其中Falloff,Theta和Phi用于聚光灯类型,也就是说把第一个参数设为D3DLIGHT_SPOT聚光灯类型的时候,这3个参数才有意义。Attenuation0,Attenuation1,Attenuation2是衰减系数,定义了光强睡着距离衰减的方式。在Direct3D中使用光照,就是用D3DLIGHT9结构体实例化一个具体的光源类型,然后对这个结构体的参数进行赋值,赋值完成后调用IDirect3DDevice9接口的SetLight方法设置光源,最后调用IDirect3DDevice9接口的LightEnable方法启用光照就可以了。
SetLight方法,用于设置光源:
HRESULT SetLight( [in] DWORD Index, //取值与0~7之间,表示选择第1~8个光源 [in] const D3DLIGHT9 *pLight //指向D3DLIGHT9结构体的指针 );
然后是LightEnable方法,用于启用光照:
HRESULT LightEnable( [in] DWORD LightIndex, //取值于0~7之间,表示选择第1~8个光源 [in] BOOL bEnable //表示启用或者禁用第一个参数里面指定的光照 );
关于3种类型的光源:点光源,方向光和聚光灯。需要进一步说明的是聚光灯。聚光灯发出的光由一个明亮的内椎体和一大点的外锥体组成。内椎体中的光最亮,内椎体到外椎体外围的光强主键减弱。
之前关于聚光灯的3个参数:Falloff,Theta和Phi,这3个属性共同来控制光强从内椎体到外椎体衰减的规律。
而Falloff用于控制光强如何从内椎体的外侧向外椎体的内侧减弱的,通常设置为1.0f,使光线在两个圆锥间平滑地减弱。
2. 材质
对于光照计算来说,光照和材质两者缺一不可。物体表面的材质属性决定了它能反射什么颜色的光线以及能反射多少。在Direct3D中,关于物体表面的材质属性是由一个结构体D3DMATERIAL9来负责管理: