第04講光照與材質(zhì)_第1頁
第04講光照與材質(zhì)_第2頁
第04講光照與材質(zhì)_第3頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、光照與材質(zhì)一、光照模型:1環(huán)境光:環(huán)境光沒有位置和方向,它是光線經(jīng)過屢次散射后所形成的光。所有的光線都均勻地從各個方向照射到物體上,并且照亮場景中的所有物體。環(huán)境光只有一個顏色值,而且不會衰減,所以在所有方向和所有物體外表上投射的環(huán)境光的數(shù)量是恒定不變的。環(huán)境光是完全獨立于場景中的任何發(fā)光物體的光照模型,所以環(huán)境光模型也被稱作全局光照模型。在 Direct3D應(yīng)用程序中,可以調(diào)用IDirect3DDevice 接口的SetRenderState方法設(shè)置場景中的環(huán)境光。例如:/設(shè)置灰色的環(huán)境光g_pd3dDevice->SetRe nderState( D3DRS_AMBIENT, D3D

2、COLOR_XRGB(222, 222, 222);但與2、漫反射光:漫反射光在生活中最為普遍,太陽的直射、日光燈的照射都可以看成漫反射 的近似。漫反射不同于環(huán)境光,漫反射光的空間位置和方向?qū)ξ矬w的照明有很大影響。觀察者位置無關(guān),因此在漫反射光照模型中一個物體的外表在所有方向上的反射都是一樣 的,如圖4.1所示。3、鏡面反射光:鏡面反射發(fā)生在光滑物體(如金屬物品、玻璃制品等)的外表,當光線照 射到這類物體外表時產(chǎn)生的高光反射,并且當觀察者移動自己所處的位置,反射的亮度也不一樣,觀察方向與反射光線越靠攏,發(fā)射光的強大就越大,如圖4.2所示??梢哉{(diào)由于鏡面反射的計算量比擬大,Direct3D在默認

3、狀態(tài)下不對物體進行鏡面反射計算,用SetRenderState方法啟用鏡面反射。例如:g_pd3dDevice->SetRe nderState ( D3DRS_SPECULARENABLE , TRUE );二、光源類型:Direct3D提供了三種光源類型:點光源(Point Light )、方向光(Directional Light )和聚光燈(Spot Light)。在Direct3D中,光源類型及其屬性由D3DLIGHT9結(jié)構(gòu)表示。該結(jié)構(gòu)體的定義如下: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;/光源類型/漫反射光強度/環(huán)境光強度/鏡面反射光強度/光源位置/光照方向/光照范圍/衰減系數(shù)1/衰減系數(shù)2/衰減系數(shù)3/聚光燈的輻射系數(shù)/聚光燈的內(nèi)錐體大小/聚光燈的外

5、錐體大小1、點光源是從一個中心點向空間中各個方向發(fā)射相等強度光線的光源。點光源具有顏色和 位置,但沒有確定的方向。點光源向各個方向發(fā)出光相,并且光的亮度會隨著距離而衰減, 如圖4.3所示。為了能夠使用點光源,在應(yīng)用程序中需要提供光源的位置、顏色和衰減系數(shù)等參數(shù)。例如, 下面的代碼將創(chuàng)立一個范圍為1000.0f,顏色為白色且位于原點的點光源。D3DLIGHT9 light;:ZeroMemory( &light, sizeof(light);light.Type = D3DLIGHT_P0INT;/ 點光源light.Ambient = D3DCOLOR_XRGB(255, 255, 2

6、55);/ 環(huán)境光,白色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;/ 衰減系數(shù)實例:2、

7、方向光是從無窮遠處發(fā)出的一組平行、均勻的光線,在場景中以相同的方向傳播。方向 光發(fā)出的光只有顏色和方向,并且不會受到衰減和范圍的影響,如圖4.4所示。方向在初始化方向光時,當指定 D3DLIGHT9 結(jié)構(gòu)類型的變量時,需要指定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、聚光燈發(fā)出圓錐形的光,并且由內(nèi)錐體和外錐體兩局部組成。其中內(nèi)錐中的光最亮,而 外錐以外那么沒有光,從內(nèi)錐體到外錐體間光強逐漸衰減,如圖4.5所示。內(nèi)協(xié)體D3DLIGHT9結(jié)構(gòu)體包含了 Fallof、Theta和Phi三個成員描述聚光燈。 其中,F(xiàn)allof字段用 于控制光強如何從內(nèi)錐的外側(cè)向外錐的內(nèi)側(cè)減弱,通常將該字段設(shè)為1.

9、0f,以使光在兩個圓錐間平滑地減弱。Theta和Phi字段用于控制聚光燈的內(nèi)、外錐體的大小,分別以弧度表示內(nèi)、外錐體的角度。在創(chuàng)立一個聚光燈時,除了指定 的光照范圍、方向和衰減系數(shù)。例如: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 = D3

10、DCOLOR_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;/光照范圍/輻射系數(shù)/衰減系數(shù)/內(nèi)錐體大小/外錐體大小三、 D3D材質(zhì)Direct3D提供D3DMATERIAL9 結(jié)構(gòu)

11、用于描述物體的材質(zhì),其中包含了反射環(huán)境光、漫反 射光和鏡面反射光的顏色屬性。該結(jié)構(gòu)體的定義如下:typedef struct D3DMATERIAL9D3DCOLORVALUE Diffuse;D3DCOLORVALUEAmbie nt;D3DCOLORVALUE Specular;D3DCOLORVALUE Emissive;float Power; D3DMATERIAL9, *LPD3DMATERIAL9;當初始化 D3DMATERIQAL9 結(jié)構(gòu)后,可以調(diào)用IDirect3DDevice9 接口的SetMaterial方法設(shè) 置材質(zhì)。例如:D3DMATERIAL9 mtrl;ZeroM

12、emory( &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->SetMate

13、rial( &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設(shè)備對象LPDIRECT3DVERTEXBUFFER

14、9LPDIRECT3DINDEXBUFFER9g_pVB g_pIB=NULL;=NULL; II索引緩沖區(qū)對象II頂點緩沖區(qū)對象D3DXVECTOR3 position;D3DXVECTOR3 normal;#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL) /設(shè)置光照與材質(zhì) void setlighting()D3DMATERIAL9 mtrl;/ 設(shè)置材質(zhì)mtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); mtrl.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.

15、0f, 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; / 設(shè)置方向光照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_l

17、ight);g_pd3dDevice->LightEnable(0, TRUE); g_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, true);/ Desc: 設(shè)置觀察矩陣和投影矩陣 .設(shè)置觀察矩陣和投影矩陣/VOID SetupViewandProjMatrices() /建立并設(shè)置觀察矩陣D3

18、DXVECTOR3 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 );/建立并設(shè)置投影矩陣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 )/創(chuàng)立Direct3D對象,該對象用于創(chuàng)立 Direct3D設(shè)備對象if( NULL = ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )return E_FAIL;設(shè)置

