第04讲光照与材质_第1页
第04讲光照与材质_第2页
第04讲光照与材质_第3页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、光照与材质一、光照模型:1环境光:环境光没有位置和方向,它是光线经过多次散射后所形成的光。所有的光线都均匀地从各个方向照射到物体上,并且照亮场景中的所有物体。环境光只有一个颜色值,而且不会衰减,所以在所有方向和所有物体表面上投射的环境光的数量是恒定不变的。环境光是完全独立于场景中的任何发光物体的光照模型,所以环境光模型也被称作全局光照模型。在 Direct3D应用程序中,可以调用IDirect3DDevice 接口的SetRenderState方法设置场景中的环境光。例如:/设置灰色的环境光g_pd3dDevice->SetRe nderState( D3DRS_AMBIENT, D3D

2、COLOR_XRGB(222, 222, 222);但与2、漫反射光:漫反射光在生活中最为普遍,太阳的直射、日光灯的照射都可以看成漫反射 的近似。漫反射不同于环境光,漫反射光的空间位置和方向对物体的照明有很大影响。观察者位置无关,因此在漫反射光照模型中一个物体的表面在所有方向上的反射都是一样 的,如图4.1所示。3、镜面反射光:镜面反射发生在光滑物体(如金属物品、玻璃制品等)的表面,当光线照 射到这类物体表面时产生的高光反射,并且当观察者移动自己所处的位置,反射的亮度也不一样,观察方向与反射光线越靠拢,发射光的强大就越大,如图4.2所示。可以调由于镜面反射的计算量比较大,Direct3D在默认

3、状态下不对物体进行镜面反射计算,用SetRenderState方法启用镜面反射。例如:g_pd3dDevice->SetRe nderState ( D3DRS_SPECULARENABLE , TRUE );二、光源类型:Direct3D提供了三种光源类型:点光源(Point Light )、方向光(Directional Light )和聚光灯(Spot Light)。在Direct3D中,光源类型及其属性由D3DLIGHT9结构表示。该结构体的定义如下:typedef struct D3DLIGHT9 D3DLIGHTTYPE Type; D3DCOLORVALUE Diffuse

4、; D3DCOLORVALUE Specular; D3DCOLORVALUE Ambie nt;D3DVECTORPosition;floatRan ge;floatAtte nuatio nOfloatAtte nu ati on1 ;floatAttenuation2 ;D3DVECTORDirection ;floatFalloff;floatTheta;floatPhi; D3DLIGHT9, *LPD3DLIGHT;/光源类型/漫反射光强度/环境光强度/镜面反射光强度/光源位置/光照方向/光照范围/衰减系数1/衰减系数2/衰减系数3/聚光灯的辐射系数/聚光灯的内锥体大小/聚光灯的外

5、锥体大小1、点光源是从一个中心点向空间中各个方向发射相等强度光线的光源。点光源具有颜色和 位置,但没有确定的方向。点光源向各个方向发出光相,并且光的亮度会随着距离而衰减, 如图4.3所示。为了能够使用点光源,在应用程序中需要提供光源的位置、颜色和衰减系数等参数。例如, 下面的代码将创建一个范围为1000.0f,颜色为白色且位于原点的点光源。D3DLIGHT9 light;:ZeroMemory( &light, sizeof(light);light.Type = D3DLIGHT_P0INT;/ 点光源light.Ambient = D3DCOLOR_XRGB(255, 255, 2

6、55);/ 环境光,白色light.Ambie nt.r=light.Ambie nt.g=light.Ambie nt.b=light.Diffuse = D3DCOLOR_XRGB(255, 255, 255);/ 漫反射光,白色light.Specular = D3DCOLOR_XRGB(255, 255, 255);/ 镜面反射光,白色light.Position = D3DXVECTOR3(O.Of, 0.0f, 0.0f);/ 点光源位置,原点light.Range = 1000.0f;/ 光照范围,1000light.AttenuationO = 1.0f;/ 衰减系数实例:2、

7、方向光是从无穷远处发出的一组平行、均匀的光线,在场景中以相同的方向传播。方向 光发出的光只有颜色和方向,并且不会受到衰减和范围的影响,如图4.4所示。方向在初始化方向光时,当指定 D3DLIGHT9 结构类型的变量时,需要指定D3DLIGHT_DIRECTION ,并制定方向光的光照方向。例如:D3DLIGHT9 light;Type成员为:ZeroMemory( &light, sizeof(light);light.Type = D3DLIGHT_DIRECTIONAL;/方向光light.Ambie nt light.Diffuse light.Specular light.Di

8、rectio n=D3DCOLOR_XRGB(255, 255, 255);=D3DCOLOR_XRGB(255, 255, 255);=D3DCOLOR_XRGB(255, 255, 255);=D3DXVECTOR3(1.0f, 0.0f, 1.0f);/光照方向3、聚光灯发出圆锥形的光,并且由内锥体和外锥体两部分组成。其中内锥中的光最亮,而 外锥以外则没有光,从内锥体到外锥体间光强逐渐衰减,如图4.5所示。内协体D3DLIGHT9结构体包含了 Fallof、Theta和Phi三个成员描述聚光灯。 其中,Fallof字段用 于控制光强如何从内锥的外侧向外锥的内侧减弱,通常将该字段设为1.0

9、f,以使光在两个圆锥间平滑地减弱。Theta和Phi字段用于控制聚光灯的内、外锥体的大小,分别以弧度表示内、外锥体的角度。在创建一个聚光灯时,除了指定 的光照范围、方向和衰减系数。例如:Falloff、Theta和Phi成员的值外,还需要指定聚光灯D3DLIGHT9 light;:ZeroMemory (&l ight, sizeof(light); light.Type = D3DLIGHT_SPOT; /light.Ambie nt= O.Of;/聚光灯light.Diffuse = D3DCOLOR_XRGB(255, 255, 255);light.Specular = D3D

10、COLOR_XRGB(255, 255, 255);light.Position = D3DXVECTOR3(-10.0f, 5.0f, -10.0f);/ 位置light.Directio n= D3DXVECTOR3(1.0f, O.Of, 1.0f);/光照方向light.Ra nge light.Falloff=1000.0f;=1.0f;light.Atte nuati onO = 1.0f;light.Theta = 0.4f;light .Phi= 0.9f;/光照范围/辐射系数/衰减系数/内锥体大小/外锥体大小三、 D3D材质Direct3D提供D3DMATERIAL9 结构用

11、于描述物体的材质,其中包含了反射环境光、漫反 射光和镜面反射光的颜色属性。该结构体的定义如下:typedef struct D3DMATERIAL9D3DCOLORVALUE Diffuse;D3DCOLORVALUEAmbie nt;D3DCOLORVALUE Specular;D3DCOLORVALUE Emissive;float Power; D3DMATERIAL9, *LPD3DMATERIAL9;当初始化 D3DMATERIQAL9 结构后,可以调用IDirect3DDevice9 接口的SetMaterial方法设 置材质。例如:D3DMATERIAL9 mtrl;ZeroMe

12、mory( &mtrl, sizeof(D3DMATERIAL9); mtrl.Diffuse.r = mtrl.Ambie nt.r = mtrl.Specular.r = 1.0f; mtrl.Diffuse.g = mtrl.Ambie nt.g = mtrl.Specular.g = 1.0f; mtrl.Diffuse.b = mtrl.Ambie nt.b = mtrl.Specular.b = 0.0f; mtrl.Diffuse.a = mtrl.Ambie nt.a = mtrl.Specular.a = 1.0f; g_pd3dDevice->SetMater

13、ial( &mtrl );完整实例: struct CUSTOMVERTEX绘制四个三角形围成的椎状体:_D3DVECTORx=0.00000000y=0.70710671 z=-0.70710671 D3DVECTOR#in clude <win dows.h>#include <d3dx9.h>#include <d3d9.h>LPDIRECT3D9LPDIRECT3DDEVICE9g_pD3D= NULL;g_pd3dDevice = NULL;IIDirect3D 对象IIDirect3D设备对象LPDIRECT3DVERTEXBUFFER9

14、LPDIRECT3DINDEXBUFFER9g_pVB g_pIB=NULL;=NULL; II索引缓冲区对象II顶点缓冲区对象D3DXVECTOR3 position;D3DXVECTOR3 normal;#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL) /设置光照与材质 void setlighting()D3DMATERIAL9 mtrl;/ 设置材质mtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); mtrl.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0

15、f, 1.0f); mtrl.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); mtrl.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); mtrl.Power = 1.0f;g_pd3dDevice->SetMaterial( &mtrl);D3DLIGHT9 dir_light; / 设置方向光照ZeroMemory(&dir_light, sizeof(dir_light);dir_light.Typedir_light.Diffuse.r dir_light.Specular.r

16、= dir_light.Ambient.r = D3DLIGHT_DIRECTIONAL;=dir_light.Diffuse.g=dir_light.Diffuse.b=1.0f; dir_light.Specular.g=dir_light.Specular.b=0.3f; dir_light.Ambient.g=dir_light.Ambient.b=0.6f;dir_light.Direction = D3DXVECTOR3(-1.0f, 0.0f, 0.0f); dir_light.Range=1000;g_pd3dDevice->SetLight(0, &dir_li

17、ght);g_pd3dDevice->LightEnable(0, TRUE); g_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, true);/ Desc: 设置观察矩阵和投影矩阵 .设置观察矩阵和投影矩阵/VOID SetupViewandProjMatrices() /建立并设置观察矩阵D3D

18、XVECTOR3 vEyePt( 5.0f,5.0f,-5.0f );D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );D3DXMATRIX matView;D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );/建立并设置投影矩阵D3DXMATRIX matProj;

