球體Phong光照模型課程設計報告(共10頁)_第1頁
球體Phong光照模型課程設計報告(共10頁)_第2頁
球體Phong光照模型課程設計報告(共10頁)_第3頁
球體Phong光照模型課程設計報告(共10頁)_第4頁
球體Phong光照模型課程設計報告(共10頁)_第5頁
已閱讀5頁,還剩5頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

1、精選優質文檔-傾情為你奉上計算機圖形學課程設計 課程設計 球體Phong光照模型一、實驗目的 (1)掌握雙線性法矢插值模型; (2)掌握ZBuffer算法的思想; (3)掌握有效邊表填充算法; 二、實驗要求1、建立三維坐標系Oxyz,原點位于屏幕客戶區中心,x軸水平向右為正,y軸垂直向上為正,z軸垂直于屏幕指向觀察者。2、繪制體心和坐標系中心重合的球體表面,使用Z-Buffer消隱算法進行消隱。3、使用單點光源對球體進行照射生成Phong光照模型,光源位置位于球體右上方。4、背景色設置為RGB(128,0,0)。5、使用鍵盤方向鍵旋轉球體。6、使用鼠標左擊縮小球體、右擊增大球體。三、實驗步驟

2、建立球體的網格模型,使用地理劃分法將球體北極和南極劃分為三角形面片,其余部分劃分為四邊形面片,先對球體網格模型進行背面剔除,然后使用深度緩沖算法進行消隱。計算面片各頂點的平均法矢量,然后采用雙線性法失插值計算面片內各點的法矢量。最終根據每點的法矢量對光源的朝向,通過簡單光照模型計算所獲得的光強。面片使用有效邊表算法填1、Phong雙線性法矢插值模型Gouraud雙線性光強插值模型解決了相鄰多邊形之間的顏色突變問題,產生的真實感圖形顏色過渡均勻,圖形顯得非常光滑,這是它的優點,但是,由于采用光強插值,其鏡面反射光效果不太理想,而且相鄰多邊形邊界處的馬赫帶效應并不能完全消除。Phong模型提出的雙

3、線性法矢插值模型可以有效的解決上述問題,產生正確的高光區域。Phong模型在進行光強插值的時候,需要先對面片的每一個頂點計算平均法矢量,然后通過雙線性法矢插值計算面片內每個點的法矢量,最后根據簡單光照模型計算面片上各點的顏色值。基本算法如下。(1)計算面片頂點的平均法矢量。由于球心位于三維坐標系原點,所以球面上任意面片的頂點平均法矢量就是該點的位置矢量。(2)計算面片內部各點的法矢量。在圖中,三角形面片的頂點坐標為,法矢量為;法矢量是;任一掃面線于三角形邊 ;為進行雙線性值插值計算三角形內點F的法矢量。邊邊上任意一點A點的法矢量可以通過拉格朗日線性插值法得到: 邊邊上B點的法矢量通過拉格朗日線

4、性插值法得到: 掃描線AB上F點的法矢量通過拉格朗日線性插值法得到: (3)對面片內的每一點根據簡單光照模型計算光強,獲得該點顏色。y A F B 2、修改CAET類 在CAET類內不僅包含邊的起點坐標和終點坐標,同時增加起點和終點的法矢量。3、修改CZBuffer類在CZBuffer類先對面片每個點的法矢量進行雙線性插值獲得面片內每一點的法矢量,然后再調用簡單光照模型計算面片內每點的光強。4、光照環境初始化在CTestView類的構造函數內設置光源個數為1,位于右上方,材質顏色為紅色。5、繪制球面函數 使用Phong雙線性法矢量插值模型時,需要計算每個面片上的矢法量。定義了Normal3數組