20、D3DPRESENT_PARAMETERS 結(jié)構(gòu),準備創(chuàng)立Direct3D設(shè)備對象 D3DPRESENT_PARAMETERS d3dpp;ZeroMemory( &d3dpp, sizeof(d3dpp) );d3dpp.Windowed = TRUE;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;/創(chuàng)立Direct3D設(shè)備對象if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,

21、 hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pd3dDevice ) ) ) return E_FAIL;/設(shè)置剔出模式為不剔出任何面(正面和反面 )g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );/關(guān)閉光照處理 , 默認情況下啟用光照處理g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); /g_pd3dDevice->SetRenderState(D3DRS_SHAD

22、EMODE, D3DSHADE_GOURAUD); g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); /g_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);/設(shè)置觀察和投影矩陣SetupViewandProjMatrices();setlighting();/設(shè)置視區(qū)/ SetupViewPort();return S_OK;/ Desc: 釋放創(chuàng)立的對象 . 、結(jié)束處理/VOID Cleanup()/釋放頂點緩沖區(qū)對象if( g_p

23、VB != NULL )g_pVB->Release();/釋放Direct3D設(shè)備對象if( g_pd3dDevice != NULL ) g_pd3dDevice->Release();/釋放Direct3D對象if( g_pD3D != NULL ) g_pD3D->Release();/釋放索引緩沖區(qū)對象if (g_pIB != NULL) g_pIB->Release();/5繪制圖形HRESULT InitGeometry()/創(chuàng)頂點緩沖區(qū)if( FAILED( g_pd3dDevice->CreateVertexBuffer(12* sizeof(C

24、USTOMVERTEX),0, D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )return E_FAIL;/填充頂點緩沖區(qū)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=D3DXVEC

25、TOR3(-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.no

26、rmal=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、&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-pVer

28、tices7.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);pVert

29、ices11.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_O

30、K;/ Desc: 渲染圖形 .渲染函數(shù)/VOID Render()/清空后臺緩沖區(qū)g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50,255), 1.0f, 0 );/開始在后臺緩沖區(qū)繪制圖形if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof (CUSTOMVERTEX) ); g_pd3dDevice->SetFVF( D3DFVF_CUSTOM

31、VERTEX ); g_pd3dDevice->SetIndices( g_pIB ); / 設(shè)置索引緩沖區(qū)/D3DXMATRIX Ry; /D3DXMatrixRotationY(&Ry,:timeGetTime()/1000.0f); /g_pd3dDevice->SetTransform(D3DTS_WORLD,&Ry); g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0,4 ); /結(jié)束在后臺緩沖區(qū)渲染圖形 g_pd3dDevice->EndScene(); /將在后臺緩沖區(qū)繪制的圖形提交到前臺緩

32、沖區(qū)顯示 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: 入口函數(shù) .程序入口/INT WINAP

33、I 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 );/創(chuàng)立窗口HWND hWnd = CreateWindow( L "ClassName" ,L "坐標變換 &qu

34、ot;, WS_OVERLAPPEDWINDOW, 200, 100, 500,500, GetDesktopWindow(), NULL, wc.hInstance, NULL );/初始化 Direct3Dif( SUCCEEDED( InitD3D( hWnd ) ) )/創(chuàng)立場景圖形if( SUCCEEDED( InitGeometry() )/ 顯示窗口ShowWindow( hWnd, SW_SHOWDEFAULT );UpdateWindow( hWnd );/進入消息循環(huán)MSG msg;ZeroMemory( &msg, sizeof(msg) );while ( ms

35、g.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_

37、light); 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->

38、SetLight(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()/創(chuàng)頂點緩沖區(qū)if( FAILED( g_pd3dD

39、evice->CreateVertexBuffer(50*2* sizeof(CUSTOMVERTEX),0, D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )return E_FAIL;/填充頂點緩沖區(qū)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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論