反射照明 (Direct3D 9)

对反射建模要求系统不仅知道光在哪个方向移动,而且知道观众眼睛的方向。 系统采用了简化版的 Phong 镜面反射模型,这种模型使用中间矢量,可获得近似于镜面反射的强度。

默认的照明状态不会计算反射高光。 若要启用反射照明,请务必将D3DRS_SPECULARENABLE设置为 TRUE

高光照明公式

反射照明按以下公式描述:

反射照明 = Cs * sum[Ls * (N ·H) P * Atten * Spot]

 

下表标识了变量及其类型和范围。

参数 默认值 类型 说明
Cₛ (0,0,0,0) D3DCOLORVALUE 反射颜色。
sum 空值 空值 每束光线的反射组件的总和。
N 空值 D3DVECTOR 顶点法线。
H 空值 D3DVECTOR 中间矢量。 请参阅有关中间矢量的部分。
P 0.0 FLOAT 镜面反射能量。 范围为 0 至正无穷
Lₛ (0,0,0,0) D3DCOLORVALUE 光线反射颜色。
Atten 空值 FLOAT 灯光衰减值。 请参阅 direct3D 9) (衰减和聚焦因子
现付 空值 FLOAT 聚焦因素。 请参阅 direct3D 9) (衰减和聚焦因子

 

Cₛ 的值为:

if(SPECULARMATERIALSOURCE == D3DMCS_COLOR1)
  C = color1;
  • 顶点颜色 1,如果反射材料源D3DMCS_COLOR1,并在顶点声明中提供第一个顶点颜色。
  • 顶点颜色 2,如果反射材料源D3DMCS_COLOR2,并在顶点声明中提供第二个顶点颜色。
  • 材料反射颜色

注意

如果使用了任一反射材料源选项,但未提供顶点颜色,则使用材料反射颜色。

 

单独处理和内插所有灯光后,将反射组件的范围限制为 0 至 255。

中间向量

中间向量 (H) 存在于以下两个向量中间:从物体顶点到光源的向量,及从物体顶点到相机位置的向量。 Direct3D 提供两种计算中间向量的方式。 当D3DRS_LOCALVIEWER设置为 TRUE 时,系统将使用相机的位置、顶点的位置以及光线的方向矢量来计算中途矢量。 下面的公式对此进行了说明。

H = norm (norm (Cp - Vp) + Ldir)

 

参数 默认值 类型 说明
Cₚ 空值 D3DVECTOR 相机位置。
Vₚ 空值 D3DVECTOR 顶点位置。
Ldir 空值 D3DVECTOR 从顶点位置到光线位置的方向矢量。

 

以这种方式确定中间矢量可能是计算密集型操作。 或者,将 D3DRS_LOCALVIEWER = FALSE 设置为指示 系统操作,就像视点在 z 轴上无限远一样。 通过以下公式来反映。

H = norm ( (0,0,1) + Ldir)

 

这种设置的计算密集程度较低,但精确度大大降低,所以最适合采用正交投影的应用使用。

示例

在此示例中,物体的颜色由场景反射光颜色和材料反射颜色决定。 代码如下所示。

D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(mtrl) );

D3DLIGHT9 light;
ZeroMemory( &light, sizeof(light) );
light.Type = D3DLIGHT_DIRECTIONAL;

D3DXVECTOR3 vecDir;
vecDir = D3DXVECTOR3(0.5f, 0.0f, -0.5f);
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );

light.Specular.r = 1.0f;
light.Specular.g = 1.0f;
light.Specular.b = 1.0f;
light.Specular.a = 1.0f;

light.Range = 1000;
light.Falloff = 0;
light.Attenuation0 = 1;
light.Attenuation1 = 0;
light.Attenuation2 = 0;
m_pd3dDevice->SetLight( 0, &light );
m_pd3dDevice->LightEnable( 0, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );

mtrl.Specular.r = 0.5f;
mtrl.Specular.g = 0.5f;
mtrl.Specular.b = 0.5f;
mtrl.Specular.a = 0.5f;
mtrl.Power = 20;
m_pd3dDevice->SetMaterial( &mtrl );
m_pd3dDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);

根据公式,生成的对象顶点颜色是材料颜色和光颜色的组合。

以下两个图例显示了反射材料颜色(灰色)和反射光颜色(白色)。

白色球体的灰色球体插图

生成的反射高光如下图所示。

反射高光图例

反射高光与环境和漫射照明结合产生的结果如下图所示。 借助三种所应用的照明所产生结果将与真实对象更相似。

反射高光、环境照明和漫射照明结合图例

高光照明的计算强度高于漫射照明。 通常可用于提供有关表面材料的视觉线索。 反射高光因表面材料的大小和颜色而异。

照明的数学运算