5、存儲三角形面片的頂點法矢量,定義了Normal4數組存儲四邊形面片的頂點法矢量。4、 程序核心代碼及思路1、程序設計中的主要思路及所使用的主要類 在程序設計中,使用Phong雙線性法矢量插值模型時,計算每個面片的頂點坐標,同時計算每個面片的頂點法矢量。在CZBuffer類內定義了雙線性法矢量插值函數Interpolation()計算面片內的每個點的法矢量。根據面片內每一點的法矢量調用CLighting類的成員函數Lighing()計算該點的光強。并在MyView構造函數中調用了透視變化初始化函數 InitParameter(); 構造頂點表函數ReadPoint(); 構造面表函數ReadFa

6、ce(); 在OnDraw()函數中使用雙緩沖函數 ,并使用繪制球面函數DrawObject() 函數,畫出球體模型。設計使用的類如下: (1)顏色類:CRGB 成員函數:Normalize() 將顏色分量red 、green、blue 規范化到 0, 1閉區間內。 (2)定義矢量類:CVector 成員函數: double Mold() 求矢量的模CVector Unit() 單位矢量 功能: 在類中重載 +、-、*、 等運算符,并利用Dot ()計算矢量點積 。 (3)定義邊節點類:CAET 和 定義桶節點類:CBucket 設置當前掃描線與有效邊的交點的橫坐標 x 定義掃描線 ScanL

7、ine 來求 圖形與有效邊表的交點 (4)設計光源類: CLight void SetDiffuse(CRGB); 設置光源的漫反射光 void SetSpecular(CRGB); 設置光源的鏡面反射光 void SetPosition(double,double,double); 設置光源的直角坐標系 void SetGlobal(double,double,double); 設置光源的球坐標 void SetCoef(double,double,double); 設置光強的衰減系數 void SetOnOff(bool); 設置光源開關狀態 void GlobalToXYZ(); 球坐標

8、轉換為直角坐標 (5)設計材質類: CMaterial void SetAmbient(CRGB); 設置材質對環境光的反射率 void SetDiffuse(CRGB); 設置材質對漫反射光的反射率 void SetSpecular(CRGB); 設置材質對鏡面反射光的反射率 void SetEmit(CRGB); 設置材質自身輻射的顏色 void SetExp(double); 設置材質的高光指數 (6)、設置光照類: CLighting 功能: 在類中定義了光照函數Lighting (),計算物體表面網格頂點所獲得的光照函數 。在該函數中分五步來實現網格頂點的光亮度,第一,累加漫反射光的

9、顏色;第二,累加鏡面反射光的顏色;第三,進行光強衰減;第四,加入環境光;第五,返回所計算頂點的光強顏色。 (7)、定義CZBuffer 類: void CreateBucket(); 在函數中使用CBucket 類創建桶節點 void CreateEdge(); 在函數中使用CAET 類創建邊表 void Phong(CDC *pDC,CPi3 ViewPoint,CLighting *pLight,CMaterial *pMaterial); Phong 填充函數 void InitDeepBuffer(int,int,double); 初始化深度緩存 CVector Interpolati

10、on(double,double,double,CVector,CVector); 法矢量線性插值 (2)程序中使用的重要函數及部分代碼:(1)、構造球體頂點表函數 ReadPoint () 在函數中定義了片面夾角為 gafa=gbeta= 10; 緯度區域為 N1=180/gafa=18,經度區域 N2=360/gbeta=36 ; 利用數組 P(N1-1)*N2+2設置的球體共有616個頂點,經緯網格的夾角為 10。利用:P0.x=0,P0.y=r,P0.z=0; 計算北極點坐標利用如下代碼計算球體上的點坐標: for(int i=0;iN1-1;i+)gafa1=(i+1)*gafa*3