19、D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );/ Desc: 初始化 Direct3D/HRESULT InitD3D( HWND hWnd )/创建Direct3D对象,该对象用于创建 Direct3D设备对象if( NULL = ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )return E_FAIL;设置D

20、3DPRESENT_PARAMETERS 结构,准备创建Direct3D设备对象 D3DPRESENT_PARAMETERS d3dpp;ZeroMemory( &d3dpp, sizeof(d3dpp) );d3dpp.Windowed = TRUE;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;/创建Direct3D设备对象if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,

21、hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pd3dDevice ) ) ) return E_FAIL;/设置剔出模式为不剔出任何面(正面和反面 )g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );/关闭光照处理 , 默认情况下启用光照处理g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); /g_pd3dDevice->SetRenderState(D3DRS_SHADE

22、MODE, D3DSHADE_GOURAUD); g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); /g_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);/设置观察和投影矩阵SetupViewandProjMatrices();setlighting();/设置视区/ SetupViewPort();return S_OK;/ Desc: 释放创建的对象 . 、结束处理/VOID Cleanup()/释放顶点缓冲区对象if( g_pV

23、B != NULL )g_pVB->Release();/释放Direct3D设备对象if( g_pd3dDevice != NULL ) g_pd3dDevice->Release();/释放Direct3D对象if( g_pD3D != NULL ) g_pD3D->Release();/释放索引缓冲区对象if (g_pIB != NULL) g_pIB->Release();/5绘制图形HRESULT InitGeometry()/创顶点缓冲区if( FAILED( g_pd3dDevice->CreateVertexBuffer(12* sizeof(CU

24、STOMVERTEX),0, D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )return E_FAIL;/填充顶点缓冲区CUSTOMVERTEX* pVertices;if( FAILED( g_pVB->Lock( 0, 0, ( void*)&pVertices, 0 ) ) )return E_FAIL;/ memcpy( pVertices, vertices, sizeof(vertices) );D3DXVECTOR3 u,v,nor;/前面pVertices0.position=D3DXVECT

25、OR3(-1.0f, 0.0f, -1.0f); pVertices1.position=D3DXVECTOR3(0.0f, 1.0f, 0.0f); pVertices2.position=D3DXVECTOR3(1.0f, 0.0f, -1.0f);v=pVertices0.position-pVertices1.position;u=pVertices2.position-pVertices1.position;D3DXVec3Cross(&nor,&u,&v);D3DXVec3Normalize(&nor,&nor);pVertices0.nor

26、mal=pVertices1.normal=pVertices2.normal=nor; /左边pVertices3.position=D3DXVECTOR3(-1.0f, 0.0f, 1.0f);pVertices4.position=D3DXVECTOR3(0.0f, 1.0f, 0.0f);pVertices5.position=D3DXVECTOR3(-1.0f, 0.0f, -1.0f);v=pVertices3.position-pVertices4.position;u=pVertices5.position-pVertices4.position;D3DXVec3Cross(&

27、amp;nor,&u,&v);D3DXVec3Normalize(&nor,&nor);pVertices3.normal=pVertices4.normal=pVertices5.normal=nor; /右边pVertices6.position=D3DXVECTOR3(1.0f, 0.0f, -1.0f);pVertices7.position=D3DXVECTOR3(0.0f, 1.0f, 0.0f);pVertices8.position=D3DXVECTOR3(1.0f, 0.0f, 1.0f);v=pVertices6.position-pVert

28、ices7.position;u=pVertices8.position-pVertices7.position;D3DXVec3Cross(&nor,&u,&v);D3DXVec3Normalize(&nor,&nor);pVertices6.normal=pVertices7.normal=pVertices8.normal=nor;/后面pVertices9.position=D3DXVECTOR3(1.0f, 0.0f, 1.0f);pVertices10.position=D3DXVECTOR3(0.0f, 1.0f, 0.0f);pVerti

29、ces11.position=D3DXVECTOR3(-1.0f, 0.0f, 1.0f);v=pVertices9.position-pVertices10.position;u=pVertices11.position-pVertices10.position;D3DXVec3Cross(&nor,&u,&v);D3DXVec3Normalize(&nor,&nor); pVertices9.normal=pVertices10.normal=pVertices11.normal=nor; g_pVB->Unlock();return S_OK

30、;/ Desc: 渲染图形 .渲染函数/VOID Render()/清空后台缓冲区g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50,255), 1.0f, 0 );/开始在后台缓冲区绘制图形if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof (CUSTOMVERTEX) ); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMV

31、ERTEX ); g_pd3dDevice->SetIndices( g_pIB ); / 设置索引缓冲区/D3DXMATRIX Ry; /D3DXMatrixRotationY(&Ry,:timeGetTime()/1000.0f); /g_pd3dDevice->SetTransform(D3DTS_WORLD,&Ry); g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0,4 ); /结束在后台缓冲区渲染图形 g_pd3dDevice->EndScene(); /将在后台缓冲区绘制的图形提交到前台缓冲

32、区显示 g_pd3dDevice->Present( NULL, NULL, NULL, NULL );/ Desc: 消息处理 .消息处理/LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )switch ( msg )case WM_DESTROY: Cleanup(); PostQuitMessage( 0 );return 0;return DefWindowProc( hWnd, msg, wParam, lParam );/ Desc: 入口函数 .程序入口/INT WINAPI

33、 WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) /注册窗口类WNDCLASSEX wc = sizeof(WNDCLASSEX), CS_CLASSDC , MsgProc, 0L, 0L,GetModuleHandle(NULL), NULL, NULL, NULL, NULL,L "ClassName" , NULL ;RegisterClassEx( &wc );/创建窗口HWND hWnd = CreateWindow( L "ClassName" ,L "坐标变换 &quo

34、t;, WS_OVERLAPPEDWINDOW, 200, 100, 500,500, GetDesktopWindow(), NULL, wc.hInstance, NULL );/初始化 Direct3Dif( SUCCEEDED( InitD3D( hWnd ) ) )/创建场景图形if( SUCCEEDED( InitGeometry() )/ 显示窗口ShowWindow( hWnd, SW_SHOWDEFAULT );UpdateWindow( hWnd );/进入消息循环MSG msg;ZeroMemory( &msg, sizeof(msg) );while ( msg

35、.message!=WM_QUIT )if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) TranslateMessage( &msg );DispatchMessage( &msg );elseRender(); / 渲染图形UnregisterClass( L "ClassName" , wc.hInstance ); return 0;实例2:void setlight in g()D3DMATERIAL9 mtrl;mtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, O.

