DX灯光与材质

来源:互联网 发布:流程图软件visio2016 编辑:程序博客网 时间:2024/04/28 22:24

 因为灯光与材质经常在一起使用,所以一起讲。

一 基本概念

在前面的例程中,通过对顶点颜色进行插值来获取实体表面的颜色,这种简化的计算模型无法如实地反映真实世界。在自然界中,我们所看到的一切都是由光线产生的:光由光源出发,沿直线传播;当光线遇到物体时,一部分被吸收,剩余的被反射,该过程反复进行,直至光线能量耗尽,或者被人眼接收从而产生视觉。
在Direct3D中,用灯光和材质来模拟这个过程。灯光用于照亮实体,可分为环境光(Ambient Light)和直射光(Direct Light):前者均匀充满整个场景,为所有实体提供一个恒定的照明,没有方向性;后者一般由光源产生,具有方向性。材质则定义了实体表面对光线的反射属性。
Direct3D用结构D3DCOLORVALUE描述直射光和材质的颜色,它有4个浮点分量,分别代表红、绿、蓝、Alpha混合,正常取值范围0.0-1.0。其中Alpha混合用来产生透明效果,仅用于材质:0.0表示完全透明;1.0为不透明。
环境光颜色用一个4字节的整数D3DCOLOR描述,每个字节依次代表红、绿、蓝、Alpha混合,取值范围0-255,可以借助宏D3DCOLOR_RGBA来简化计算。和直射光一样,环境光也不使用Alpha混合。
虽然灯光和材质都有颜色,但其含义并不相同。灯光的颜色定义了光线中三原色的“数量”,红=绿=蓝=1.0为白光,都取0.0表示没有光。材质的颜色代表了在光线发生反射时,三原色被反射的“数量”,红=绿=蓝=Alpha=1.0表示所有光线都被反射,也就是说,材质看上去为白色,而红=绿=0.0,蓝=Alpha=1.0则表示只有蓝光被反射,即材质为蓝色。

二 灯光

1 光照计算模型

环境光(Ambient Light):没有方向和光源,但有强度和颜色,且充满整个场景。开启方法:g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );

漫反射(Diffuse Light):漫反射是分散的,但又方向

镜面反射(Specular Light ):它是相对于漫射光来说的,它根本不会分散,你可以用它在对象上创建高亮

 

2 光的类型

点光源:电光源的一个很好的例子就是灯泡,它没有方向(因为向全部方向发出),但是有颜色、范围和衰减

平行光:直射光具有颜色,没有位置。举个例子应该是太阳,场景里的所有对象都会从同样的方向接收到同样的光,直射光也没有范围和衰减。

聚和光:手电筒是聚光灯的好例子,它具有位置、方向、范围、发光内径和发光外径属性,光照强度还会随距离而衰减

 

注意:光照计算模型和光的类型是不同的两个概念

 

3 设置灯光

 

  1. typedef struct _D3DLIGHT9 {
  2. D3DLIGHTTYPE Type; //类型:只能是点光源、平行光或聚光灯
  3. D3DCOLORVALUE Diffuse; //灯光的漫反射颜色
  4. D3DCOLORVALUE Specular; //灯光的镜面反射颜色
  5. D3DCOLORVALUE Ambient; //灯光的环境光颜色
  6. D3DVECTOR Position; //光源在世界坐标系的位置
  7. D3DVECTOR Direction; //灯光的方向,建议使用单位矢量
  8. float Range; //灯光的作用范围
  9. float Falloff; //聚光灯内核到外核的衰减系数,通常取1.0,表示均匀过渡
  10. float Attenuation0; //距离衰减系数之一:通常取0.0
  11. float Attenuation1; //距离衰减系数之二:通常取一个大于0的常数
  12. float Attenuation2; //距离衰减系数之三:通常取0.0
  13. float Theta; //聚光灯的内核大小
  14. float Phi; //聚光灯的外核大小
  15. } D3DLIGHT9;

例:

  1.     D3DXVECTOR3 vecDir;
  2.     D3DLIGHT9 light;
  3.     ZeroMemory( &light, sizeof(D3DLIGHT9) );
  4.     light.Type       = D3DLIGHT_DIRECTIONAL;
  5.     light.Diffuse.r  = 1.0f;
  6.     light.Diffuse.g  = 1.0f;
  7.     light.Diffuse.b  = 1.0f;
  8.     vecDir = D3DXVECTOR3(cosf(timeGetTime()/350.0f),
  9.                          1.0f,
  10.                          sinf(timeGetTime()/350.0f) );
  11.     D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
  12.     light.Range       = 1000.0f;
  13.     g_pd3dDevice->SetLight( 0, &light );
  14.     g_pd3dDevice->LightEnable( 0, TRUE );

 

 

三 材质

前面已经提过,材质用于描述实体的反光性能,Direct3D使用结构D3DMATERIAL9保存材质,它有如下成员:
typedef struct _D3DMATERIAL9 {
D3DCOLORVALUE Diffuse; //材质的漫反射颜色
D3DCOLORVALUE Ambient; //材质的环境光颜色
D3DCOLORVALUE Specular; //材质的镜面反射颜色
D3DCOLORVALUE Emissive; //材质的发射颜色
float Power; //材质的镜面反射强度
} D3DMATERIAL9;
漫反射颜色定义了材质对灯光中漫反射分量的反射性能,环境光颜色定义了材质对环境光照的反射性能,这二者结合在一起,决定了实体的外观颜色。在编程中,它们通常取相同的值。

 

例:

  1.     D3DMATERIAL9 mtrl;
  2.     ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
  3.     mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
  4.     mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
  5.     mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
  6.     mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
  7.     g_pd3dDevice->SetMaterial( &mtrl );

上面表示RG两种颜色会被完全反射出去。

 

原创粉丝点击