11、.14/180;for(int j=0;jN2;j+)gbeta1=j*gbeta*3.14/180;Pi*N2+j+1.x=r*sin(gafa1)*sin(gbeta1);Pi*N2+j+1.y=r*cos(gafa1);Pi*N2+j+1.z=r*sin(gafa1)*cos(gbeta1);利用:P(N1-1)*N2+1.x=0,P(N1-1)*N2+1.y=-r,P(N1-1)*N2+1.z=0;計算南極點坐標 (2)、構造面片表函數 ReadFace() 面片用二維數組表示,第一維按維度自北極向南極增加的方向定義,第二維在同一緯度帶上z 軸正向開始,按逆時針方向定義。球體共有N1*

12、N2 個面,北極和南極各有N2 個面,其余部分有 (N1-2)*N2個面片 。具體實現代碼和算法見源程序。構造北極三角形面片代碼:for(int j=0;jN2;j+)int tempj=j+1;if(tempj=N2) tempj=0;int NorthIndex3;NorthIndex0=0;NorthIndex1=j+1;NorthIndex2=tempj+1;F0j.SetEN(3);for(int k=0;kF0j.En;k+)F0j.pk=NorthIndexk;F0j.SetNormal(PNorthIndex0,PNorthIndex1,PNorthIndex2);構造球體四邊

13、形面片代碼: for(int i=1;iN1-1;i+)for(int j=0;jN2;j+)int tempi=i+1;int tempj=j+1;if(tempj=N2) tempj=0;int BodyIndex4;BodyIndex0=(i-1)*N2+j+1;BodyIndex1=(tempi-1)*N2+j+1;BodyIndex2=(tempi-1)*N2+tempj+1;BodyIndex3=(i-1)*N2+tempj+1;Fij.SetEN(4);for(int k=0;kFij.En;k+)Fij.pk=BodyIndexk;Fij.SetNormal(PBodyInde

14、x0,PBodyIndex1,PBodyIndex2); (3)、繪制球體函數 DrawObject (CDC *pDC) 使用Z-Buffer 算法對球面進行深度消隱,然后使用有效邊表算法進行填充,為減少渲染的面片數,先使用凸多面體消隱算法對球體不可見面片進行剔除。然后使用Z-Buffer 算法對可見面進行消隱,最后使用有效邊表算法進行填充。在函數中,使用Phong雙線性法矢量插值模型,計算每個面片上的矢法量。定義了Normal3數組存儲三角形面片的頂點法矢量,定義了Normal4數組存儲四邊形面片的頂點法矢量。 (4)、使用鍵盤方向鍵OnKeyDown(UINT nChar, UINT n

15、RepCnt, UINT nFlags)消息響應窗口函數,代碼如下: if(!Play)switch(nChar)case VK_UP: 使用 Phi 每次自減5 ,按向上鍵使球體向里旋轉 Phi=Phi-5; break;case VK_DOWN: 使用 Phi 每次自加5 ,按向下鍵使球體向外旋轉Phi=Phi+5; break; case VK_LEFT: 使用 Theta 每次自加5 ,按向左鍵使球體向左旋轉Theta=Theta+5; break;case VK_RIGHT: 使用 Theta 每次自減5 ,按向左鍵使球體向右旋轉 Theta=Theta-5;break;defaul

16、t: break; InitParameter();DoubleBuf(); (5)、使用鼠標左右點擊窗口響應函數,對球體進行放大和縮小 void CMyView:OnLButtonDblClk(UINT nFlags, CPoint point) R=R+30; 在鼠標左擊函數中視點半徑每次增加30,使球體縮小DoubleBuf();CView:OnLButtonDblClk(nFlags, point);void CMyView:OnRButtonDblClk(UINT nFlags, CPoint point) R=R-30; 在鼠標右擊函數中視點半徑每次減少30,使球體增大DoubleBuf();CView:OnRButtonDblClk(nFlags, point); 五、程序運行結果 (1)當球體半徑r=150,面片夾角=10,緯度區間N1=18,經度區間N2=36時,球體共有(N1-1)*N2+2=616個頂點,其運行結果如圖:(2)使用鍵盤方向向左旋轉球體,Theta=Theta+10 所

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論