• <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>

            天行健 君子當(dāng)自強(qiáng)而不息

            3D圖形數(shù)學(xué)(7)

            幾何體的生成與提交

             

            幾何體的生成與提交

            一旦知道哪些物體可見(或至少潛在可見),即可將其生成并提交到圖形處理器。該階段完成以下任務(wù):

            (1)細(xì)節(jié)層次(LOD)選擇

            (2)漸進(jìn)式生成幾何體

            (3)向圖形API提交數(shù)據(jù)

             

            LOD選擇和漸進(jìn)式生成

            一般我們希望以最大可能的三角形數(shù)量描繪物體以求得最佳的視覺效果,但不幸的是,較多的三角形一般意味著低幀率。我們必須在可接受的外表和幀率間做出折中選擇。LOD在一定程度上可兩全其美,基本思路是離攝像機(jī)遠(yuǎn)的物體只使用較少的多邊形,此時(shí)并不降低視覺效果。

            如何得到三角形數(shù)量較少的三角網(wǎng)?一種簡單方法(從程序員角度)是讓美工直接制作一個(gè),然后根據(jù)物體離攝像機(jī)的遠(yuǎn)近(或屏幕分辨率大小)選用合適的LOD。問題是就在它由遠(yuǎn)及近改變的那一刻,這種方法會(huì)有一種跳動(dòng)效果,當(dāng)然我們希望把這種視覺上的不連續(xù)性降低到最低限度----好的三角網(wǎng)也許會(huì)有更大幫助。

            一種克服跳動(dòng)的方法是引入連續(xù)LOD。這種系統(tǒng)中,不同級(jí)別LOD包含的三角形數(shù)目幾乎是連續(xù)的,我們可以產(chǎn)生任意多三角形的網(wǎng)格。漸進(jìn)式網(wǎng)格技術(shù)就是一種這樣的網(wǎng)格消減技術(shù),但需要注意生成連續(xù)LOD的開支可能會(huì)很顯著。而使用離散LOD,網(wǎng)格是現(xiàn)成可用的,渲染時(shí)可立即投送,我們所要做的就是決定用哪個(gè)網(wǎng)格。所以,即使實(shí)際的網(wǎng)格是用網(wǎng)格的消減技術(shù)生成的,離散LOD還是在實(shí)踐中經(jīng)常使用。

            有時(shí)候幾何體并非由美工創(chuàng)建,而是由計(jì)算機(jī)生成,這稱為程序建模。分形地形圖是程序建模的好例子,植物也可以自動(dòng)創(chuàng)建,有時(shí)LOD也用在此類建模算法中。

             

            向API投送幾何體

            多數(shù)API希望某種形式的三角網(wǎng)格輸入,如單個(gè)三角形,索引三角網(wǎng)格,三角帶或三角扇等。無論哪種形式,數(shù)據(jù)的核心都是頂點(diǎn),三角形不過是頂點(diǎn)合適的連接方式。從另一方面說,API并不需要超過三角形級(jí)別的數(shù)據(jù)。

            API根據(jù)操作的不同接受不同的數(shù)據(jù)格式。(當(dāng)我們說“API如何時(shí)”,是指整個(gè)圖形子系統(tǒng),不論操作是由軟件完成還是硬件完成的。)

            在簡化的情況下,頂點(diǎn)的數(shù)據(jù)一般分為三類:

            (1)位置:描述頂點(diǎn)的位置,可以是3D向量或者有深度信息的2D屏幕坐標(biāo)。如果采用3D向量,還需要用模型、視圖變換做向屏幕映射的工作。另一個(gè)骨骼動(dòng)畫中使用的高級(jí)技術(shù)是skinning,頂點(diǎn)坐標(biāo)由若干骨骼給出。

            (2)光照和霧化:為了渲染,頂點(diǎn)一般都帶有色彩值,然后由這些值插值計(jì)算三角形中各點(diǎn)的顏色。我們可以指定這些值,或者讓API計(jì)算合適的光照值。如果讓API計(jì)算光照,通常要給出頂點(diǎn)法向量。無論如何,顏色均為RGBalpha的元組。如果直接指定顏色,經(jīng)常使用一個(gè)32位的ARGB值,每分量8位,或者為每個(gè)分量使用一個(gè)單獨(dú)的值。如使用硬件霧化,還要指定各點(diǎn)的霧化強(qiáng)度,可以手動(dòng)指定這個(gè)值,也可由API計(jì)算。

            (3)紋理映射坐標(biāo):使用紋理映射時(shí),每個(gè)頂點(diǎn)必須要有紋理映射坐標(biāo)。最簡單的情形下,只需要紋理圖的2D坐標(biāo),常記為(u, v)。當(dāng)使用多重紋理時(shí),每個(gè)紋理都需要一個(gè)坐標(biāo)。有時(shí),可以階段式生成紋理坐標(biāo)(如向表面投射一道光線)。或者,可以階段式地拷貝紋理坐標(biāo)。在這種情況下,就可以不指定紋理坐標(biāo)。

            簡單的說,投送頂點(diǎn)并沒有一個(gè)簡單的格式。事實(shí)上,存在許多變種,如DirectX有可變頂點(diǎn)格式的概念,可使你自定義格式,以最方便的順序保存任何想要的信息。

            有了這些之后,讓我們給出幾個(gè)C++結(jié)構(gòu),記錄上面提到的常用格式。

            最常見的是3D坐標(biāo),表面法向量和紋理映射坐標(biāo),需要API進(jìn)行光照的靜態(tài)紋理映射網(wǎng)格常使用這種格式。

                // Untransformed, unlit vertex
               
            struct RenderVertex 
                {
                    Vector3 p; 
            // position
               
                Vector3 n; // normal
               
                float u,v; // texture mapping coordinates
               
            };

            另一種常用的格式,是用來顯示2D物體或HUD(head up display)的,含有屏幕坐標(biāo)和預(yù)定義的光照。雖然數(shù)據(jù)是2D的,但仍然帶有某種形式的深度信息。

                // Transformed and lit vertex
               
            struct RenderVertexTL 
                {
                    Vector3 p;        
            // screen space position and depth
               
                float w;        // 1/z
               
                unsigned argb;    // prelit diffuse color (8 bits per component – 0xAARRGGBB)
               
                unsigned spec;    // prelit specular color
               
                float u,v;        // texture mapping coordinates
               
            };

            最后一個(gè)例子是某種3D頂點(diǎn),但不需要圖形API的光照引擎照亮,它自帶預(yù)定義的光照。這種格式經(jīng)常用于特效,如爆炸、火焰、發(fā)光物等,以及調(diào)試用物體如包圍盒、路點(diǎn)、標(biāo)記等。

                // Untransformed, lit vertex
               
            struct RenderVertexL
                {
                    Vector3 p;        
            // position
               
                unsigned argb;    // prelit color (8 bits per component – 0xAARRGGBB)
               
                unsigned spec;    // prelit specular color
               
                float u,v;        // texture mapping coordinates
               
            };

            變換和光照

            網(wǎng)格被提交到API之后,接下來的操作就是變換與光照(經(jīng)常用T&L表示),圖形管道的該階段其實(shí)包含大量頂點(diǎn)級(jí)別的計(jì)算。基本上,所有頂點(diǎn)級(jí)別的計(jì)算都可以在本階段進(jìn)行,但最常見的操作有:

            (1)物體空間頂點(diǎn)位置變換到裁剪空間

            (2)使用光照設(shè)置及法向量計(jì)算光照

            (3)根據(jù)頂點(diǎn)位置計(jì)算頂點(diǎn)級(jí)霧濃度

            (4)階段式產(chǎn)生紋理映射坐標(biāo)

            (5)在骨骼動(dòng)畫中,用skinning技術(shù)計(jì)算頂點(diǎn)值

            當(dāng)然,根據(jù)不同的渲染上下文和提交的數(shù)據(jù)類型,某些操作不會(huì)執(zhí)行。

            當(dāng)前圖形API給予T&L階段完全的靈活性。自第八版開始,DirectX支持頂點(diǎn)著色,其實(shí)就是運(yùn)行在硬件上的小段代碼。這些代碼操作單個(gè)頂點(diǎn),接受幾何提交階段發(fā)送來的任意多輸入,并產(chǎn)生任意多輸出到裁剪/光柵化階段。典型的輸入如頂點(diǎn)位置、法向量、光照前的顏色、紋理映射坐標(biāo)等。可能的輸出包括頂點(diǎn)坐標(biāo)轉(zhuǎn)換(攝像機(jī)空間或裁剪空間),Gourand著色,紋理坐標(biāo),霧濃度等。經(jīng)常,輸入只是簡單地通過頂點(diǎn)著色,并映射成合適的輸出(如紋理映射坐標(biāo),預(yù)計(jì)算的光照),或頂點(diǎn)著色執(zhí)行一些運(yùn)算產(chǎn)生全新的輸出,如變換頂點(diǎn)位置、霧濃度、動(dòng)態(tài)光照、或階段式生成紋理映射坐標(biāo)。

             

            變換到裁剪空間

            模型空間到裁剪空間的轉(zhuǎn)換常以矩陣乘法實(shí)現(xiàn)。概念上,頂點(diǎn)經(jīng)過一系列變換,如下所示:

            (1)模型轉(zhuǎn)換到世界空間

            (2)視圖變換將世界空間轉(zhuǎn)換到攝像機(jī)空間

            (3)攝像機(jī)空間轉(zhuǎn)換到裁剪空間

            乘法順序如下:

            vclip = vmodel(Mmodel->world)(Mworld->camera)(Mcamera->clip)

            實(shí)現(xiàn)中并沒有做三步乘法,實(shí)際上,變換矩陣是連接好的,頂點(diǎn)的變換不需要做三次矩陣乘法。根據(jù)硬件的設(shè)計(jì)和光照方法,可以將所有矩陣連接成兩個(gè)或一個(gè)矩陣。如果能夠訪問T&L硬件(如頂點(diǎn)著色),則可以直接施加精確的控制。如果不能,就必須依賴API讓它作所有的優(yōu)化。

             

            頂點(diǎn)光照

            理想的情況應(yīng)該使用Phong著色,先對(duì)表面法向量插值而后像素點(diǎn)計(jì)算光照。實(shí)際上,我們卻不得不多用Gourand著色,先計(jì)算頂點(diǎn)的光照而后插值生成多邊形中各點(diǎn)的光照。

            當(dāng)在頂點(diǎn)級(jí)計(jì)算光照時(shí),無法直接用公式15.14,因?yàn)?/span>mdiff不是一個(gè)頂點(diǎn)級(jí)材質(zhì)屬性,通常是由紋理定義這個(gè)值。為了使公式15.14更適合插值,必須進(jìn)行變換以分離mdiff,同時(shí),可以假設(shè)mamb等于mdiff

            用上面的光照方程,就可以在頂點(diǎn)級(jí)插值計(jì)算光照。對(duì)于每個(gè)頂點(diǎn),我們計(jì)算兩個(gè)值,vdiffvspecvdiff包含公式15.16的環(huán)境與散射分量,vspec包含鏡面分量:

            上述值都是逐頂點(diǎn)計(jì)算,然后對(duì)整個(gè)三角形插值。于是對(duì)每個(gè)像素,光照公式如下:

            如前所述,mspec經(jīng)常為常量,但也可以用光澤圖定義。

            應(yīng)使用哪個(gè)坐標(biāo)空間計(jì)算光照?可以在世界空間內(nèi)進(jìn)行。此時(shí),頂點(diǎn)坐標(biāo)、法向量都要轉(zhuǎn)換到世界空間,以進(jìn)行光照計(jì)算,接著頂點(diǎn)坐標(biāo)轉(zhuǎn)至裁剪空間。或者,可以將光照放到模型空間中計(jì)算,因?yàn)楣庹湛偙软旤c(diǎn)較少,結(jié)果是總體減少了向量----矩陣乘法計(jì)算。第三種可能是在攝像機(jī)空間內(nèi)計(jì)算。如果你不通過頂點(diǎn)著色直接控制T&L管道,API會(huì)為你做出這種選擇。

            posted on 2008-03-11 08:58 lovedday 閱讀(1335) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            91久久国产视频| 久久精品成人国产午夜| 无码8090精品久久一区| 免费久久人人爽人人爽av| 欧美喷潮久久久XXXXx| 国产综合精品久久亚洲| 久久久久久久91精品免费观看| 亚洲国产精品无码成人片久久| 亚洲国产精品久久| 久久精品国产久精国产果冻传媒 | 亚洲AV无码一区东京热久久| 国产亚洲欧美成人久久片| 色婷婷久久综合中文久久一本| 久久99国产精品尤物| 久久久久久无码国产精品中文字幕 | 国产一久久香蕉国产线看观看| 久久精品无码一区二区三区免费| 亚洲精品无码久久久久sm| 国产成人99久久亚洲综合精品| 亚洲人成网亚洲欧洲无码久久 | 久久男人中文字幕资源站| 精产国品久久一二三产区区别 | 亚洲成av人片不卡无码久久| 久久美女人爽女人爽| 亚洲国产精品无码久久久不卡| 午夜精品久久影院蜜桃| 一本伊大人香蕉久久网手机| 久久综合狠狠综合久久综合88| 亚洲国产成人久久综合碰| 久久久久一级精品亚洲国产成人综合AV区 | 午夜精品久久影院蜜桃| 亚洲一本综合久久| 国产99久久精品一区二区| 久久综合给久久狠狠97色 | 久久这里只有精品视频99| 午夜不卡888久久| 久久中文字幕一区二区| 国产亚洲美女精品久久久久狼| 国内精品久久久久久久97牛牛| 国产精品久久久久9999高清| 97久久香蕉国产线看观看|