Direct3D研究院之光照、材质(七)

谈到光照,涉及到的内容就包括光照模型和光源类型。

一、首先说一下光照模型。

由于现在的计算机的计算能力有限,无法真正实时实现现实中复杂的光照效果,所以在模拟现实光照时,我们不得不简化光照计算,经过对现实光照进行分类,最终抽象出4个光照模型,分别是:环境光、漫反射、镜面反射、自发光。

1、环境光

环境光就是场景中物体表面产生的反射光的统一光照,环境光没有位置和方向,并且值为常量。

在D3D中设置环境光的方式如下:

C#

1

pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(100, 100, 100));

2、漫反射

漫反射是自然界中最普遍的光照现象,它由光照方向以及顶点法向量计算得到,每个顶点的漫反射光颜色都要单独计算,所以漫反射计算比较耗时,但是这种牺牲时值得的,这能体现物体的三维深度。

3、镜面反射

顾名思义,就是发生在镜面上的光反射现象,这里的镜面就是光滑的物体表面,镜面反射的计算量比漫反射计算量还要大得多,所以在D3D中镜面反射是默认关闭的,设置它的开关状态的方法如下:

C#

1

pDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);

4、自发光

自发光就是物体自己发出的光,这是通过对物体材质Emissive属性设置来实现的,自发光不会影响到其他物体。

二、光源

光源类型包括:方向光、点光源、聚光灯。

这些光源类型被定义在枚举类型D3DLIGHTTYPE中,定义如下:

C#

1

2

3

4

5

6

7

Typedef enum _D3DLIGHTTYPE

{

D3DLIGHT_POINT=1,//点光源

D3DLIGHT_SPOT=2,//聚光灯

D3DLIGHT_DIRECTIONAL=3,//方向光

D3DLIGHT_FORCE_DWORD=0x7fffffff

} D3DLIGHTTYPE;

1、点光源

点光源具有颜色与位置属性,没有方向。光照强度会随着距光源中心的距离变大衰减。在具体应用中,可以利用点光源来模拟电灯或精灵。在D3D中设置点光源的方式如下:

C#

1

2

3

4

5

6

7

8

9

10

D3DLIGHT9 light;

ZeroMemory(&light, sizeof(light));

light.Type = D3DLIGHT_POINT;

light.Position = D3DXVECTOR3(1, 1, 1);

light.Range = 10.0f;

light.Diffuse.r = 1.0f;

light.Diffuse.g = 1.0f;

light.Diffuse.b = 1.0f;

light.Attenuation0 = 1.0f;//恒定变化

pDevice->SetLight(0, &light);

2、聚光灯

聚光灯具有颜色、方向和位置。聚光灯由内锥与外锥组成,光照强度由内锥到外锥逐渐衰减。在应用中可以模拟探照灯。由于聚光灯计算量比较大,所以尽量少使用。D3D中设置光源方式如下:

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

D3DLIGHT9 light;

ZeroMemory(&light, sizeof(light));

light.Type = D3DLIGHT_SPOT;

light.Position = D3DXVECTOR3(0, 0, 0);

light.Direction = D3DXVECTOR3(1, 1, 1);

light.Range = 100.0f;

light.Diffuse.r = light.Ambient.r = 0.5f;

light.Diffuse.g = light.Ambient.g = 0.5f;

 

light.Diffuse.b = light.Ambient.b = 0.5f;

light.Phi = D3DX_PI / 4.0;

light.Theta = D3DX_PI / 8.0f;

light.Falloff = 1.0f;

pDevice->SetLight(1, &light);

3、方向光

方向光具有颜色、方向属性,没有位置。方向光不存在范围,所以,计算量在所以光源中最小。在应用中可以模拟太阳光。在D3D中设置光源的方式如下:

C#

1

2

3

4

5

6

7

8

9

10

D3DLIGHT9 light;

ZeroMemory(&light, sizeof(light));

light.Type = D3DLIGHT_DIRECTIONAL;

light.Diffuse.r = 1.0f;

light.Diffuse.g = 1.0f;

light.Diffuse.b = 1.0f;

D3DXVECTOR3 dir;

Dir = D3DXVECTOR3(-1, -1, -1);

D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &dir);

pDevice->SetLight(2, &light);

 这些就是光照的内容,下面来说一下材质。

        在光照的计算中,光照和材质是必需的,缺一不可。那什么是材质呢?

材质就是物体的质地,在D3D中的就是物体对光的吸收与反射特性。

在D3D中结构体D3DMATERIAL9表示材质信息,其定义如下:

C#

1

2

3

4

5

6

7

8

Typedef struct D3DMATERIAL9

{

D3DCOLORVALUE Diffuse;

D3DCOLORVALUE Ambient;

D3DCOLORVALUE Specular;

D3DCOLORVALUE Emissive;

Float Power;

} D3DMATERIAL9, *LPD3DMATERIAL9;

 

其中的成员变量Diffuse、Ambient、Specular分别表示物体表面的漫反射光、环境光、镜面反射光的反射系数,Emissive表示物体的自身发光度,Power表示镜面反射指数。

如果用Id、Ia、Is、Ie分别表示漫反射光、环境光、镜面反射光和自发光的亮度,那么物体顶点最终的颜色亮度为:

It = Id + Ia + Is + Ie;

C#

1

HRESULT SetMaterial(CONST D3DMATERIAL *pMatrial);

函数用来设置当前材质。

下面举例来说明物体材质的设置:

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

D3DMATERIAL9 mtl;

ZeroMemory(&mtl, sizeof(mtl));

//漫反射光

mtl.Diffuse.r = 0.5f;

mtl.Diffuse.g = 0.5f;

mtl.Diffuse.b = 0.5f;

mtl.Diffuse.a = 1.0f;

//环境光

mtl.Ambient.r = 0.2f;

mtl.Ambient.g = 0.4f;

mtl.Ambient.b = 0.8f;

mtl.Ambient.a = 1.0f;

//镜面反射光

mtl.Specular.r = 1.0f;

mtl.Specular.g = 1.0f;

mtl.Specular.b = 1.0f;

mtl.Specular.a = 1.0f;

mtl.Power = 25.0f;

//自发光

mtl.Emissive.r = 0.3f;

mtl.Emissive.g = 1.0f;

mtl.Emissive.b = 0.6f;

mtl.Emissive.a = 1.0f;

gDevice->SetMaterial(&mtl);

gDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);

 

好,这一讲就到这里,回头看一下,离上次更新已经快一个世纪了(汗颜,不过确实最近忙得要死),不过同样还是希望大家,编程愉快。ZXGoto与大家一起学习进步。

下面的例子是在上一篇中的太阳系项目基础上改的,运行效果如图:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值