36、Of, 1.0f);mtrl.Diffuse = D3DXCOLOR(1.0f, 1.0f, O.Of, 1.0f);mtrl.Specular = D3DXCOLOR(1.0f, 1.0f, O.Of, 1.0f);mtrl.Emissive = D3DXCOLOR(O.Of, O.Of, O.Of, 1.0f); mtrl.P ower = 1.0f;g_pd3dDevice->SetMaterial( & mtrl);D3DLIGHT9 dir_light;D3DXVECTOR3 dir_vec;ZeroMemory(&dir_light, sizeof(dir_l

37、ight); dir_light.Type = D3DLIGHT_DIRECTIONAL;dir_light.Diffuse.r =dir_light.Diffuse.g=dir_light.Diffuse.b=1.0f;dir_vec=D3DXVECTOR3 (cos(:timeGetTime()/1000.0f),0,sin(:timeGetTime()/1000.0f);D3DXVec3Normalize(D3DXVECTOR3*)&dir_light.Direction,&dir_vec); dir_light.Range=1000;g_pd3dDevice->S

38、etLight(0, &dir_light);g_pd3dDevice->LightEnable(0, TRUE); g_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, true);/5 绘制图形HRESULT InitGeometry()/创顶点缓冲区if( FAILED( g_pd3dDe

39、vice->CreateVertexBuffer(50*2* sizeof(CUSTOMVERTEX),0, D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )return E_FAIL;/填充顶点缓冲区CUSTOMVERTEX* pVertices;if( FAILED( g_pVB->Lock( 0, 0, ( void *)&pVertices, 0 ) ) )return E_FAIL;for( DWORD i=0; i<50; i+ )FLOAT theta = (2*D3DX_PI*i)/(50-1);pVertices2*i+0.position = D3DXVECT

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论