第九章使用MFC實現(xiàn)真實感圖形繪制自然科學_第1頁
第九章使用MFC實現(xiàn)真實感圖形繪制自然科學_第2頁
第九章使用MFC實現(xiàn)真實感圖形繪制自然科學_第3頁
第九章使用MFC實現(xiàn)真實感圖形繪制自然科學_第4頁
第九章使用MFC實現(xiàn)真實感圖形繪制自然科學_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1/1第九章使用MFC實現(xiàn)真實感圖形繪制-自然科學

第九章使用MFC實現(xiàn)真實感圖形繪制

真實感圖形繪制是計算機圖形學的一個重要組成部分。它綜合利用數(shù)學、物理學、計算機科學和其他學科學問在計算機圖形設備上生成象彩色照片那樣的真實感圖形。要用計算機圖形設備繪制場景的真實感圖形,就必需首先在計算機中建立該場景的模型,用這個模型來反映場景的特點和屬性。這一模型通常是由一批幾何數(shù)據(jù)及數(shù)據(jù)之間的拓撲關系來表示的,這就是造型技術(shù),它是真實感圖形繪制技術(shù)的重要組成部分。有了三維場景的模型,并給定了觀看點和觀看方向以后,就可以通過幾何變換和投影變換在屏幕上顯示該三維場景的二維圖像。為了使二維圖像具有立體感,并盡可能逼真地顯示出該物體在現(xiàn)實世界中被觀看到的形象,就需要運用適當?shù)墓庹漳P?,來模擬場景在現(xiàn)實世界中受到各種光源照耀時的效果,這就是真實感圖形的畫面繪制技術(shù),也就是真實感圖形的生成技術(shù)。

用計算機在圖形設備上生成連續(xù)色調(diào)的真實感圖形大致可以分為以下四步:第一步,用數(shù)學方法建立所需三維場景的幾何描述,并將它們輸入至計算機。這部分工作可由三維立體造型或曲面造型系統(tǒng)來完成。場景的幾何描述直接影響了圖形的簡單性和圖形繪制的計算耗費,因此選擇合理的、有效的數(shù)據(jù)表示和輸入手段是特別重要的。

其次步,將三維幾何描述轉(zhuǎn)換為二維投影圖。這可以通過對場景的投影變換來完成。

第三步,確定場景中的全部可見面,這需要使用隱蔽面消退算法將被其他物體遮擋的不行見面消去。

第四步,計算場景中可見面的顏色,嚴格地說,就是依據(jù)基于光學物理的光照明模型計算可見面投射到觀看者眼中的光亮度大小和顏色重量,并將它轉(zhuǎn)換成適合圖形設備的顏色值,從而確定投影畫面上每一象素的顏色,最終生成圖形。

前三步的相關學問在前面已經(jīng)進行了介紹,本章將重點介紹如何通過MFC編程的方式,利用光照模型計算場景中可見面的光亮度和顏色,并繪制最終的真實感圖形。實際上,現(xiàn)在OpenGL和DirectX等圖形函數(shù)庫供應了許多支持真實感圖形繪制的函數(shù),使用它們可以更輕松的完成真實感圖形繪制。本章仍采納最基本的MFC編程方式來實現(xiàn)真實感圖形繪制,是為了讓讀者可以更好的體會和理解真實感圖形繪制中用到的光照模型等相關學問的原理。

9.1演示程序使用的場景造型

場景造型又叫幾何造型,它是在計算機中建立的用于描述現(xiàn)實場景的幾何模型,它是真實感圖形生成的一個重要部分。在真實感圖形中,一個景物的場景造型體現(xiàn)了該景物的幾何特征和景物屬性。場景造型的簡單程度直接打算了最終繪制的真實感圖形的效果。

本章的重點在于光照模型的實現(xiàn),所以本章中的演示程序沒有創(chuàng)建簡單場景,只使用了一種景物——球體。演示程序依據(jù)球體的函數(shù)方程,計算球體表面的參數(shù)點坐標,然后按這些參數(shù)點對球體表面作三角剖分,最終利用光照模型對剖分得到的三角面片計算光照并進行繪制。

