包含高度復(fù)雜繪制元素的三維場景高性能繪制優(yōu)化方法
【專利摘要】本發(fā)明涉及一種包含高度復(fù)雜繪制元素的三維場景高性能繪制優(yōu)化方法。該方法包括:遍歷三維場景繪制系統(tǒng)中所有繪制單元,收集每個繪制單元與繪制相關(guān)的狀態(tài),并枚舉得到由若干狀態(tài)所構(gòu)成的狀態(tài)集合;將所有狀態(tài)集合中元素的狀態(tài)參數(shù)設(shè)置用兩個值分別表示,根據(jù)每個繪制單元的繪制狀態(tài)參數(shù)設(shè)置得到狀態(tài)編碼;將由所有狀態(tài)參數(shù)構(gòu)成的狀態(tài)編碼作為二進(jìn)制格雷碼,將繪制單元按照格雷碼排序,格雷碼編碼的值相同的繪制單元組成鏈表結(jié)構(gòu);依次收集格雷碼對應(yīng)的繪制單元,建立繪制單元的隊列;設(shè)置所有繪制單元的相同的狀態(tài)參數(shù);按照繪制單元隊列的順序進(jìn)行三維場景的繪制。本發(fā)明能夠?qū)L制系統(tǒng)中的多種繪制單元的繪制順序進(jìn)行調(diào)節(jié),提高繪制效率。
【專利說明】
包含高度復(fù)雜繪制元素的H維場景高性能繪制優(yōu)化方法
技術(shù)領(lǐng)域
[0001] 本發(fā)明屬于信息技術(shù)、計算機(jī)圖形與虛擬現(xiàn)實(shí)技術(shù)領(lǐng)域,具體設(shè)及一種面向包含 高度復(fù)雜繪制元素的=維場景的高性能繪制優(yōu)化方法。
【背景技術(shù)】
[0002] -個復(fù)雜的虛擬現(xiàn)實(shí)環(huán)境,往往由各種繪制場景元素構(gòu)成,例如既包含地形,樹 木,草地,道路,建筑物,窗戶(透明),云,汽車交通工具(金屬材料),水面(深水,淺水),噴 泉,人物(骨骼,蒙皮動畫),飛行器等各種=維物體,又包含火焰,天空大氣,雨,雪,霧,炫 光,陰影,反射,散射等自然現(xiàn)象。單獨(dú)針對上述其中一種=維物體或者現(xiàn)象而設(shè)計的繪制 單元在進(jìn)行繪制時,其效率可能是高效的。一個繪制單元是指由一定的繪制數(shù)據(jù)和繪制算 法組成,并具有一些確定的繪制狀態(tài)、參數(shù)W及材質(zhì)紋理參數(shù)等,每個繪制算法執(zhí)行一遍繪 制管線的流程。
[0003] 使用化en化圖形標(biāo)準(zhǔn)進(jìn)行任何S維場景的繪制,其繪制單元的執(zhí)行過程都要遵循 繪制(擅染)流水線。一個繪制單元的執(zhí)行過程就是首先利用化en化提供的API接口對GPU的 繪制狀態(tài)進(jìn)行設(shè)置,或者向GPU發(fā)送一些特殊的繪制參數(shù)(例如化化的shader中的各項參 數(shù)),或者設(shè)置某些材質(zhì)和紋理參數(shù)等,然后向繪制流水線提交幾何(頂點(diǎn))數(shù)據(jù),最后由GPU 執(zhí)行繪制指令的過程。運(yùn)樣通過化en化的接口,用戶為GPU設(shè)置了相應(yīng)的繪制參數(shù)和狀態(tài), 并最終使GPU按照用戶需要的方式繪制出正確的擅染結(jié)果。發(fā)送繪制數(shù)據(jù)的代碼具有和狀 態(tài)設(shè)置的代碼相同的生命周期,但是由于狀態(tài)的設(shè)置是為了給實(shí)現(xiàn)繪制效果提供繪制參 數(shù),指定繪制功能,而傳送繪制是為了給GPU提供繪制的場景數(shù)據(jù)對象。在進(jìn)行場景繪制時, 對不同的場景常常具有相同的繪制狀態(tài)但卻需要設(shè)定不同的頂點(diǎn)數(shù)據(jù)源,而具有相同頂點(diǎn) 數(shù)據(jù)的場景卻可能需要形成不同的繪制效果。
[0004] 在包含高度復(fù)雜繪制元素的=維場景的繪制過程中,當(dāng)多個繪制單元一起被繪制 時,由于各自繪制的方式不同,在執(zhí)行繪制的操作流程上可能產(chǎn)生沖突,如一個繪制單元需 要開啟某種繪制狀態(tài),而另外一種繪制需要關(guān)閉該繪制狀態(tài)。當(dāng)該沖突反復(fù)出現(xiàn)時,反復(fù)執(zhí) 行運(yùn)些互相沖突的操作會耗費(fèi)一定的CPU和GPU時間。不同的繪制單元會設(shè)置截然相反的繪 制狀態(tài),例如在執(zhí)行繪制透明物體的繪制單元時,利用深度緩沖進(jìn)行深度測試的狀態(tài)是啟 用的,深度緩沖的狀態(tài)是禁止寫入的;而在進(jìn)行不透明物體繪制的時候,深度測試的狀態(tài)仍 然是啟用,但同時深度緩沖的狀態(tài)應(yīng)該設(shè)置為允許寫入。
[0005] 高度復(fù)雜繪制元素的=維場景在繪制時設(shè)及多種=維物體和多種自然現(xiàn)象的及 其對應(yīng)的多個繪制單元。每個繪制單元的實(shí)現(xiàn)都遵循向GPU所管理的顯存發(fā)送數(shù)據(jù),設(shè)置 GPU運(yùn)行狀態(tài)、參數(shù)W及材質(zhì)和紋理等運(yùn)一流程。而每一次操作都需要耗費(fèi)CPU和GPU-定的 時間,尤其是會消耗CPU的時間,因?yàn)槊恳淮尾僮鞫紩{(diào)用一次3D圖形繪制的底層接口。但 如果相鄰兩個繪制過程具有相同的操作,就能夠省去一次重復(fù)的操作,提高繪制效率。
[0006] W下面的一個圖形系統(tǒng)中各個元素的繪制過程為例:
[0007] 1.設(shè)置繪制狀態(tài)、參數(shù)W及材質(zhì)1,繪制模型A,
[000引2.設(shè)置繪制狀態(tài)、參數(shù)W及材質(zhì)2,繪制模型B,
[0009] 3.設(shè)置繪制狀態(tài)、參數(shù)W及材質(zhì)1,繪制模型C。
[0010] 上述過程包含了=個繪制單元,模型A和C的繪制狀態(tài)、參數(shù)W及材質(zhì)等信息是相 同的,但是模型A和C的繪制并不是在一起的,而是被模型B的繪制打斷了,造成繪制狀態(tài)、參 數(shù)W及材質(zhì)1被設(shè)置了兩次。如果調(diào)整其繪制順序如下:
[0011] 1.設(shè)置繪制狀態(tài)、參數(shù)W及材質(zhì)2,繪制模型B,
[0012] 2.設(shè)置繪制狀態(tài)、參數(shù)W及材質(zhì)1,繪制模型A,C。
[0013] 則按照上述順序進(jìn)行繪制的效率要獲得提升。因此合理安排場景中繪制單元的繪 制順序?qū)μ岣呃L制效率具有重要的作用。但是在實(shí)際繪制系統(tǒng)中,各個繪制單元的操作多 種多樣,該如何安排繪制單元的執(zhí)行順序才能獲得最優(yōu)的性能是整個繪制系統(tǒng)設(shè)計的關(guān) 鍵。
[0014] 假設(shè)一個繪制單元由包含狀態(tài)設(shè)置指令在內(nèi)的一系列各種操作構(gòu)成,假設(shè)第i個 操作的執(zhí)行代價為fi,那么繪制單元k的繪制過程花費(fèi)的代價Fk為:
[0015]
(1)
[0016] 假設(shè)在繪制整個場景的繪制系統(tǒng)之中的一遍繪制過程中相鄰的兩個繪制單元Ki 和K2具有完全相同的一些操作,而運(yùn)些相同的操作可W為兩個繪制單元所共用(如設(shè)置繪 制狀態(tài)、參數(shù)等),則執(zhí)行運(yùn)兩個繪制單元時可W只執(zhí)行一遍運(yùn)些相同的操作而無需重復(fù)執(zhí) 行,從而節(jié)省出一定的時間代價,假設(shè)運(yùn)些因重復(fù)而可被省略的操作的執(zhí)行代價為Fklk2,那 么對于按照順序依次繪制的N個繪制單元的繪制流程來說,執(zhí)行所有操作花費(fèi)的代價總值W 為:
[0017] (2)
[001引由式(2)可W看出對于N個繪制單元的繪制流程來說,如何安排它們的繪制順序使 得Z 最大從而W最小是獲得最佳繪制效率的關(guān)鍵。
[0019] 該問題是旅行商的NP難問題,而解決運(yùn)一問題的目的就是為了減少繪制系統(tǒng)執(zhí)行 繪制流程的時間,因此不能W花費(fèi)額外的高昂時間開銷為代價進(jìn)行排序W獲得較好的擅染 排序結(jié)果。Ogre系統(tǒng)(Open Source 3D Graphics Engine,http://www.ogre3d.org/)和 Irrlicht引擎化ttp://irrlicht. sourceforge. net/)采用了 W材質(zhì)信息中的某個參數(shù)作 為排序的依據(jù),實(shí)際上大部分情況下該參數(shù)是材質(zhì)具有的第一個紋理的名稱。運(yùn)種W繪制 單元中的某個數(shù)據(jù)作為參考的較優(yōu)排序結(jié)構(gòu)的貪屯、的算法能夠迅速得把具有相似的材質(zhì) 的場景放到繪制隊列中相鄰的位置。其算法復(fù)雜度與排序算法的復(fù)雜度相同。添加擅染排 序模塊就是為了提高繪制效率,但同時擅染排序模塊本身執(zhí)行各個繪制單元的管理操作也 會增加 CPU的時間,所W擅染排序模塊本身執(zhí)行操作一定要高效。
【發(fā)明內(nèi)容】
[0020] 本發(fā)明的核屯、思想就是通過添加一個繪制(擅染)排序模塊(方法)對一個高度復(fù) 雜的繪制系統(tǒng)中的多種繪制單元的繪制順序進(jìn)行調(diào)整,將繪制狀態(tài)、繪制參數(shù)W及材質(zhì)等 相同的繪制單元放置在一起繪制,運(yùn)樣相同的一些繪制操作僅執(zhí)行一遍即可。同時將狀態(tài)、 參數(shù)W及材質(zhì)等參數(shù)值變化較小的繪制單元排序作為相鄰的繪制單元,從而減少相鄰兩個 繪制單元之間進(jìn)行狀態(tài)切換操作的代價Fklk2,可W減少冗余的狀態(tài)參數(shù)W及材質(zhì)等的設(shè)置 操作,從而提高繪制效率。
[0021 ]本發(fā)明采用的技術(shù)方案如下:
[0022] -種面向包含高度復(fù)雜繪制元素的=維場景的高性能繪制優(yōu)化方法,包括W下步 驟:
[0023] 1)遍歷=維場景繪制系統(tǒng)中所有繪制單元,收集每個繪制單元與繪制相關(guān)的狀 態(tài),并枚舉得到由若干狀態(tài)所構(gòu)成的狀態(tài)集合;所述狀態(tài)包括繪制狀態(tài)、繪制參數(shù)W及材質(zhì) 紋理等信息,統(tǒng)一 W狀態(tài)參數(shù)來表示;
[0024] 2)將所有狀態(tài)集合中元素的狀態(tài)參數(shù)設(shè)置用兩個值分別表示(例如某個狀態(tài)參數(shù) 的啟用設(shè)置其參數(shù)值為1,該狀態(tài)的禁用則為0;又例如某個參數(shù)值的設(shè)置可W表示為1,而 與該參數(shù)無關(guān)則可W表示為0;如果無法用二值表示的狀態(tài)、參數(shù)W及材質(zhì)等不在本發(fā)明考 慮范圍之內(nèi)),根據(jù)每個繪制單元的繪制狀態(tài)參數(shù)設(shè)置得到狀態(tài)編碼,每一個狀態(tài)參數(shù)對應(yīng) 一個二進(jìn)制位;
[0025] 3)將由所有狀態(tài)參數(shù)構(gòu)成的狀態(tài)編碼作為二進(jìn)制格雷碼,將對應(yīng)的繪制單元按照 格雷碼排序,格雷碼編碼的值相同的繪制單元組成鏈表結(jié)構(gòu);
[0026] 4)依次收集格雷碼對應(yīng)的繪制單元,建立繪制單元的隊列,該隊列由鏈表形式表 不和存儲;
[0027] 5)設(shè)置所有繪制單元的相同的狀態(tài)參數(shù),即不在狀態(tài)集合中出現(xiàn)的狀態(tài)參數(shù);
[0028] 6)按照繪制單元隊列的順序進(jìn)行S維場景的繪制。
[0029] 進(jìn)一步地,步驟6)在執(zhí)行每個繪制單元時,首先進(jìn)行繪制狀態(tài)的更新;繪制結(jié)果為 生成一帖圖像,標(biāo)記為第j帖;如果繪制系統(tǒng)中繪制單元的數(shù)目W及每個繪制單元的繪制狀 態(tài)參數(shù)設(shè)置不發(fā)生改變,則繼續(xù)繪制第j+1帖,如此循環(huán)執(zhí)行,直至繪制系統(tǒng)運(yùn)行被終止。
[0030] 進(jìn)一步地,步驟6)中,如果繪制單元的數(shù)目發(fā)生變化,則做如下處理:
[0031] 曰〉如果向繪制系統(tǒng)添加了一個繪制單元kN+1,則首先檢查并判定是否引入新的狀 態(tài),即該繪制單元的所有繪制狀態(tài)參數(shù)是否包含在狀態(tài)集合中:
[0032] al>如果未引入新的狀態(tài)位,則說明之前的n個狀態(tài)位完全覆蓋了新繪制單元所設(shè) 及的狀態(tài),繪制隊列不需要做任何變更;
[0033] a2>否則需要引入新的狀態(tài)位,則添加第n+1位二進(jìn)制位作為新的狀態(tài)位,并且能 夠斷定:該kN+i繪制單元的第n+1個狀態(tài)位的值與其它N個繪制單元的第n+1位的值不同;
[0034] b>如果去除了一個繪制單元k,則檢查判斷是否需要從狀態(tài)集合I中刪除某些狀 態(tài),檢查方法為對其余N-I個繪制單元的n個狀態(tài)所對應(yīng)的狀態(tài)位的值進(jìn)行逐一比較。
[0035] 進(jìn)一步地,步驟6)中,如果某一個繪制單元k的狀態(tài)參數(shù)iq所對應(yīng)的狀態(tài)發(fā)生改 變,則修改其格雷碼,其對應(yīng)狀態(tài)位的值由O^l或者由1^0;具體方法是:首先檢查N個繪制 單元的該狀態(tài)位的值是否都相同,即都是1或者0;如果相同,則該狀態(tài)iq從狀態(tài)集合I中刪 除;并作如下步驟的操作:把所有N個繪制單元的格雷碼中iq所對應(yīng)的位的值設(shè)置為0,并將 該位左邊所有數(shù)位統(tǒng)一右移一位,格雷碼的位數(shù)減1變?yōu)閚-1。
[0036] 本發(fā)明的有益效果如下:
[0037] 本發(fā)明提出一種基于格雷碼形式的繪制單元優(yōu)化排序方法,N個繪制單元的排序 復(fù)雜度為O(N),排序之后獲得的益處首先是把具有相同的繪制狀態(tài)、參數(shù)W及材質(zhì)等的繪 制單元組成一組一起繪制,其狀態(tài)參數(shù)的值只需要設(shè)置一次即可對該繪制單元組生效;其 次相鄰兩個狀態(tài)參數(shù)的值存在差異的繪制單元的繪制狀態(tài)參數(shù)的差異理想狀況下為1個 (當(dāng)N=2D-1時,n為格雷碼的位數(shù),且每個繪制單元的狀態(tài)編碼恰好彼此不同時),即每個繪 制單元每次僅僅執(zhí)行一個狀態(tài)參數(shù)的設(shè)置操作(因?yàn)槌嗽摖顟B(tài)參數(shù)外,其它狀態(tài)參數(shù)等 都與上一個繪制單元相同,無需重新設(shè)置)。運(yùn)樣本發(fā)明的優(yōu)化排序算法可W大大節(jié)約每個 繪制單元設(shè)置狀態(tài)參數(shù)的時間開銷。=維場景的實(shí)時繪制的一帖對應(yīng)的是一遍執(zhí)行完繪制 任務(wù)所對應(yīng)的所有按順序排列的繪制單元,下一帖將重復(fù)執(zhí)行運(yùn)些按順序排列的繪制單 元,即=維場景的繪制系統(tǒng)循環(huán)執(zhí)行繪制單元的任務(wù)。由于格雷碼是一種循環(huán)格式的編碼, 因此本方法的另外一個優(yōu)勢就是,從一帖結(jié)束時的繪制狀態(tài)至下一帖開始時的繪制狀態(tài), 其差異通常為1個,即繪制狀態(tài)僅僅需要通過執(zhí)行一個狀態(tài)參數(shù)設(shè)置操作即可。運(yùn)樣又進(jìn)一 步減少了繪制系統(tǒng)的時間代價。
【附圖說明】
[0038] 圖1是本發(fā)明方法的整體流程圖。
[0039] 圖2是根據(jù)格雷碼組織所有繪制單元(W四位格雷碼為例)的示意圖。
【具體實(shí)施方式】
[0040] 為使本發(fā)明的上述目的、特征和優(yōu)點(diǎn)能夠更加明顯易懂,下面通過具體實(shí)施例和 附圖,對本發(fā)明做進(jìn)一步說明。
[0041] 本發(fā)明的面向包含高度復(fù)雜繪制元素的=維場景高性能繪制優(yōu)化方法,其整體流 程如圖1所示,具體包括W下步驟:
[0042] 1. S維場景繪制系統(tǒng)啟動;
[0043] 2.遍歷所有N個繪制單元K=化i,k2, ???!?},收集每個繪制單元的狀態(tài),所述狀態(tài)包 括繪制狀態(tài)、繪制參數(shù)W及材質(zhì)紋理等信息,統(tǒng)稱為狀態(tài)參數(shù),并枚舉得到n個狀態(tài)所構(gòu)成 的狀態(tài)集合I = Ul, i2,i3,…in},說明除了運(yùn)n個狀態(tài)參數(shù)之外,余下的繪制狀態(tài)、繪制參 數(shù)、材質(zhì)紋理,所有N個繪制單元皆保持一致;
[0044] 3.所有狀態(tài)集合中元素的狀態(tài)參數(shù)設(shè)置由兩個值分別表示:開啟(啟用)、關(guān)閉(禁 用),分別編碼為1和0,其它狀態(tài)參數(shù)設(shè)置只要其值能夠用兩個不同的值表示也可W (例如 繪制多邊形的模式分為線框模式和填充模式兩種);根據(jù)該條件計算每個繪制單元k的繪制 狀態(tài)參數(shù)設(shè)置,得到狀態(tài)編碼,每一個狀態(tài)對應(yīng)一個二進(jìn)制位;
[0045] 4.將該編碼看做二進(jìn)制格雷碼,將對應(yīng)的繪制單元按照格雷碼排序,格雷碼編碼 的值相同的繪制單元組成鏈表結(jié)構(gòu);如果兩個繪制單元A和B對應(yīng)完全一樣的格雷碼,則兩 個繪制單元的先后順序無關(guān)緊要。該步驟的具體實(shí)現(xiàn)如下(如圖2所示):
[0046] 4.1建立數(shù)組元素數(shù)目為N的數(shù)組;
[0047] 4.2遍歷每個繪制單元k,得到其格雷碼Gk,并將格雷碼轉(zhuǎn)換為自然碼Ak;可參照后 文表1的四位格雷碼與自然碼的對照表;
[004引4.3如果數(shù)組的第Ak個元素中的值為空,則將繪制單元k的指針放入數(shù)組的第Ak個 元素中,作為該數(shù)組元素的值;
[0049] 4.4如果數(shù)組的第Ak個元素中的值不為空,則根據(jù)該數(shù)組元素所指向的鏈表的末 尾遍歷,并將繪制單元k的指針放入該鏈表的末尾。
[0050] 5.從數(shù)組的第一個元素開始,依次收集格雷碼對應(yīng)的繪制單元,建立最終高效率 的繪制單元的隊列Q,該隊列Q由鏈表形式表示和存儲;
[0051] 6.設(shè)置所有繪制單元的相同的狀態(tài)參數(shù)的值(即不在狀態(tài)集合I中出現(xiàn)的狀態(tài)參 數(shù),對于所有繪制單元,運(yùn)些狀態(tài)參數(shù)均相同);
[0052] 7.然后繪制系統(tǒng)按照繪制單元隊列Q的順序依次執(zhí)行進(jìn)行繪制,在執(zhí)行每個繪制 單元的繪制算法時,首先進(jìn)行繪制狀態(tài)的更新(往往只有一個繪制狀態(tài)的切換);繪制結(jié)果 為生成一帖圖像,標(biāo)記為第j帖;
[0053] 8.如果繪制系統(tǒng)中繪制單元的數(shù)目W及每個繪制單元的繪制狀態(tài)參數(shù)設(shè)置不發(fā) 生改變,則將繼續(xù)繪制第j+1帖(第j+1帖的開始狀態(tài)與第j帖的結(jié)束狀態(tài)相比,由于第j+1帖 的第1個繪制單元與第j帖的第N個繪制單元的繪制狀態(tài)參數(shù)的值相差位僅僅為1位(理想狀 態(tài)下),即狀態(tài)的差異僅僅只有一項,則僅僅需要更新一種狀態(tài)就可W進(jìn)行正確的繪制了), 循環(huán)執(zhí)行步驟7;
[0054] 9.如果繪制單元的數(shù)目發(fā)生變化:
[0055] 9.1如果向繪制系統(tǒng)添加了一個繪制單元kN+i,則首先檢查并判定是否引入新的狀 態(tài),即該繪制單元的所有繪制狀態(tài)參數(shù)是否包含在狀態(tài)集合I中(含n個集合元素所代表的 狀態(tài)參數(shù))。
[0056] 9.1.1如果未引入新的狀態(tài)位,則說明之前的n個狀態(tài)位完全覆蓋了新繪制單元所 設(shè)及的狀態(tài)參數(shù),繪制隊列Q不需要做任何變更;
[0057] 9.1.2否則需要添加該狀態(tài)參數(shù)作為元素到狀態(tài)集合I中(集合元素數(shù)變更為n+ 1),同時引入新的狀態(tài)位,則添加第n+1位二進(jìn)制位作為新的狀態(tài)位,并且可W斷定:該kN+i 繪制單元的第n+1個狀態(tài)位的值與其它N個繪制單元的第n+1位的值不同。因?yàn)槿绻渌麼個 繪制單元的第n+1位如果存在不同的話,那原本就應(yīng)該有n+1個狀態(tài)位來表示運(yùn)N個繪制單 元,運(yùn)樣就產(chǎn)生矛盾。例如:如果該繪制單元kN+i的第n+1狀態(tài)位值為0,即禁用狀態(tài),則其它N 個繪制單元的該位的值一定為1;
[0058] 1)如果該繪制單元kN+i的第n+1狀態(tài)位值為0,則將該編碼位放置于其格雷碼編碼 的最高位,即〇******(*代表原先其它編碼位的值,*的個數(shù)為n個),并將其它N個繪制單元 的格雷編碼位的最高位置為1;同時只需要將繪制單元kN+l插入繪制隊列Q的頭部,即作為第 一個單元進(jìn)行繪制。因?yàn)楦鶕?jù)格雷碼原理,其它N個繪制單元的編碼都大于當(dāng)前運(yùn)個繪制單 元kN+l的編碼,同時運(yùn)N個繪制單元的繪制先后順序維持不變;
[0059] 2)如果該繪制單元kN+i的第n+1狀態(tài)位值為1,則將該編碼放置于格雷編碼的最高 位,即1*****(*代表其它編碼位的值,*的個數(shù)為n個),并將其它N個繪制單元的格雷編碼位 的最高位置為0。同時將繪制單元kN+i插入繪制隊列Q的尾部,即作為最后一個單元進(jìn)行繪 審IJ。因?yàn)楦鶕?jù)格雷碼原理,其它N個繪制單元的編碼都小于當(dāng)前運(yùn)個繪制單元kN+l的編碼,同 時運(yùn)N個繪制單元的繪制先后順序維持不變;
[0060] 9.1.3返回步驟 6;
[0061] 9.2如果繪制系統(tǒng)中某一個繪制單元k被去除,則首先檢查判斷是否需要從狀態(tài)集 合I中刪除某些狀態(tài)參數(shù),檢查方法為對其余N-I個繪制單元的n個狀態(tài)參數(shù)所對應(yīng)的狀態(tài) 位的值進(jìn)行逐一比較(需要進(jìn)行n次);
[0062] 9.2.1如果存在某一個狀態(tài)參數(shù)ip及其對應(yīng)的格雷碼狀態(tài)位,N-I個繪制單元的該 狀態(tài)位的值都相同(即都是1或者都是0,實(shí)際實(shí)施可W通過位運(yùn)算計算出),則該狀態(tài)參數(shù) ip可W從狀態(tài)集合I中刪除;并作如下步驟的操作:
[0063] 1)把所有N-I個繪制單元的格雷碼中ip所對應(yīng)的位設(shè)置為0,并將該位左邊所有數(shù) 位的值統(tǒng)一右移一位,格雷碼的位數(shù)減一變?yōu)閚-1;
[0064] 2)將相應(yīng)的繪制單元從隊列Q中刪除,可W通過鏈表結(jié)點(diǎn)刪除實(shí)現(xiàn),其它繪制單元 的順序無需做任何調(diào)整,運(yùn)也是格雷碼的非常大的優(yōu)點(diǎn);
[00化]9.2.2繼續(xù)執(zhí)行9.2.1,直至所有n個狀態(tài)參數(shù)全部檢查完畢;
[0066] 9.2.3如果不存在需要刪除的狀態(tài)參數(shù),則直接找到繪制單元k在Q隊列中的位置, 并將其從鏈表結(jié)構(gòu)中刪除。
[0067] 9.2.4返回步驟6;
[0068] 10 .如果某一個繪制單元k的狀態(tài)參數(shù)iq所對應(yīng)的狀態(tài)發(fā)生改變,則修改其格雷 碼,其對應(yīng)狀態(tài)位的值由O^l或者由1^0;
[0069] 10.1首先檢查N個繪制單元的該狀態(tài)位的值是否都相同(即都是1或者0,可W通過 位運(yùn)算計算出);
[0070] 10.2如果相同,則該狀態(tài)iq可W從狀態(tài)集合I中刪除;并作如下步驟的操作:把所 有N個繪制單元的格雷碼中iq所對應(yīng)的位設(shè)置為0,并將該位左邊所有數(shù)位統(tǒng)一右移一位, 格雷碼的位數(shù)減一變?yōu)閚-1;返回步驟6;
[0071] 10.3無論是否相同,繪制單元的順序都無需做任何調(diào)整,運(yùn)也是格雷碼的非常大 的優(yōu)點(diǎn)(因?yàn)楦窭状a確保相鄰兩個編碼之間只有一個二進(jìn)制位的變化,當(dāng)前繪制單元狀態(tài) 編碼Gk^Gk'的改變只發(fā)生在一個二進(jìn)制數(shù)位上,則當(dāng)前繪制單元修改之后的編碼Gk'或者 等于Gk-I或者等于Gk+1);
[0072] 10.4如果不同則直接返回步驟7;
[0073] 11.繪制系統(tǒng)結(jié)束。
[0074] 下面進(jìn)一步說明實(shí)施例的實(shí)現(xiàn)細(xì)節(jié)。
[0075] 3D圖形的標(biāo)準(zhǔn)編程API Open化采用一種狀態(tài)機(jī)機(jī)制??蒞設(shè)置它的各種狀態(tài)(或 模式),然后讓運(yùn)些狀態(tài)一直生效,直到再次修改它們的值。例如當(dāng)前顏色就是一個狀態(tài)變 量(等價于上述內(nèi)容中的狀態(tài)參數(shù)),可W把當(dāng)前顏色設(shè)置為白色、紅色或其他任何顏色,在 此之后繪制的所有物體都將使用運(yùn)種顏色,直到再次把當(dāng)前顏色設(shè)置為其他顏色。當(dāng)前顏 色只是化en化所維護(hù)的許多狀態(tài)變量之一。其他的狀態(tài)變量還有很多,并且有著各自的用 途,例如控制當(dāng)前視圖和投影變換、直線和多邊形點(diǎn)畫模式、多邊形繪圖模式、像素包裝約 定、光照的位置和特征W及被繪制物體的材料屬性等。許多表示模式的狀態(tài)變量可W用 g化nableO和glDisableO函數(shù)進(jìn)行啟用和禁用。
[0076] 如果使用可編程的著色器,根據(jù)所用的化en化版本的不同,著色器所能識別的狀 態(tài)的數(shù)量也有所不同。每個狀態(tài)變量(或模式)或者參數(shù)都有一個默認(rèn)值。在任何時候都可 W向系統(tǒng)查詢每個狀態(tài)變量的當(dāng)前值。一般情況下,可W使用下面運(yùn)6個函數(shù)之一來完成運(yùn) 個任務(wù):gl GetBoolean v()、glGetDoublev()、glGetIntege;rv()、glGetfloatv()、 glGet化intervO或glIsEnabledO。具體選擇的函數(shù)取決于希望返回的結(jié)果的數(shù)據(jù)類型。 有些狀態(tài)變量還有更為特定的查詢函數(shù)(例如glGe1:Light*( KglGetErrorO或 glGet化IygonSti卵le()等)。另外,還可 W使用gl化shAtt;r;Lb()、glPushClientAtt;rib()函 數(shù)把狀態(tài)變量的集合保存到一個屬性找中,對它們進(jìn)行臨時的修改,W后再用 gl化pAttrirbO或gl化pClientAttribO恢復(fù)運(yùn)些值。如果需要對狀態(tài)變量進(jìn)行臨時修改, 就應(yīng)該使用運(yùn)些函數(shù),而不是使用任何查詢函數(shù),因?yàn)榍罢叩男矢摺?br>[0077] 對化en化狀態(tài)設(shè)置的代碼每次被調(diào)用后,如果沒有其它狀態(tài)設(shè)置的代碼運(yùn)行,那 么就其效果就可W-直生效,不用每一帖都重復(fù)調(diào)用。
[0078] 表1.四位格雷碼與自然碼對照表
[0079]
[0080]
[0081] W上實(shí)施例僅用W說明本發(fā)明的技術(shù)方案而非對其進(jìn)行限制,本領(lǐng)域的普通技術(shù) 人員可W對本發(fā)明的技術(shù)方案進(jìn)行修改或者等同替換,而不脫離本發(fā)明的精神和范圍,本 發(fā)明的保護(hù)范圍應(yīng)W權(quán)利要求書所述為準(zhǔn)。
【主權(quán)項】
1. 一種面向包含高度復(fù)雜繪制元素的三維場景的高性能繪制優(yōu)化方法,其特征在于, 包括以下步驟: 1) 遍歷三維場景繪制系統(tǒng)中所有繪制單元,收集每個繪制單元與繪制相關(guān)的狀態(tài),并 枚舉得到由若干狀態(tài)所構(gòu)成的狀態(tài)集合; 2) 將所有狀態(tài)集合中元素的狀態(tài)參數(shù)設(shè)置用兩個值分別表示,根據(jù)每個繪制單元的繪 制狀態(tài)參數(shù)設(shè)置得到狀態(tài)編碼,每一個狀態(tài)參數(shù)對應(yīng)一個二進(jìn)制位; 3) 將由所有狀態(tài)參數(shù)構(gòu)成的狀態(tài)編碼作為二進(jìn)制格雷碼,將對應(yīng)的繪制單元按照格雷 碼排序,格雷碼編碼的值相同的繪制單元組成鏈表結(jié)構(gòu); 4) 依次收集格雷碼對應(yīng)的繪制單元,建立繪制單元的隊列,該隊列由鏈表形式表示和 存儲; 5) 設(shè)置所有繪制單元的相同的狀態(tài)參數(shù),即不在狀態(tài)集合中出現(xiàn)的狀態(tài)參數(shù); 6) 按照繪制單元隊列的順序進(jìn)行三維場景的繪制。2. 如權(quán)利要求1所述的方法,其特征在于,步驟6)在執(zhí)行每個繪制單元時,首先進(jìn)行繪 制狀態(tài)的更新;繪制結(jié)果為生成一幀圖像,標(biāo)記為第j幀;如果繪制系統(tǒng)中繪制單元的數(shù)目 以及每個繪制單元的繪制狀態(tài)參數(shù)設(shè)置不發(fā)生改變,則繼續(xù)繪制第j+Ι幀,如此循環(huán)執(zhí)行, 直至繪制系統(tǒng)運(yùn)行被終止。3. 如權(quán)利要求1或2所述的方法,其特征在于,步驟3)的具體實(shí)現(xiàn)方法如下: a) 建立數(shù)組元素數(shù)目為N的數(shù)組; b) 遍歷每個繪制單元k,得到其格雷碼Gk,并將格雷碼轉(zhuǎn)換為自然碼Ak; c) 如果數(shù)組的第Ak個元素中的值為空,則將繪制單元k的指針放入數(shù)組的第Ak個元素 中,作為該數(shù)組元素的值; d) 如果數(shù)組的第Ak個元素中的值不為空,則根據(jù)該數(shù)組元素所指向的鏈表的末尾遍歷, 并將繪制單元k的指針放入該鏈表的末尾。4. 如權(quán)利要求2所述的方法,其特征在于,步驟6)中,如果繪制單元的數(shù)目發(fā)生變化,則 做如下處理: a>如果向繪制系統(tǒng)添加了一個繪制單元1?+1,則首先檢查并判定是否引入新的狀態(tài),即 該繪制單元的所有繪制狀態(tài)參數(shù)是否包含在狀態(tài)集合中: al>如果未引入新的狀態(tài)位,則說明之前的η個狀態(tài)位完全覆蓋了新繪制單元所涉及的 狀態(tài),繪制隊列Q不需要做任何變更; a2>否則需要引入新的狀態(tài)位,則添加第η+1位二進(jìn)制位作為新的狀態(tài)位,并且能夠斷 定:該kN+1繪制單元的第η+1個狀態(tài)位的值與其它N個繪制單元的第η+1位的值不同; b>如果去除了一個繪制單元k,則檢查判斷是否需要從狀態(tài)集合I中刪除某些狀態(tài),檢 查方法為對其余N-I個繪制單元的η個狀態(tài)所對應(yīng)的狀態(tài)位的值進(jìn)行逐一比較。5. 如權(quán)利要求4所述的方法,其特征在于,步驟a2>中: 如果繪制單元1?+1的第11+1狀態(tài)位值為0,則將該編碼位放置于其格雷碼編碼的最高位, 并將其它N個繪制單元的格雷編碼位的最高位置為1;同時將繪制單元kN+1插入繪制隊列Q的 頭部,即作為第一個單元進(jìn)行繪制; 如果繪制單元1?+1的第11+1狀態(tài)位值為1,則將該編碼放置于格雷編碼的最高位,并將其 它N個繪制單元的格雷編碼位的最高位置為0;同時將繪制單元kN+1插入繪制隊列Q的尾部, 即作為最后一個單元進(jìn)行繪制。6. 如權(quán)利要求4所述的方法,其特征在于,步驟b>包括如下子步驟: bl>如果存在某一個狀態(tài)參數(shù)iP及其對應(yīng)的格雷碼狀態(tài)位,N-I個繪制單元的該狀態(tài)位 的值都相同,則該狀態(tài)參數(shù)。可以從狀態(tài)集合I中刪除;并作如下步驟的操作: 1>把所有N-I個繪制單元的格雷碼中^所對應(yīng)的位設(shè)置為0,并將該位左邊所有數(shù)位的 值統(tǒng)一右移一位,格雷碼的位數(shù)減一變?yōu)閚-1; 2>將相應(yīng)的繪制單元從隊列Q中刪除,其它繪制單元的順序無需做任何調(diào)整; b2>繼續(xù)執(zhí)行bl>,直至所有η個狀態(tài)參數(shù)全部檢查完畢; b3>如果不存在需要刪除的狀態(tài)參數(shù),則直接找到繪制單元k在Q隊列中的位置,并將其 從鏈表結(jié)構(gòu)中刪除。7. 如權(quán)利要求4至6中任一項所述的方法,其特征在于,步驟6)中,如果某一個繪制單元 k的狀態(tài)參數(shù)iq所對應(yīng)的狀態(tài)發(fā)生改變,則修改其格雷碼,其對應(yīng)狀態(tài)位的值由0-1或者由 1-0;具體方法是:首先檢查N個繪制單元的該狀態(tài)位的值是否都相同,即都是1或者〇;如果 相同,則該狀態(tài)i q從狀態(tài)集合I中刪除;并作如下步驟的操作:把所有N個繪制單元的格雷碼 中iq所對應(yīng)的位的值設(shè)置為0,并將該位左邊所有數(shù)位統(tǒng)一右移一位,格雷碼的位數(shù)減1變 為 n-1 〇
【文檔編號】G06T15/00GK105957132SQ201610252206
【公開日】2016年9月21日
【申請日】2016年4月21日
【發(fā)明人】李勝, 汪國平
【申請人】北京大學(xué)