圖形學(xué)第十一課--OpenGL特殊光處理_第1頁
圖形學(xué)第十一課--OpenGL特殊光處理_第2頁
圖形學(xué)第十一課--OpenGL特殊光處理_第3頁
圖形學(xué)第十一課--OpenGL特殊光處理_第4頁
圖形學(xué)第十一課--OpenGL特殊光處理_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第十四章 OpenGL特殊光處理 目 錄14.1 光照模型14.2 光源位置與衰減14.3 聚光和多光源14.4 光源位置與方向的控制14.5 輻射光本章內(nèi)容是基礎(chǔ)篇第七章的補(bǔ)充和提高。這一章主要講述一些特殊光效果處理,如全局環(huán)境光、雙面光照、光的衰減、聚光、多光源、光源位置的改變等等。讀者若有興趣,可以按照本章例程的方法作出許多變換,則會(huì)出現(xiàn)意想不到的效果,充分發(fā)揮你的藝術(shù)才能。14.1、光照模型OpenGL光照模型的概念由一下三部分組成:1)全局泛光強(qiáng)度、2)視點(diǎn)位置在景物附近還是在無窮遠(yuǎn)處、3)物體的正面和背面是否分別進(jìn)行光照計(jì)算。14.1.1 全局環(huán)境光正如前面基礎(chǔ)篇中所提到的一樣,每

2、個(gè)光源都能對(duì)一個(gè)場(chǎng)景提供環(huán)境光。此外,還有一個(gè)環(huán)境光,它不來自任何特定的光源,即稱為全局環(huán)境光。下面用參數(shù)GL_LIGHT_MODEL_AMBIENT來說明全局環(huán)境光的RGBA強(qiáng)度:GLfloat lmodel_ambient=0.2,0.2,0.2,1.0;glLightModelfv(GLLIGHT_MODEL_AMBIENT,lmodel_ambient);在這個(gè)例子中,lmodel_ambient所用的值為GL_LIGHT_MODEL_AMBIENT的缺省值。這些數(shù)值產(chǎn)生小量的白色環(huán)境光。14.1.2 近視點(diǎn)與無窮遠(yuǎn)視點(diǎn)視點(diǎn)位置能影響鏡面高光的計(jì)算,也就是說,頂點(diǎn)的高光強(qiáng)度依賴于頂點(diǎn)法

3、向量,從頂點(diǎn)到光源的方向和從頂點(diǎn)到視點(diǎn)的方向。實(shí)際上,調(diào)用光照函數(shù)并不能移動(dòng)視點(diǎn)。但是可以對(duì)光照計(jì)算作出不同的假定,這樣視點(diǎn)似乎移動(dòng)了。對(duì)于一個(gè)無窮遠(yuǎn)視點(diǎn),視點(diǎn)到任何頂點(diǎn)的方向保持固定,缺省時(shí)為無窮遠(yuǎn)視點(diǎn)。對(duì)于一個(gè)近視點(diǎn),物體每個(gè)頂點(diǎn)到視點(diǎn)的方向是不同的,需要逐個(gè)計(jì)算,從而整體性能降低,但效果更真實(shí)。下面一句函數(shù)代碼是假定為近視 點(diǎn):glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE);這個(gè)調(diào)用把視點(diǎn)放在視點(diǎn)坐標(biāo)系的原點(diǎn)處。若要切換到無窮遠(yuǎn)視點(diǎn),只需將參數(shù)GL_TRUE 改為GL_FALSE即可。14.1.3 雙面光照光照計(jì)算通常是對(duì)所有多邊形進(jìn)

4、行的,無論其是正面或反面。一般情況下,設(shè)置光照條件時(shí)總是正面多邊形,因此不能對(duì)背面多邊形進(jìn)行正確地光照。在基礎(chǔ)篇的第七章中的例子里,物體是一個(gè)球,只有正面多邊形能看到,即球的外部可見,這種情況下不必考慮背面光照。若球被砍開,其內(nèi)部的曲面是可見的,那么對(duì)內(nèi)部多邊形需進(jìn)行光照計(jì)算,這時(shí)應(yīng)該調(diào)用如下函數(shù):glLightModeli(LIGHT_MODEL_TWO_SIDE,GL_TRUE);啟動(dòng)雙面光照。實(shí)際上,這就是OpenGL給背面多邊形定義一個(gè)相反的法向量(相對(duì)于正面多邊形而言)。一般來說,這意味著可見正面多邊形和可見反面多邊形的法向量都面朝觀察者,而不是向里,這樣所有多邊形都能進(jìn)行正確的光照