9.1.1球體造型

球體表面的函數(shù)方程式如下:

x?x0?rcosucoswy?y0?rcosucoswz?z0?rsinuu?[??2,]?2]w?[0,?2

其中,坐標(x0,y0,z0)為球心坐標,而坐標(x,y,z)為球面上的參數(shù)點坐標,r為半徑,u、w分別為緯度和經(jīng)度參數(shù)變量。

我們創(chuàng)建一個MFC項目RealityDemo,該應用程序作為本章中的演示程序。在該應用程序中添加一個類CObject3D,其基類為CObject。該類的實例對應場景中的一個景物。為了定義景物,需要定義如下結(jié)構(gòu)體:

//三維空間中點structPoint3D{doublex;doubley;doublez;};

//三角面

structTriSurface{

intno;//所屬景物序號

Point3Dp1,p2,p3;//三角面的頂點doublexn,yn,zn;//三角面的法向量};

//景物光照參數(shù)structParam{

doublekrd;//景物表面紅色光漫反射率doublekgd;//景物表面綠色光漫反射率doublekbd;//景物表面藍色光漫反射率doublekra;//景物表面紅色光泛光反射率doublekga;//景物表面綠色光泛光反射率doublekba;//景物表面藍色光泛光反射率doublekrs;//景物表面紅色光鏡面反射率doublekgs;//景物表面綠色光鏡面反射率doublekbs;//景物表面藍光鏡面反射率intn;//景物表面鏡面高光指數(shù)};

Point3D定義了三維空間中的一點。而TriSurface則定義了一個三角面片。結(jié)構(gòu)體Param中的各成員變量指定了景物的光照參數(shù),其詳細含義將會在介紹光照模型時說明。

我們在CObject3D類中添加如下的成員變量和成員函數(shù):

public:

//球體表面三角剖分后得到的三角面列表CArraym_SurfaceList;Paramm_Param;//球體表面光照參數(shù)

Point3Dp3d[101][101];//球體表面參數(shù)點數(shù)組

intcountx,county;//生成的參數(shù)點在經(jīng)度和緯度上的數(shù)量doublebx,by,bz;//圓心坐標public:

//創(chuàng)建指定球心和半徑的球體

voidCreateBall(doublex0,doubley0,doublez0,doubler);voidSetSurfaceList;//對球體表面進行三角剖分

voidSetFVector(TriSurface*surface);//設置三角面的法向量voidSetParam(Paramparam);//設置球體表面光照參數(shù)9.1.2生成球體表面參數(shù)點

成員函數(shù)CreateBall用于生成球體表面的參數(shù)點,并按這些參數(shù)點對球體表面進行三角剖分,將剖分生成的三角面片存入到列表m_SurfaceList中,其中三角剖分由成員函數(shù)SetSurfaceList完成。CreateBall函數(shù)的實現(xiàn)代碼如下:

//創(chuàng)建一個球體

voidCObject3D::CreateBall(doublex0,doubley0,doublez0,doubler){

inti=0,j;

doublepi=3.1415926;bx=x0;by=y0;bz=z0;

for(doubleu=-pi/2;ucountx=i;county=j;

SetSurfaceList;}

其中u和v的步長打算了產(chǎn)生的球體表面的參數(shù)點的數(shù)量。countx和county需要在類的構(gòu)造函數(shù)中設置初始值為0。程序中將生成的球體表面參數(shù)點存入到p3d數(shù)組中,這樣做是為了便利對球體表面進行三角剖分。

9.1.3球體表面三角剖分

對球體表面進行三角剖分采納如下方法。設球體表面上一個參數(shù)點為P[i][j],則其經(jīng)度上的下一個參數(shù)點為p[i+1][j],而緯度上的下一個參數(shù)點為p[i][j+1],再加上該點在對角線方向上的下一個參數(shù)點p[i+1][j+1],這四個點構(gòu)成的區(qū)域可以剖分成兩個三角面片。第一個三角面片的頂點為p[i][j],p[i+1][j],p[i+1][j+1],其次個三角面片的頂點為p[i][j],p[i][j+1],p[i+1][j+1]。在生成三角面片的同時需要計算該三角面片的法向量,由于在計算光照的時候需要用到此法向量。平面上兩個向量的叉乘積即為平面的法向量,其方向性滿意右手定則,計算的時候需要留意法向量的方向應當是指向球外的。執(zhí)行三角剖分的函數(shù)SetSurfaceList和計算法向量的函數(shù)SetFVector實現(xiàn)代碼如下:

//球體表面進行三角剖分

voidCObject3D::SetSurfaceList{

for(inti=0;ip2.x-surface->p1.x;yu=surface->p2.y-surface->p1.y;zu=surface->p2.z-surface->p1.z;xv=surface->p3.x-surface->p1.x;yv=surface->p3.y-surface->p1.y;zv=surface->p3.z-surface->p1.z;

d=sqrt((yu*zv-yv*zu)*(yu*zv-yv*zu)+

(zu*xv-zv*xu)*(zu*xv-zv*xu)+(xu*yv-xv*yu)*(xu*yv-xv*yu));surface->xn=(yu*zv-yv*zu)/d;surface->yn=(zu*xv-zv*xu)/d;surface->zn=(xu*yv-xv*yu)/d;}

在計算三角面片的法向量時計算的是單位法向量。在CObject3D類中還有一個函數(shù)SetParam用于設置景物的光照參數(shù),其實現(xiàn)特別簡潔,代碼如下:

//設置光照參數(shù)

voidCObject3D::SetParam(Paramparam){

m_Param.kra=param.kra;m_Param.kga=param.kga;m_Param.kba=param.kba;m_Param.krd=param.krd;m_Param.kgd=param.kgd;m_Param.kbd=param.kbd;m_Param.krs=param.krs;m_Param.kgs=param.kgs;m_Param.kbs=param.kbs;m_Param.n=param.n;}

我們創(chuàng)建景物時,首先需要實例化CObject3D對象,然后調(diào)用CreateBall函數(shù)創(chuàng)建球體景物,其實質(zhì)是生成該球體的三角剖分面片列表,然后設置該球體的光照參數(shù)。此時就可以使用光照模型來計算球體表面的光照并進行繪制了。同樣的,我們也可以創(chuàng)建其它外形的景物,其過程大體如下:獲得景物表面的參數(shù)點,然后進行三角剖分,計算三角面片的法向量,最終設置景物的光照參數(shù)。

9.2局部光照模型

為了模擬光源照耀在景物表面所產(chǎn)生的光照效果,就需要用到光照模型,光照模型是生成真實感圖形的基礎。光照模型是依據(jù)光學物理的有關定律,計算景物表面上任一點投向觀看者眼中的光亮度的大小和顏色組成的公式。光照模型分為局部光照模型和整體光照模型。

局部光照模型僅考慮光源直接照耀在景物表面所產(chǎn)生的光照效果,景物表面通常被假定為不透亮?????,且具有勻稱的反射率。局部光照模型能表現(xiàn)由光源直接照耀在漫射表面上形成的連續(xù)明暗色調(diào)、鏡面上的高光以及由于景物相互遮擋而形成的陰影等,具有肯定的真實感效果。而整體光照模型除了考慮上述因素外,還要考慮四周環(huán)境對景物表面的影響,如消失在鏡面上的其他景物的印象,通過透亮?????面可觀看到后面的景物等。本節(jié)我們將實現(xiàn)的是局部光照模型。9.2.1局部光照模型概述

從光源發(fā)出的光照耀到景物表面時,會消失以下四種情形:(1)經(jīng)景物表面對外反射形成反射光;

(2)若景物透亮?????,則入射光會穿透該景物,從而產(chǎn)生透射光;(3)若景物透亮?????,入射光在穿透景物時會產(chǎn)生散射光;(4)部分入射光將被景物汲取而轉(zhuǎn)換成熱。

明顯,刺激人眼產(chǎn)生視覺效果的主要是反射光和透射光,如圖9.1所示。

物體表面的反射光和透射光的光譜分布打算了景物表面呈現(xiàn)的顏色,反射光和透射光的強弱則打算了景物表面的明暗程度。明顯,反射光和透射光打算于入射光的強弱、光譜組成以及景物表面對入射光中不同波長光的汲取程度。例如,當一束白光照耀在一個汲取除紅光以外全部不同波長光的不透亮?????景物表面上時,景物呈紅色。但若用一束綠光或藍光照耀該景物,則它將呈黑色。

若已知入射光在每一波長上的強弱和物體表面在各波長上對光的汲取率,即給出入射光的光譜分布以及物體表面的反射率和透射率的光譜分布,我們就能依據(jù)環(huán)境的光源布置和景物表面的材料屬性正確計算出景物表面反射光和透射光的光強和顏色。物體表面的反射光可分為漫反射光和鏡面反射光。漫反射光可以認為是光穿過物體表面層被部分汲取后,重新放射出來的光。因此,漫反射光勻稱地散布在各個方向,觀看者不論站在哪一方位上,他所觀看到的漫射光的強度均相等。鏡面反射光則是物體的外表面對入射光的直接反射。鏡面反射光亮度沿鏡面反射主方向最強,在該主方向四周則漸漸衰減,形成肯定的空間分布,因而,觀看者只有位于肯定方向上,才能看到光明的鏡面反射光。以上就是構(gòu)成局部光照模型的基本思想。依據(jù)這個思想,可以得到基本的光照模型。局部光照模型通常假定光源為點光源,物體為非透亮?????體。因此,透射光和散射光可忽視不記。計算光照時只需計算反射光。

常用的局部模型有Lamber漫反射光照模型和Phong局部光照模型。9.2.2Lambert漫反射光照模型概述

自然界的絕大多數(shù)景物為抱負漫反射體,Lambert余弦定律總結(jié)了一個抱負漫反射物體在點光源照耀下的反射規(guī)律,這就是Lambert漫反射模型。依據(jù)Lambert定律,一個抱負漫反射物體表面上反射出來的漫反射光的強度同入射光與物體表面法向量之間的余弦成正比,即:

I?kdIlcosθ

其中,I為景物表面在被照耀點P處的漫反射光的光亮度,Il為點光源所發(fā)出的入射光亮度,kd為景物表面的漫反射率,?為入射光與表面法向量之間的夾角,如圖9.2所示。

若景物表面在被照耀點P處的單位法向量為N,P到點光源的單位向量為L,則上式可表達為如下的向量形式:

I?kdIl(N?L)

明顯,當點光源離被照耀表面很遠時,上式中的向量L變化很小,因而可將L看作為一常向量。我們稱此時的點光源為方向光,它由一向量完全確定??芍斎肷浣?大于?時,光源位于物體背面,因而該光源對被照耀點的光亮度貢

2獻為零,而當入射角?為零度時,光源垂直照耀在景物表面上,此時反射光的強度最大。由不同材料構(gòu)成的景物表面具有不同的漫反射率,漫反射率的大小標志了景物表面對四周反射光線的力量的大小。在入射光強度相同的狀況下,漫反射率越大的景物,看上去越亮。

在實際場景中,物體不僅接收光源發(fā)出的光,還會接收到從四周環(huán)境投射來的光,如房間的墻壁、天空等。在圖形學中,稱這部分光為環(huán)境光或泛光。環(huán)境光是一種分布光源,精確模擬它特別耗時。在局部光照模型中,常假定環(huán)境反射光是勻稱入射的漫反射光,并用一常數(shù)來表示其強度。這樣,Lambert漫反射光照模型可寫成:

I?kaIa?kdIl(N?L)

其中,Ia為入射的泛光光強,ka為景物表面對泛光的漫反射系數(shù)。在上面的公式里沒有反映出光的距離衰減效應。光的傳播以距離平方衰減,即某處入射光的強度與該點和光源間的距離平方成反比。為了模擬光的距離衰減效應,可以采納線形衰減模型:

I?kaIa?kdIld?k(N?L)

其中,d為光源到景物的距離,k為一任意常數(shù)。

通??刹杉{以下的Lambert漫反射模型來模擬光的各種距離衰減效果:

I?kaIa?fkd(N?L)

??1?f?max,1??c?cd?cd2?23?1?其中,f為光源強度衰減因子,c1、c2和c3為用戶確定的常數(shù)。上述模型可以推廣到多光源情形,只需將這些點光源對景物表面的光亮度貢

獻逐個累加起來。此時,Lambert漫反射模型為:

MI?kaIa?kd?i?1fiIli(N?Li)

其中,fi,Ili,Li分別為第i個光源強度衰減因子、光強和單位入射方向的向量。

9.2.3Lambert漫反射光照模型的實現(xiàn)

在應用程序項目中添加一個新類CReality,我們在該類中實現(xiàn)光照模型。為了定義光源的相關屬性,需要定義如下結(jié)構(gòu):

//光源參數(shù)

structLightParam{

doublem_distance;//光源距離doublec1;//距離衰減系數(shù)c1doublec2;//距離衰減系數(shù)c2doublec3;//距離衰減系數(shù)c3

doubleirl;//入射光紅顏色重量強度doubleigl;//入射光綠顏色重量強度doubleibl;//入射光藍顏色重量強度doublexn,yn,zn;//入射單位方向向量doublef;//距離衰減};

該結(jié)構(gòu)中的各個成員變量打算了光源的相關屬性。

為了實現(xiàn)Lambert漫反射模型,需要在CReality類中添加如下的成員變量和成員函數(shù):

public:

CArraym_SurfaceList;//景物表面三角面列表CArraym_ParamList;//景物表面參數(shù)列表CArraym_LightList;//光源參數(shù)列表doublelxn,lyn,lzn;//視點向量intm_count;//景物數(shù)量

doubleira;//泛光中紅色光重量的強度doubleiga;//泛光中綠色光重量的強度doubleiba;//泛光中藍色光重量的強度public:

voidAddObject3D(CObject3D*pObject);//添加景物voidAddLight(LightParamlightParam);//添加光源//設置泛光強度

voidSetIA(doubler,doubleg,doubleb);//計算傳入兩個向量夾角余弦值

doubleGetVectorPM(doublexn1,doubleyn1,doublezn1,doublexn2,doubleyn2,doublezn2);

//計算投影點

CPointProjection(Point3Dpoint3d);//Lambert漫反射光照模型實現(xiàn)函數(shù)voidLambert(CDC*pDC);

voidClear;//清除當前景物和光源

成員變量和成員函數(shù)的含義可以看相應的解釋。下面分別介紹每個成員函數(shù)的實現(xiàn)。

函數(shù)AddObject3D用于添加要計算光照的景物,其實現(xiàn)代碼如下:voidCReality::AddObject3D(CObject3D*pObject){

m_count++;

for(inti=0;im_SurfaceList.GetSize;i++){TriSurfacesurface=(TriSurface)pObject->m_SurfaceList.GetAt(i);//背向視點方向的面不行見if(GetVectorPM(surface.xn,surface.yn,surface.zn,lxn,lyn,lzn)>=0){surface.no=m_count;//設置當前面對應的光照參數(shù)m_SurfaceList.Add(surface);}}

//設置景物參數(shù)

m_ParamList.Add(pObject->m_Param);}

實現(xiàn)代碼中需要說明的是,對于景物表面進行三角剖分得到的三角面片來說,假如該面片的單位法向量與視線的單位方向向量的夾角余弦值小于0,表示該面片背向于觀看者,所以不用計算其光照。

函數(shù)AddLight用于添加光源,其實現(xiàn)代碼如下:voidCReality::AddLight(LightParamlightParam){

//計算距離衰減

doublef=1.0/(lightParam.c1+lightParam.c2*lightParam.m_distance+lightParam.c3*lightParam.m_distance*lightParam.m_distance);

if(f1)f=1.0;lightParam.f=f;

//添加到光源列表中

m_LightList.Add(lightParam);}

在添加光源的同時,將光源的距離衰減值計算了出來。

函數(shù)SetIA用于設置泛光強度,其三個參數(shù)代表了泛光中三個顏色重量的強度,其實現(xiàn)代碼如下:

voidCReality::SetIA(doubler,doubleg,d

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 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

提交評論