• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            使用光照來表現(xiàn)立體感(轉(zhuǎn))

            今天要講的是OpenGL光照的基本知識(shí)。雖然內(nèi)容顯得有點(diǎn)多,但條理還算比較清晰,理解起來應(yīng)該沒有困難。即使對(duì)于一些內(nèi)容沒有記住,問題也不大——光照部分是一個(gè)比較獨(dú)立的內(nèi)容,它的學(xué)習(xí)與其它方面的學(xué)習(xí)可以分開,不像視圖變換那樣,影響到許多方面。課程的最后給出了一個(gè)有關(guān)光照效果的動(dòng)畫演示程序,我想大家會(huì)喜歡的。
            從生理學(xué)的角度上講,眼睛之所以看見各種物體,是因?yàn)楣饩€直接或間接的從它們那里到達(dá)了眼睛。人類對(duì)于光線強(qiáng)弱的變化的反應(yīng),比對(duì)于顏色變化的反應(yīng)來得靈敏。因此對(duì)于人類而言,光線很大程度上表現(xiàn)了物體的立體感。
            請(qǐng)看圖1,圖中繪制了兩個(gè)大小相同的白色球體。其中右邊的一個(gè)是沒有使用任何光照效果的,它看起來就像是一個(gè)二維的圓盤,沒有立體的感覺。左邊的一個(gè)是使用了簡(jiǎn)單的光照效果的,我們通過光照的層次,很容易的認(rèn)為它是一個(gè)三維的物體。
            http://blog.programfan.com/upfile/200702/2007022315149.jpg
            圖1

            OpenGL對(duì)于光照效果提供了直接的支持,只需要調(diào)用某些函數(shù),便可以實(shí)現(xiàn)簡(jiǎn)單的光照效果。但是在這之前,我們有必要了解一些基礎(chǔ)知識(shí)。
            一、建立光照模型
            在現(xiàn)實(shí)生活中,某些物體本身就會(huì)發(fā)光,例如太陽(yáng)、電燈等,而其它物體雖然不會(huì)發(fā)光,但可以反射來自其它物體的光。這些光通過各種方式傳播,最后進(jìn)入我們的眼睛——于是一幅畫面就在我們的眼中形成了。
            就目前的計(jì)算機(jī)而言,要準(zhǔn)確模擬各種光線的傳播,這是無法做到的事情。比如一個(gè)四面都是粗糙墻壁的房間,一盞電燈所發(fā)出的光線在很短的時(shí)間內(nèi)就會(huì)經(jīng)過非常多次的反射,最終幾乎布滿了房間的每一個(gè)角落,這一過程即使使用目前運(yùn)算速度最快的計(jì)算機(jī),也無法精確模擬。不過,我們并不需要精確的模擬各種光線,只需要找到一種近似的計(jì)算方式,使它的最終結(jié)果讓我們的眼睛認(rèn)為它是真實(shí)的,這就可以了。
            OpenGL在處理光照時(shí)采用這樣一種近似:把光照系統(tǒng)分為三部分,分別是光源、材質(zhì)和光照環(huán)境。光源就是光的來源,可以是前面所說的太陽(yáng)或者電燈等。材質(zhì)是指接受光照的各種物體的表面,由于物體如何反射光線只由物體表面決定(OpenGL中沒有考慮光的折射),材質(zhì)特點(diǎn)就決定了物體反射光線的特點(diǎn)。光照環(huán)境是指一些額外的參數(shù),它們將影響最終的光照畫面,比如一些光線經(jīng)過多次反射后,已經(jīng)無法分清它究竟是由哪個(gè)光源發(fā)出,這時(shí),指定一個(gè)“環(huán)境亮度”參數(shù),可以使最后形成的畫面更接近于真實(shí)情況。
            在物理學(xué)中,光線如果射入理想的光滑平面,則反射后的光線是很規(guī)則的(這樣的反射稱為鏡面反射)。光線如果射入粗糙的、不光滑的平面,則反射后的光線是雜亂的(這樣的反射稱為漫反射)。現(xiàn)實(shí)生活中的物體在反射光線時(shí),并不是絕對(duì)的鏡面反射或漫反射,但可以看成是這兩種反射的疊加。對(duì)于光源發(fā)出的光線,可以分別設(shè)置其經(jīng)過鏡面反射和漫反射后的光線強(qiáng)度。對(duì)于被光線照射的材質(zhì),也可以分別設(shè)置光線經(jīng)過鏡面反射和漫反射后的光線強(qiáng)度。這些因素綜合起來,就形成了最終的光照效果。

            二、法線向量
            根據(jù)光的反射定律,由光的入射方向和入射點(diǎn)的法線就可以得到光的出射方向。因此,對(duì)于指定的物體,在指定了光源后,即可計(jì)算出光的反射方向,進(jìn)而計(jì)算出光照效果的畫面。在OpenGL中,法線的方向是用一個(gè)向量來表示。
            不幸的是,OpenGL并不會(huì)根據(jù)你所指定的多邊形各個(gè)頂點(diǎn)來計(jì)算出這些多邊形所構(gòu)成的物體的表面的每個(gè)點(diǎn)的法線(這話聽著有些迷糊),通常,為了實(shí)現(xiàn)光照效果,需要在代碼中為每一個(gè)頂點(diǎn)指定其法線向量。
            指定法線向量的方式與指定顏色的方式有雷同之處。在指定顏色時(shí),只需要指定每一個(gè)頂點(diǎn)的顏色,OpenGL就可以自行計(jì)算頂點(diǎn)之間的其它點(diǎn)的顏色。并且,顏色一旦被指定,除非再指定新的顏色,否則以后指定的所有頂點(diǎn)都將以這一向量作為自己的顏色。在指定法線向量時(shí),只需要指定每一個(gè)頂點(diǎn)的法線向量,OpenGL會(huì)自行計(jì)算頂點(diǎn)之間的其它點(diǎn)的法線向量。并且,法線向量一旦被指定,除非再指定新的法線向量,否則以后指定的所有頂點(diǎn)都將以這一向量作為自己的法線向量。使用glColor*函數(shù)可以指定顏色,而使用glNormal*函數(shù)則可以指定法線向量。
            注意:使用glTranslate*函數(shù)或者glRotate*函數(shù)可以改變物體的外觀,但法線向量并不會(huì)隨之改變。然而,使用glScale*函數(shù),對(duì)每一坐標(biāo)軸進(jìn)行不同程度的縮放,很有可能導(dǎo)致法線向量的不正確,雖然OpenGL提供了一些措施來修正這一問題,但由此也帶來了各種開銷。因此,在使用了法線向量的場(chǎng)合,應(yīng)盡量避免使用glScale*函數(shù)。即使使用,也最好保證各坐標(biāo)軸進(jìn)行等比例縮放。

            三、控制光源
            在OpenGL中,僅僅支持有限數(shù)量的光源。使用GL_LIGHT0表示第0號(hào)光源,GL_LIGHT1表示第1號(hào)光源,依次類推,OpenGL至少會(huì)支持8個(gè)光源,即GL_LIGHT0到GL_LIGHT7。使用glEnable函數(shù)可以開啟它們。例如,glEnable(GL_LIGHT0);可以開啟第0號(hào)光源。使用glDisable函數(shù)則可以關(guān)閉光源。一些OpenGL實(shí)現(xiàn)可能支持更多數(shù)量的光源,但總的來說,開啟過多的光源將會(huì)導(dǎo)致程序運(yùn)行速度的嚴(yán)重下降,玩過3D Mark的朋友可能多少也有些體會(huì)。一些場(chǎng)景中可能有成百上千的電燈,這時(shí)可能需要采取一些近似的手段來進(jìn)行編程,否則以目前的計(jì)算機(jī)而言,是無法運(yùn)行這樣的程序的。
            每一個(gè)光源都可以設(shè)置其屬性,這一動(dòng)作是通過glLight*函數(shù)完成的。glLight*函數(shù)具有三個(gè)參數(shù),第一個(gè)參數(shù)指明是設(shè)置哪一個(gè)光源的屬性,第二個(gè)參數(shù)指明是設(shè)置該光源的哪一個(gè)屬性,第三個(gè)參數(shù)則是指明把該屬性值設(shè)置成多少。光源的屬性眾多,下面將分別介紹。
            (1)GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR屬性。這三個(gè)屬性表示了光源所發(fā)出的光的反射特性(以及顏色)。每個(gè)屬性由四個(gè)值表示,分別代表了顏色的R, G, B, A值。GL_AMBIENT表示該光源所發(fā)出的光,經(jīng)過非常多次的反射后,最終遺留在整個(gè)光照環(huán)境中的強(qiáng)度(顏色)。GL_DIFFUSE表示該光源所發(fā)出的光,照射到粗糙表面時(shí)經(jīng)過漫反射,所得到的光的強(qiáng)度(顏色)。GL_SPECULAR表示該光源所發(fā)出的光,照射到光滑表面時(shí)經(jīng)過鏡面反射,所得到的光的強(qiáng)度(顏色)。
            (2)GL_POSITION屬性。表示光源所在的位置。由四個(gè)值(X, Y, Z, W)表示。如果第四個(gè)值W為零,則表示該光源位于無限遠(yuǎn)處,前三個(gè)值表示了它所在的方向。這種光源稱為方向性光源,通常,太陽(yáng)可以近似的被認(rèn)為是方向性光源。如果第四個(gè)值W不為零,則X/W, Y/W, Z/W表示了光源的位置。這種光源稱為位置性光源。對(duì)于位置性光源,設(shè)置其位置與設(shè)置多邊形頂點(diǎn)的方式相似,各種矩陣變換函數(shù)例如:glTranslate*、glRotate*等在這里也同樣有效。方向性光源在計(jì)算時(shí)比位置性光源快了不少,因此,在視覺效果允許的情況下,應(yīng)該盡可能的使用方向性光源。
            (3)GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF屬性。表示將光源作為聚光燈使用(這些屬性只對(duì)位置性光源有效)。很多光源都是向四面八方發(fā)射光線,但有時(shí)候一些光源則是只向某個(gè)方向發(fā)射,比如手電筒,只向一個(gè)較小的角度發(fā)射光線。GL_SPOT_DIRECTION屬性有三個(gè)值,表示一個(gè)向量,即光源發(fā)射的方向。GL_SPOT_EXPONENT屬性只有一個(gè)值,表示聚光的程度,為零時(shí)表示光照范圍內(nèi)向各方向發(fā)射的光線強(qiáng)度相同,為正數(shù)時(shí)表示光照向中央集中,正對(duì)發(fā)射方向的位置受到更多光照,其它位置受到較少光照。數(shù)值越大,聚光效果就越明顯。GL_SPOT_CUTOFF屬性也只有一個(gè)值,表示一個(gè)角度,它是光源發(fā)射光線所覆蓋角度的一半(見圖2),其取值范圍在0到90之間,也可以取180這個(gè)特殊值。取值為180時(shí)表示光源發(fā)射光線覆蓋360度,即不使用聚光燈,向全周圍發(fā)射。
            http://blog.programfan.com/upfile/200702/20070223151415.gif
            圖2

            (4)GL_CONSTANT_ATTENUATION、GL_LINEAR_ATTENUATION、GL_QUADRATIC_ATTENUATION屬性。這三個(gè)屬性表示了光源所發(fā)出的光線的直線傳播特性(這些屬性只對(duì)位置性光源有效)。現(xiàn)實(shí)生活中,光線的強(qiáng)度隨著距離的增加而減弱,OpenGL把這個(gè)減弱的趨勢(shì)抽象成函數(shù):
            衰減因子 = 1 / (k1 + k2 * d + k3 * k3 * d)
            其中d表示距離,光線的初始強(qiáng)度乘以衰減因子,就得到對(duì)應(yīng)距離的光線強(qiáng)度。k1, k2, k3分別就是GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION。通過設(shè)置這三個(gè)常數(shù),就可以控制光線在傳播過程中的減弱趨勢(shì)。

            屬性還真是不少。當(dāng)然了,如果是使用方向性光源,(3)(4)這兩類屬性就不會(huì)用到了,問題就變得簡(jiǎn)單明了。
            四、控制材質(zhì)
            材質(zhì)與光源相似,也需要設(shè)置眾多的屬性。不同的是,光源是通過glLight*函數(shù)來設(shè)置的,而材質(zhì)則是通過glMaterial*函數(shù)來設(shè)置的。
            glMaterial*函數(shù)有三個(gè)參數(shù)。第一個(gè)參數(shù)表示指定哪一面的屬性。可以是GL_FRONT、GL_BACK或者GL_FRONT_AND_BACK。分別表示設(shè)置“正面”“背面”的材質(zhì),或者兩面同時(shí)設(shè)置。(關(guān)于“正面”“背面”的內(nèi)容需要參看前些課程的內(nèi)容)第二、第三個(gè)參數(shù)與glLight*函數(shù)的第二、三個(gè)參數(shù)作用類似。下面分別說明glMaterial*函數(shù)可以指定的材質(zhì)屬性。
            (1)GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR屬性。這三個(gè)屬性與光源的三個(gè)對(duì)應(yīng)屬性類似,每一屬性都由四個(gè)值組成。GL_AMBIENT表示各種光線照射到該材質(zhì)上,經(jīng)過很多次反射后最終遺留在環(huán)境中的光線強(qiáng)度(顏色)。GL_DIFFUSE表示光線照射到該材質(zhì)上,經(jīng)過漫反射后形成的光線強(qiáng)度(顏色)。GL_SPECULAR表示光線照射到該材質(zhì)上,經(jīng)過鏡面反射后形成的光線強(qiáng)度(顏色)。通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以達(dá)到比較真實(shí)的效果。使用GL_AMBIENT_AND_DIFFUSE可以同時(shí)設(shè)置GL_AMBIENT和GL_DIFFUSE屬性。
            (2)GL_SHININESS屬性。該屬性只有一個(gè)值,稱為“鏡面指數(shù)”,取值范圍是0到128。該值越小,表示材質(zhì)越粗糙,點(diǎn)光源發(fā)射的光線照射到上面,也可以產(chǎn)生較大的亮點(diǎn)。該值越大,表示材質(zhì)越類似于鏡面,光源照射到上面后,產(chǎn)生較小的亮點(diǎn)。
            (3)GL_EMISSION屬性。該屬性由四個(gè)值組成,表示一種顏色。OpenGL認(rèn)為該材質(zhì)本身就微微的向外發(fā)射光線,以至于眼睛感覺到它有這樣的顏色,但這光線又比較微弱,以至于不會(huì)影響到其它物體的顏色。
            (4)GL_COLOR_INDEXES屬性。該屬性僅在顏色索引模式下使用,由于顏色索引模式下的光照比RGBA模式要復(fù)雜,并且使用范圍較小,這里不做討論。

            五、選擇光照模型
            這里所說的“光照模型”是OpenGL的術(shù)語(yǔ),它相當(dāng)于我們?cè)谇懊嫣岬降?#8220;光照環(huán)境”。在OpenGL中,光照模型包括四個(gè)部分的內(nèi)容:全局環(huán)境光線(即那些充分散射,無法分清究竟來自哪個(gè)光源的光線)的強(qiáng)度、觀察點(diǎn)位置是在較近位置還是在無限遠(yuǎn)處、物體正面與背面是否分別計(jì)算光照、鏡面顏色(即GL_SPECULAR屬性所指定的顏色)的計(jì)算是否從其它光照計(jì)算中分離出來,并在紋理操作以后在進(jìn)行應(yīng)用。
            以上四方面的內(nèi)容都通過同一個(gè)函數(shù)glLightModel*來進(jìn)行設(shè)置。該函數(shù)有兩個(gè)參數(shù),第一個(gè)表示要設(shè)置的項(xiàng)目,第二個(gè)參數(shù)表示要設(shè)置成的值。
            GL_LIGHT_MODEL_AMBIENT表示全局環(huán)境光線強(qiáng)度,由四個(gè)值組成。
            GL_LIGHT_MODEL_LOCAL_VIEWER表示是否在近處觀看,若是則設(shè)置為GL_TRUE,否則(即在無限遠(yuǎn)處觀看)設(shè)置為GL_FALSE。
            GL_LIGHT_MODEL_TWO_SIDE表示是否執(zhí)行雙面光照計(jì)算。如果設(shè)置為GL_TRUE,則OpenGL不僅將根據(jù)法線向量計(jì)算正面的光照,也會(huì)將法線向量反轉(zhuǎn)并計(jì)算背面的光照。
            GL_LIGHT_MODEL_COLOR_CONTROL表示顏色計(jì)算方式。如果設(shè)置為GL_SINGLE_COLOR,表示按通常順序操作,先計(jì)算光照,再計(jì)算紋理。如果設(shè)置為GL_SEPARATE_SPECULAR_COLOR,表示將GL_SPECULAR屬性分離出來,先計(jì)算光照的其它部分,待紋理操作完成后再計(jì)算GL_SPECULAR。后者通常可以使畫面效果更為逼真(當(dāng)然,如果本身就沒有執(zhí)行任何紋理操作,這樣的分離就沒有任何意義)。

            六、最后的準(zhǔn)備
            到現(xiàn)在可以說是完事俱備了。不過,OpenGL默認(rèn)是關(guān)閉光照處理的。要打開光照處理功能,使用下面的語(yǔ)句:
            glEnable(GL_LIGHTING);
            要關(guān)閉光照處理功能,使用glDisable(GL_LIGHTING);即可。
            七、示例程序
            到現(xiàn)在,我們已經(jīng)可以編寫簡(jiǎn)單的使用光照的OpenGL程序了。
            我們?nèi)匀灰蕴?yáng)、地球作為例子(這次就不考慮月亮了^-^),把太陽(yáng)作為光源,模擬地球圍繞太陽(yáng)轉(zhuǎn)動(dòng)時(shí)光照的變化。于是,需要設(shè)置一個(gè)光源——太陽(yáng),設(shè)置兩種材質(zhì)——太陽(yáng)的材質(zhì)和地球的材質(zhì)。把太陽(yáng)光線設(shè)置為白色,位置在畫面正中。把太陽(yáng)的材質(zhì)設(shè)置為微微散發(fā)出紅色的光芒,把地球的材質(zhì)設(shè)置為微微散發(fā)出暗淡的藍(lán)色光芒,并且反射藍(lán)色的光芒,鏡面指數(shù)設(shè)置成一個(gè)比較小的值。簡(jiǎn)單起見,不再考慮太陽(yáng)和地球的大小關(guān)系,用同樣大小的球體來代替之。
            關(guān)于法線向量。球體表面任何一點(diǎn)的法線向量,就是球心到該點(diǎn)的向量。如果使用glutSolidSphere函數(shù)來繪制球體,則該函數(shù)會(huì)自動(dòng)的指定這些法線向量,不必再手工指出。如果是自己指定若干的頂點(diǎn)來繪制一個(gè)球體,則需要自己指定法線響亮。
            由于我們使用的太陽(yáng)是一個(gè)位置性光源,在設(shè)置它的位置時(shí),需要利用到矩陣變換。因此,在設(shè)置光源的位置以前,需要先設(shè)置好各種矩陣。利用gluPerspective函數(shù)來創(chuàng)建具有透視效果的視圖。我們也將利用前面課程所學(xué)習(xí)的動(dòng)畫知識(shí),讓整個(gè)畫面動(dòng)起來。

            下面給出具體的代碼:
            #include <gl/glut.h>

            #define WIDTH 400
            #define HEIGHT 400

            static GLfloat angle = 0.0f;

            void myDisplay(void)
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                // 創(chuàng)建透視效果視圖
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

                // 定義太陽(yáng)光源,它是一種白色的光源
                {
                GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f};
                GLfloat sun_light_ambient[]  = {0.0f, 0.0f, 0.0f, 1.0f};
                GLfloat sun_light_diffuse[]  = {1.0f, 1.0f, 1.0f, 1.0f};
                GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

                glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);
                glLightfv(GL_LIGHT0, GL_AMBIENT,  sun_light_ambient);
                glLightfv(GL_LIGHT0, GL_DIFFUSE,  sun_light_diffuse);
                glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);

                glEnable(GL_LIGHT0);
                glEnable(GL_LIGHTING);
                glEnable(GL_DEPTH_TEST);
                }

                // 定義太陽(yáng)的材質(zhì)并繪制太陽(yáng)
                {
                    GLfloat sun_mat_ambient[]  = {0.0f, 0.0f, 0.0f, 1.0f};
                    GLfloat sun_mat_diffuse[]  = {0.0f, 0.0f, 0.0f, 1.0f};
                    GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
                    GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
                    GLfloat sun_mat_shininess  = 0.0f;

                    glMaterialfv(GL_FRONT, GL_AMBIENT,   sun_mat_ambient);
                    glMaterialfv(GL_FRONT, GL_DIFFUSE,   sun_mat_diffuse);
                    glMaterialfv(GL_FRONT, GL_SPECULAR,  sun_mat_specular);
                    glMaterialfv(GL_FRONT, GL_EMISSION,  sun_mat_emission);
                    glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);

                    glutSolidSphere(2.0, 40, 32);
                }

                // 定義地球的材質(zhì)并繪制地球
                {
                    GLfloat earth_mat_ambient[]  = {0.0f, 0.0f, 0.5f, 1.0f};
                    GLfloat earth_mat_diffuse[]  = {0.0f, 0.0f, 0.5f, 1.0f};
                    GLfloat earth_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f};
                    GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
                    GLfloat earth_mat_shininess  = 30.0f;

                    glMaterialfv(GL_FRONT, GL_AMBIENT,   earth_mat_ambient);
                    glMaterialfv(GL_FRONT, GL_DIFFUSE,   earth_mat_diffuse);
                    glMaterialfv(GL_FRONT, GL_SPECULAR,  earth_mat_specular);
                    glMaterialfv(GL_FRONT, GL_EMISSION,  earth_mat_emission);
                    glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);

                    glRotatef(angle, 0.0f, -1.0f, 0.0f);
                    glTranslatef(5.0f, 0.0f, 0.0f);
                    glutSolidSphere(2.0, 40, 32);
                }

                glutSwapBuffers();
            }
            void myIdle(void)
            {
                angle += 1.0f;
                if( angle >= 360.0f )
                    angle = 0.0f;
                myDisplay();
            }

            int main(int argc, char* argv[])
            {
                glutInit(&argc, argv);
                glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
                glutInitWindowPosition(200, 200);
                glutInitWindowSize(WIDTH, HEIGHT);
                glutCreateWindow("OpenGL光照演示");
                glutDisplayFunc(&myDisplay);
                glutIdleFunc(&myIdle);
                glutMainLoop();
                return 0;
            }
            小結(jié):
            本課介紹了OpenGL光照的基本知識(shí)。OpenGL把光照分解為光源、材質(zhì)、光照模式三個(gè)部分,根據(jù)這三個(gè)部分的各種信息,以及物體表面的法線向量,可以計(jì)算得到最終的光照效果。
            光源、材質(zhì)和光照模式都有各自的屬性,盡管屬性種類繁多,但這些屬性都只用很少的幾個(gè)函數(shù)來設(shè)置。使用glLight*函數(shù)可設(shè)置光源的屬性,使用glMaterial*函數(shù)可設(shè)置材質(zhì)的屬性,使用glLightModel*函數(shù)可設(shè)置光照模式。
            GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR這三種屬性是光源和材質(zhì)所共有的,如果某光源發(fā)出的光線照射到某材質(zhì)的表面,則最終的漫反射強(qiáng)度由兩個(gè)GL_DIFFUSE屬性共同決定,最終的鏡面反射強(qiáng)度由兩個(gè)GL_SPECULAR屬性共同決定。
            可以使用多個(gè)光源來實(shí)現(xiàn)各種逼真的效果,然而,光源數(shù)量的增加將造成程序運(yùn)行速度的明顯下降。
            在使用OpenGL光照過程中,屬性的種類和數(shù)量都非常繁多,通常,需要很多的經(jīng)驗(yàn)才可以熟練的設(shè)置各種屬性,從而形成逼真的光照效果。(各位也看到了,其實(shí)這個(gè)課程的示例程序中,屬性設(shè)置也不怎么好)。然而,設(shè)置這些屬性的藝術(shù)性遠(yuǎn)遠(yuǎn)超過了技術(shù)性,往往是一些美術(shù)制作人員設(shè)置好各種屬性(并保存為文件),然后由程序員編寫的程序去執(zhí)行繪制工作。因此,即使目前無法熟練運(yùn)用各種屬性,也不必過于擔(dān)心。如果條件允許,可以玩玩類似3DS MAX之類的軟件,對(duì)理解光照、熟悉各種屬性設(shè)置會(huì)有一些幫助。
            在課程的最后,我們給出了一個(gè)樣例程序,演示了太陽(yáng)和地球模型中的光照效果。

            posted on 2009-01-03 05:59 RedLight 閱讀(642) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 3D渲染技術(shù)

            <2009年1月>
            28293031123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導(dǎo)航

            統(tǒng)計(jì)

            公告


            Name: Galen
            QQ: 88104725

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            相冊(cè)

            My Friend

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久夜色精品国产噜噜麻豆| 久久99精品久久久久久噜噜| 香蕉aa三级久久毛片| 很黄很污的网站久久mimi色| 久久精品国产99国产电影网 | 久久996热精品xxxx| 伊人久久精品线影院| 久久久久久综合一区中文字幕 | 欧美粉嫩小泬久久久久久久| 国产2021久久精品| 久久99热这里只有精品国产| 久久精品视频91| 亚洲欧洲精品成人久久奇米网| 少妇无套内谢久久久久| 日本久久久久亚洲中字幕 | 日本精品久久久久影院日本 | 亚洲欧美另类日本久久国产真实乱对白| 精品免费久久久久国产一区| 久久久久久毛片免费看| 人妻无码αv中文字幕久久琪琪布| 国产精品久久新婚兰兰| 久久国产精品77777| 国产69精品久久久久99| 一级女性全黄久久生活片免费 | 日本精品久久久久影院日本| 伊人久久综合无码成人网| 国产精品久久国产精品99盘 | 天天久久狠狠色综合| 欧洲性大片xxxxx久久久| 亚洲va久久久噜噜噜久久| 国产99久久久久久免费看| 99久久免费国产精品特黄| 久久精品国内一区二区三区| 午夜精品久久久久久| 精品久久久久久久无码| 天堂无码久久综合东京热| www.久久精品| 伊人久久大香线蕉AV色婷婷色| 99久久婷婷国产综合精品草原 | 伊人久久大香线蕉无码麻豆| 青青青青久久精品国产|