5、。關(guān)閉雙面光照,只需將參數(shù)GL_TRUE改為GL_FALSE即可。14.2、光源位置與衰減在基礎(chǔ)篇中已經(jīng)提到過,光源有無窮遠(yuǎn)光源和近光源兩種形式。無窮遠(yuǎn)光源又稱作定向光源,即這種光到達(dá)物體時(shí)是平行光,例如現(xiàn)實(shí)生活中的太陽光。近光源又稱作定位光源,光源在場(chǎng)景中的位置影響場(chǎng)景的光照效果,尤其影響光到達(dá)物體的方向。臺(tái)燈是定位光源的范例。在以前所有與光照有關(guān)的例子里都采用的是定向光源,如:GLfloat light_position=1.0,1.0,1.0,0.0;glLightfv(GL_LIGHT0,GL_POSITION,light_position);光源位置坐標(biāo)采用的齊次坐標(biāo)(x, y, z

6、, w),這里的w為0,所以相應(yīng)的光源是定向光,(x, y, z)描述光源的方向,這個(gè)方向也要進(jìn)行模型變換。GL_POSITION的缺省值是(0.0, 0.0, 1.0, 0.0),它定義了一個(gè)方向指向Z負(fù)軸的平行光源。若w非零,光源為定位光源。(x, y, z, w)指定光源在齊次坐標(biāo)系下的具體位置,這個(gè)位置經(jīng)過模型變換等在視點(diǎn)坐標(biāo)系下保存下來。真實(shí)的光,離光源越遠(yuǎn)則光強(qiáng)越小。因?yàn)槎ㄏ蚬庠词菬o窮遠(yuǎn)光源,因此距離的變換對(duì)光強(qiáng)的影響幾乎沒有,所以定向光沒有衰減,而定位光有衰減。OpenGL的光衰減是通過光源的發(fā)光量乘以衰減因子計(jì)算出來的。其中衰減因子在第十章表10-2中說明過。缺省狀態(tài)下,常數(shù)衰

7、減因子是1.0,其余兩個(gè)因子都是0.0。用戶也可以自己定義這些值,如:glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,2.0);glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,1.0);glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.5);注意:環(huán)境光、漫反射光和鏡面光的強(qiáng)度都衰減,只有輻射光和全局環(huán)境光的強(qiáng)度不衰減。14.3、聚光和多光源14.3.1 聚光定位光源可以定義成聚光燈形式,即將光的形狀限制在一個(gè)圓錐內(nèi)。OpenGL中聚光的定義有以下幾步:1)定義聚光源位置。因?yàn)榫酃?/p>

8、源也是定向光源,所以他的位置同一般定向光一樣。如:GLfloat light_position=1.0,1.0,1.0,1.0;glLightfv(GL_LIGHT0,LIGHT_POSITION,light_position);2)定義聚光截止角。參數(shù)GL_SPOT_CUTOFF給定光錐的軸與中心線的夾角,也可說成是光錐頂角的一半,如圖14-1所示。缺省時(shí),這個(gè)參數(shù)為180.0,即頂角為360度,光向所有的方向發(fā)射,因此聚光關(guān)閉。一般在聚光啟動(dòng)情況下,聚光截止角限制在0.0, 90.0 之間,如下面一行代碼設(shè)置截止角為45度:glLightf(GL_LIGHT0,GL_SPOT_CUTOFF

9、,45.0);3)定義聚光方向。聚光方向決定光錐的軸,它齊次坐標(biāo)定義,其缺省值為(0.0, 0.0, -1.0),即指向Z負(fù)軸。聚光方向也要進(jìn)行幾何變換,其結(jié)果保存在視點(diǎn)坐標(biāo)系中。它的定義如下:GLfloat spot_direction=-1.0,-1.0,0.0;glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_direction);4)定義聚光指數(shù)。參數(shù)GL_SPOT_EXPONENT控制光的集中程度,光錐中心的光強(qiáng)最大,越靠邊的光強(qiáng)越小,缺省時(shí)為0。如:glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,2.0);此外,除了定義聚

10、光指數(shù)控制光錐內(nèi)光強(qiáng)的分布,還可利用上一節(jié)所講的衰減因子的設(shè)置來實(shí)現(xiàn),因?yàn)樗p因子與光強(qiáng)相乘得最終光強(qiáng)值。14.3.2 多光源及例程在前面已提到過場(chǎng)景中最多可以設(shè)置八個(gè)光源(根據(jù)OpenGL的具體實(shí)現(xiàn)也許會(huì)更多一些)。在多光源情況下,OpenGL需計(jì)算每個(gè)頂點(diǎn)從每個(gè)光源接受的光強(qiáng),這樣會(huì)增加計(jì)算量,降低性能,因此在實(shí)時(shí)仿真中最好盡可能地減少光源數(shù)目。在前面都已討論過八個(gè)光源的常數(shù):GL_LIGHT0、GL_LIGHT1、LIGHT7,注意:GL_LIGHT0的參數(shù)缺省值與其它光源的參數(shù)缺省值不同。下面這段代碼定義了紅色的聚光:GLfloat light1_ambient= 0.2, 0.2,

11、0.2, 1.0 ;GLfloat light1_diffuse= 1.0, 0.0, 0.0, 1.0 ;GLfloat light1_specular = 1.0, 0.6, 0.6, 1.0 ;GLfloat light1_position = -3.0, -3.0, 3.0, 1.0 ;GLfloat spot_direction= 1.0,1.0,-1.0;glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);glLightfv(GL_LIGH

12、T1, GL_SPECULAR,light1_specular);glLightfv(GL_LIGHT1, GL_POSITION,light1_position);glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 30.0);glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,spot_direction);glEnable(GL_LIGHT1);/ 這段代碼描述的是一個(gè)紅色的立方體,用它來代表所定義的聚光光源 / 可加到程序的函數(shù)display()中去。 /glPushMatrix();glTranslated (-3.0, -3.0, 3

13、.0);glDisable (GL_LIGHTING);glColor3f (1.0, 0.0, 0.0);auxWireCube (0.1);glEnable (GL_LIGHTING);glPopMatrix ();/將這些代碼加到基礎(chǔ)篇第十章光照的例程(light2.c)中去:例14-1 聚光和多光源運(yùn)用例程(spmulght.c)#include #include #include #include #include /* 初始化光源、材質(zhì)等 */void myInit (void)GLfloat mat_ambient= 0.2, 0.2, 0.2, 1.0 ;GLfloat mat

14、_diffuse= 0.8, 0.8, 0.8, 1.0 ;GLfloat mat_specular = 1.0, 1.0, 1.0, 1.0 ;GLfloat mat_shininess = 50.0 ;GLfloat light0_diffuse= 0.0, 0.0, 1.0, 1.0;GLfloat light0_position = 1.0, 1.0, 1.0, 0.0 ;GLfloat light1_ambient= 0.2, 0.2, 0.2, 1.0 ;GLfloat light1_diffuse= 1.0, 0.0, 0.0, 1.0 ;GLfloat light1_specu

15、lar = 1.0, 0.6, 0.6, 1.0 ;GLfloat light1_position = -3.0, -3.0, 3.0, 1.0 ;GLfloat spot_direction= 1.0,1.0,-1.0;glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,mat_shi

16、niness);glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);glLightfv(GL_LIGHT0, GL_POSITION,light0_position);glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);glLightfv(GL_LIGHT1, GL_SPECULAR,light1_specular);glLightfv(GL_LIGHT1, GL_POSITION,light1_posit

17、ion);glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 30.0);glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,spot_direction);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_LIGHT1);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);void myReshape(GLsizei w,GLsizei h)glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLo

18、adIdentity();if (w = h)glOrtho (-5.5, 5.5, -5.5*(GLfloat)h/(GLfloat)w, 5.5*(GLfloat)h/(GLfloat)w,-10.0, 10.0);elseglOrtho (-5.5*(GLfloat)w/(GLfloat)h, 5.5*(GLfloat)w/(GLfloat)h,-5.5, 5.5, -10.0, 10.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();void myDisplay(void)glClear(GL_COLOR_BUFFER_BIT | GL_DE

19、PTH_BUFFER_BIT);glPushMatrix();glTranslated (-3.0, -3.0, 3.0);glDisable (GL_LIGHTING);glColor3f (1.0, 0.0, 0.0);auxWireCube (0.1);glEnable (GL_LIGHTING);glPopMatrix ();auxSolidSphere(2.0);glFlush();void main(int argc, char* argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA);glutIni

20、tWindowSize(800,600);glutInitWindowPosition(100,100);glutCreateWindow(Spotlight and Multi_lights);myInit();/glutKeyboardFunc(myKeyboard);glutReshapeFunc(myReshape); glutDisplayFunc(myDisplay);glutMainLoop();以上程序運(yùn)行結(jié)果是球被兩個(gè)光源照射,一個(gè)是藍(lán)色的定向光,另一個(gè)紅色的是聚光。圖14-1 聚光與多光源14.4、光源位置與方向的控制OpenGL光源的位置和方向與其它幾何圖元的位置和方向一

21、樣都必須經(jīng)過變換矩陣的作用。尤其是當(dāng)用glLight*()說明光源的位置和方向時(shí),位置和方向都要經(jīng)過當(dāng)前變換矩陣的作用并保存在視點(diǎn)坐標(biāo)系中,注意投影矩陣變換對(duì)它們不起作用。OpenGL可通過調(diào)整光源函數(shù)和視點(diǎn)變換函數(shù)在程序中的相對(duì)位置來獲得三種不同的效果:1)光源位置保持固定、2)光源繞靜止物體移動(dòng)、3)光源隨視點(diǎn)移動(dòng)。在第一種情況下,為獲得光源位置固定的效果,必須在所有視點(diǎn)和模型變換之后設(shè)置光源位置。第二種情況下,有兩種方法可以達(dá)到這種效果,一種是在模型變換后設(shè)置光源位置,變換的改變將修改光源位置;另一種是使物體和視點(diǎn)繞光源移動(dòng),相對(duì)地光源就能繞物體移動(dòng)了。第三種情況下,要建立一個(gè)沿視線移動(dòng)

22、的光源,必須在視點(diǎn)變換之前設(shè)置光源位置,則視點(diǎn)變換按同樣的方式影響光源和視點(diǎn)。下面有一個(gè)光源移動(dòng)的例子:例14-1 光源移動(dòng)例程(mvlight.c)#include #include #include #include #include static int step = 0;void processMouse (int button, int state, int x, int y)if (state = GLUT_DOWN)if (button = GLUT_LEFT_BUTTON)step = (step + 15) % 360;void myInit (void)GLfloat ma

23、t_diffuse=0.0,0.5,1.0,1.0;GLfloat mat_ambient=0.0,0.2,1.0,1.0;GLfloat light_diffuse=1.0,1.0,1.0,1.0;GLfloat light_ambient=0.0,0.5,0.5,1.0;glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,mat_diffuse);glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);glEnable(GL_LIG

24、HTING);glEnable(GL_LIGHT0);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);void myReshape(GLsizei w,GLsizei h) glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);glMatrixMode(GL_MODELVIEW);void myDisplay(void)GLfloat position = 0

25、.0, 0.0, 1.5, 1.0 ;glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix ();glTranslatef (0.0, 0.0, -5.0);glPushMatrix ();glRotated (GLdouble) step, -1.0, 1.0, 1.0);glRotated (0.0, 1.0, 0.0, 0.0);glLightfv (GL_LIGHT0, GL_POSITION, position);glTranslated (0.0, 0.0, 1.5);glDisable (GL_LIGHTING);glColor3f

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論