灯光的种类
1.环境光(Ambient Light): 这种灯光被其他所有表面反射。
2.漫反射(Diffuse Reflection) : 当它照射到一个表面时,它将在所有方向上均匀的反射。
3.镜面反射(Specular Reflection): 当它照到一个表面时,它严格地按照一个方向反射。
其中镜面反射比其他灯光要求更多的计算。它默认是被关闭的。要使用镜面光必须设置D3DRS_SPECULARENABLE渲染状态。
每一种光都是通过D3DCOLORVALUE结构或者描述灯光颜色的D3DXCOLOR来描述的。在D3DXCOLOR类中alpha的值用在描述灯光颜色时是被忽略的。
材质
在现实世界物理颜色是由物体反射的颜色决定。Direct3D通过我们定义的物体材质来模拟这些所有的现象。材质允许我们定义表面反射灯光的百分比。在代码中通过3D3MATRIAL9结构描述一个材质。
Diffuse——指定此表面反射的漫射光数量。
Ambient——指定此表面反射的环境光数量。
Specular——指定此表面反射的镜面光数量
Emissive——这个是被用来给表面添加颜色,它使得物体看起来就象是它自己发出的光一样。
Power——指定锐利的镜面高光;它的值是高光的锐利值.
顶点法线
面法线是描述多边形表面方向的一个向量顶点法线也是基于同样的概念。Direct3D需要知道顶点法线一边他能狗确定灯光照射到物体表面的角度。
为了描述顶点的顶点法线,我们必须更新原来的顶点结构:
下面是一个C函数,它通过三角形的三个顶点计算三角形的面法线。注意这个函数的三个顶点是按照顺时针方向指定的。假如不是这样,那么法线方向将是相反的
当用三角形近似表示曲面时,使用面法线作为顶点法线不能表现一个平滑的结果。一个更好的方法是找到顶点法线的平均法线。为了找到顶点v的顶点法线vn,我们找到网格模型中所有三角形的面。法线记为顶点v。vn是通过计算他们的平均面法线得到的。这里有一个例子,假设有3个三角形它们的面法线分别是n0,n1,n2,指定为顶点v。那么vn的平均法线就是:
通过改变"舞台",把顶点法线变为non-normal,这是有可能的。因此这样最好是安全的且在通过D3DRS_NORMALIZENORMALS设置渲染状态来改变"舞台"后,Direct3D从新规格化所有法线。
光源
Direct3D 支持三种类型的光源。
- 点光源
- 方向光源
- 聚光灯
在代码中一个灯光资源是通过D3DLIGHT9结构来表现的。
Type——定义灯光类型,我们能够使用下面三种类型之一:D3DLIGHT_POINT,
D3DLIGHT_SPOT, D3DLIGHT_DIRECTIONAL
Diffuse——此光源发出的漫射光颜色。
Specular——此光源发出的镜面光颜色。
Ambient——此光源发出的环境光颜色。
Position——用一个向量来描述的光源世界坐标位置。这个值对于灯光的方向是无意义的。
Direction——用一个向量来描述的光源世界坐标照射方向。这个值不能用在点光源上。
Range——灯光能够传播的最大范围。这个值不能比大。且不能用于方向光源。
Falloff——这个值只能用在聚光灯上。它定义灯光在从内圆锥到外圆锥之间的强度衰减。它的值通常设置为1.0f。
Attenuation0, Attenuation1, Attenuation2——这些衰减变量被用来定义灯光强度的传播距离衰减。它们只被用于点光源和聚光灯上。Attenuation0定义恒定衰减,Attenuation1定义线性衰减,Attenuation2定义二次衰减。适当的使用这个公式,D是代表到光源的距离,A0,A1,A2与Attenuation0,1,2相匹配。
Theta——只用于聚光灯;指定内圆锥的角度,单位是弧度。
Phi——只用于聚光灯;指定外圆锥的角度,单位是弧度。
就象初始化D3DMATERIAL9结构一样,初始化D3DLIGHT9结构是一件单调乏味的工作。我们添加下面的函数到d3dUtility.h/cpp文件中用于初始化简单灯光。
在把D3DLIGHT9初始化好以后,我们需要用Direct3D内在支持的灯光来注册。就象这样做:一旦灯光注册了,我们就能使用下面的列举的例子来开或关灯光了: