首页 > 编程学习 > Direct 3D学习笔记(三)——光照与材质

 

                            Direct 3D学习笔记(三)——光照与材质

现实世界中物体的颜色是一个复杂的系统,物体在不同的光照下,可能呈现在我们面前的就是不同的颜色。根据物理中的光学知识,物体在各种环境光照下,根据物体自身特性,吸收其中一些光线(其实吸收的是光线的能量),而将自己不能吸收的光线反射回去,当我们的眼睛捕捉到这些被反射的光线后,就可以感觉到物体的外观形状和物体表面的色泽。

在计算机系统中为了表示颜色,通常是由RGB三种颜色来混合得到不同的颜色值,RGB的位数越大表示的颜色数越多,当然这知识理论值,并且当达到了一定的极限后,人眼也无法分辨,就没有意义了。由于颜色是由波长决定的,所以可以将任一种颜色表示为:

λ = μR + βG + γB;(RGB分别表示红绿蓝色光的波长,λ是任意波长的光)

三元数(μβγ)决定任意光的波长,实际中还可能加入一个A来表示颜色的饱和度。

Direct 3D中分别设计了两个struct来表示这个四元颜色值,分别是D3DCOLORVALUED3DXCOLORVALUE,后面的是为了支持颜色值的算术运算而对前面结构体的扩展,他支持一系列的颜色值算术运算,注意这些颜色值分量是float。当然Direct 3D还提供了D3DCOLOR这个结构体来表示整形分量的颜色值,具体见MSDN

 

Direct 3D中提供了点光源(Point Light)、聚焦光源(Spot Light)、方向光源(Directional Light)和环境光源(Ambient Light)四种标准光源。实际应用中可以根据不同光源的属性来设置光照,各种光源以及它的属性在DirectX中用结构体D3DLIGHT9来描述。

typedef struct D3DLIGHT9 {

    D3DLIGHTTYPE Type;      //光源类型

    D3DCOLORVALUE Diffuse;  //漫射光颜色

    D3DCOLORVALUE Specular; //镜面光颜色

    D3DCOLORVALUE Ambient;  //环境光颜色

    D3DVECTOR Position;     //光源位置

    D3DVECTOR Direction;    //光照方向

    float Range;            //光照范围

    float Falloff;          //光线衰减系数

    float Attenuation0;     //于距离相关的光强衰减系数0

    float Attenuation1;     //于距离相关的光强衰减系数1

    float Attenuation2;     //于距离相关的光强衰减系数2

    float Theta;            //聚焦光源的内锥角

    float Phi;              //聚焦光源的外锥角

} D3DLIGHT9, *LPD3DLIGHT;

在设置系统的光照时,可以定义一个光源结构体变量,并根据不同的光进行属性设置,然后利用IDirect3DDevice9::SetLight()函数将光源设置到渲染管道流水线中,当光源被设置给渲染管道流水线后,需要调用IDirect3DDevice9::LightEnable()函数使光源能够被使用,最后利用函数IDirect3DDevice9::SetRenderState()打开渲染管道流水线的光照开关,这样,渲染管道流水线才会真正执行光照处理。

1、 点光源(Point Light)

点光源顾名思义就是一个中心点向空间各个各个方向等强度发射光线的光源。比如

实际生活中的电灯炮就是一个点光源。点光源发射光的强度将随着距离的增加而逐渐衰减,但它没有方向属性

2、 方向光源(Directional Light)

方向光源可以理解为从无限远以特定的方向照射过来的光,而且光照强度随距离的增

加而衰减。比如现实生活中的太阳光。方向光光源不需要设置光源位置、衰减系数和光照左右范围。

3、 聚焦光源(Spot Light)

聚集光源的发光区域是一个圆锥体,内锥的光的强度沿着聚焦光的主发射方向,随着

距离的增加而逐步衰减;外锥的光照强度沿着外径逐渐衰减。比如实际生活中的手电筒就是一个聚焦光源模型。

4、 环境光源(Ambient Light)

环境光是根据场景中的各种光源的综合照射效果所模拟出的一种光源。它来自各个方

向,不做任何光照强度的衰减处理,能够均匀照射物体表面的各个部位。

 

     由前面物体颜色的说明可知,物体表面颜色不仅仅跟照射光源的属性有关,而且还与实际物体对光的反射属性和物体自身表面颜色有关,也即物体的材质属性有关。所以光照与物体材质是相辅相成的,对于整个光照计算是缺一不可的。在DirectX中物体表面的材质由结构体D3DMATERIAL9来定义:

typedef struct D3DMATERIAL9 {

    D3DCOLORVALUE Diffuse; //漫射光的反射属性

    D3DCOLORVALUE Ambient; //环境光的反射属性

    D3DCOLORVALUE Specular;//镜面光的反射属性

    D3DCOLORVALUE Emissive;//自发光的反射属性

    float Power;           //镜面光的高光强度

} D3DMATERIAL9, *LPD3DMATERIAL9;

其中D3DCOLORVALUE结构体中包含rgba四个分量,在这里每个分量的值表

示物体表面对各种反射光的各种成分的反射比率。Emissive表示物体自发光的颜色值,也即是物体本身的颜色值。Power参数说明镜面光的搞光强度,power越大,光强越强,反之越弱。

   

由于三维场景中物体的渲染最终是对物体各个剖分三角形面的渲染,在使用光源光的照射下,顶点的颜色值是由光的入射方向与顶点的法向量的夹角来决定,所以在使用光照模型时,三角形面的灵活顶点格式要包括顶点的法向量坐标。

 

  最后给出一个光照设置代码块:

// setup material D3DMATERIAL9 mtrl; SecureZeroMemory(&mtrl, sizeof(D3DMATERIAL9)); mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f; mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f; mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f; mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f; m_pD3Dev->SetMaterial(&mtrl); // set lights D3DXVECTOR3 vecDir; D3DLIGHT9 light; SecureZeroMemory(&light, sizeof(D3DLIGHT9)); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 1.0f; light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; vecDir = D3DXVECTOR3(cosf(timeGetTime()/500.0f), 1.0f, sinf(timeGetTime()/500.0f)); D3DXVec3Normalize((D3DXVECTOR3 *)&light.Direction, &vecDir); light.Range = 1000.0f; m_pD3Dev->SetLight(0, &light); m_pD3Dev->LightEnable(0, true); m_pD3Dev->SetRenderState(D3DRS_LIGHTING, true); // set ambient m_pD3Dev->SetRenderState(D3DRS_AMBIENT, 0x00505050);

转载于:https://www.cnblogs.com/leezhm/archive/2008/07/28/2560352.html

Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000