張 生,龍云躍
(上海理工大學(xué) 光電信息與計算機學(xué)院,上海 200093)
近年來,隨著計算機硬件技術(shù)的不斷發(fā)展,增強現(xiàn)實、虛擬現(xiàn)實技術(shù)開始從理論變?yōu)楝F(xiàn)實,出現(xiàn)了越來越多的增強現(xiàn)實應(yīng)用及設(shè)備。相關(guān)產(chǎn)品主要分為兩類:一類是增強現(xiàn)實頭盔,比較具有代表性的是微軟的Hololens增強現(xiàn)實頭盔、谷歌的Google glasses,這兩種屬于獨立增強現(xiàn)實設(shè)備,因為其具有自己的處理芯片,可以脫離計算機獨立工作;另一類是智能手機,美國蘋果公司與谷歌公司分別研發(fā)了自己的技術(shù)ARkit和ARcore,利用智能手機攝像頭,使增強現(xiàn)實應(yīng)用可以運行在手機上。由于智能手機的廣泛普及,手機增強現(xiàn)實應(yīng)用具有更好的發(fā)展前景與商業(yè)應(yīng)用價值。
一般的智能手機由于其硬件的性能局限性(CPU頻率低,內(nèi)存小, GPU性能低),導(dǎo)致很多開發(fā)完成的AR應(yīng)用雖然在臺式計算機中可以流暢運行,且?guī)瑪?shù)穩(wěn)定、圖像質(zhì)量較好,但當移植到手機上,則會出現(xiàn)明顯的幀數(shù)降低、畫面卡頓等情況,大大降低了使用體驗。傳統(tǒng)解決方案主要有:①使用對性能要求較低的3D模型;②降低畫面質(zhì)量參數(shù)(光照、幀數(shù)、色彩、分辨率等)。但上述方案都以降低畫面質(zhì)量為代價,所以在某些場景下并不是最佳解決方案。
隨著移動設(shè)備的普及以及移動應(yīng)用的大量增加,特別是游戲、圖像分析類軟件的快速發(fā)展,使渲染性能優(yōu)化成為移動圖形類應(yīng)用研發(fā)的一個核心問題。根據(jù)應(yīng)用場景不同有各種不同優(yōu)化方案,一類方案為優(yōu)化渲染算法類,如張驥先 、羅蕾 、姜帆[1]提出的富媒體場景渲染優(yōu)化策略,該優(yōu)化策略從局部渲染與多邊形填充兩方面進行,通過跟蹤場景變化的失效區(qū)域體現(xiàn)局部渲染;另一類則是對被渲染的場景與物體模型進行優(yōu)化的方案,如江能興、周淦淼[2]提出的基于3DMAX的三維模型優(yōu)化策略,通過簡化3D模型提高渲染性能。
增強現(xiàn)實類軟件與傳統(tǒng)圖形類軟件的最大區(qū)別在于,其需要通過攝像頭實時捕獲真實世界的圖像信息進行分析,并在真實世界基礎(chǔ)上建立一個虛擬空間。所以對捕獲到的圖像進行分析與處理會造成很大開銷,從而影響系統(tǒng)的整理渲染性能。
對于增強現(xiàn)實應(yīng)用的優(yōu)化,傳統(tǒng)對被渲染的虛擬物體模型進行優(yōu)化是一個可行方案,但是優(yōu)化效果依賴于需要渲染的模型數(shù)量。如果應(yīng)用本身需要渲染的虛擬物體數(shù)量不多,則該優(yōu)化方案收益并不理想。目前學(xué)術(shù)界和產(chǎn)業(yè)界研究與使用最多的方案是對捕獲到的圖像進行處理,并建立虛擬空間的算法進行優(yōu)化,如Arthur、 Guez、Joelle、Pineau[3]提出的多任務(wù)SLAM算法。
一般增強現(xiàn)實應(yīng)用的性能測試包括渲染性能與計算性能測試。計算性能測試與常規(guī)軟件性能測試基本一致,采用一定約束,在其它條件不變的情況下,通過改變單一參數(shù),比較軟件運行時的內(nèi)存開銷、CPU占用及運算時間等[4]。渲染性能測試,主要關(guān)注的性能指標為屏幕分辨率、渲染幀數(shù)及渲染幀數(shù)穩(wěn)定性。本文主要實驗流程為在一個已搭建好的AR軟件環(huán)境中,在其它參數(shù)及條件一致的情況下,通過將運算進行多線程分離,比較使用多線程與不使用多線程情況下的渲染性能,得出實驗結(jié)果。
采用多線程即應(yīng)用程序可在同一時間里使用芯片的不同部分。雖然單線程芯片每秒能夠處理成千上萬條指令,但在任一時刻只能夠?qū)σ粭l指令進行操作,而多線程技術(shù)可以使芯片同時進行多線程處理,由此芯片性能得到提升[5]。本文使用多線程方式,將增強現(xiàn)實應(yīng)用中的屏幕渲染功能與圖像分析功能分開為兩個線程,屏幕渲染功能設(shè)置為主線程,圖像分析功能設(shè)置為子線程,兩個線程異步工作。主線程不必等待子線程,當子線程完成圖像分析后,發(fā)送信號給主線程,從而使屏幕渲染功能可以保持流暢執(zhí)行,提升畫面渲染性能。
2.2.1 單線程環(huán)境搭建
本文實驗環(huán)境使用美國蘋果公司ARkit搭建的一個智能手機增強現(xiàn)實應(yīng)用,測試平臺為Unity3D引擎。該應(yīng)用的主要功能為通過攝像頭捕捉圖像數(shù)據(jù)進行圖像識別,當識別到特定模式圖像后,展示相關(guān)分析數(shù)據(jù),主要工作流程如圖1所示。只要軟件處于開啟狀態(tài),則必須進行屏幕渲染,在該流程下,每一個渲染幀中,都要等待圖像識別到發(fā)送信號后,才可繼續(xù)執(zhí)行下一幀渲染,兩個功能之間是同步關(guān)系。
圖1 軟件工作流程
其中,Update方法用于更新屏幕內(nèi)容,運行在每一個渲染幀,每一次執(zhí)行都需要等待圖像識別功能的結(jié)束,根據(jù)patternFound信號量的真假情況,才能進行下一步操作。單線程環(huán)境執(zhí)行流程核心代碼如下:
...
//模式識別函數(shù)
PatternDetector patternDetector;
//需要匹配的模式
Pattern pattern
void Start()
{
pattern = new Pattern();
patternDetector = new PatternDetector();
//生成模式
patternDetector.buildPatternFromImage();
}
//Update方法會在屏幕刷新的每一幀執(zhí)行
void Update()
{
//執(zhí)行圖像模式識別
patternDetector.detectPattern();
if(patternDetector.patternFound == true)
{
nextStep();
}
else
{
//do nothing
}
}//update
2.2.2 多線程技術(shù)引入
考慮到保持圖像模式識別處理與屏幕渲染的同步會嚴重影響系統(tǒng)性能,將圖像識別處理功能分離到子線程中進行,而屏幕渲染功能依舊為主線程。此時的軟件工作流程如圖3所示。屏幕渲染功能運行在主線程,圖像識別處理功能運行在子線程。因為線程分離,主線程運行不依賴于子線程的運行。當圖像識別處理功能未完成時,主線程會一直執(zhí)行屏幕渲染功能;當子線程中圖像識別完成時,發(fā)送一個完成信號給主線程,此時主線程再執(zhí)行下一步操作,子線程任務(wù)完成并被掛起。
圖2 多線程引入后的工作流程
其中, Update方法用于更新屏幕內(nèi)容,運行在每一個渲染幀,主線程執(zhí)行屏幕渲染工作,子線程detectThread進行圖像模式識別及處理工作。每一幀中,主線程都會對isComplete信號量進行校驗,如果為假,則繼續(xù)執(zhí)行下一幀的屏幕渲染工作;如果為真,則開始執(zhí)行觸發(fā)相應(yīng)功能。子線程完成圖像模式識別后,將信號量isComplete設(shè)置為真,通知主線程,然后將isThreadRuning信號量設(shè)置為假,掛起子線程。在該流程下,屏幕渲染與圖像處理處于異步執(zhí)行關(guān)系中。加入多線程之后的執(zhí)行流程核心代碼如下:
...
//定義一個子線程,用來執(zhí)行圖像識別處理功能
Theard detectTheard;
//模式識別函數(shù)
PatternDetector patternDetector;
//需要匹配的模式
Pattern pattern;
//isComplete用于標識是否完成了識別
private boolean isComplete;
//isTheardRunning用來控制子線程開關(guān)
boolean isTheardRunning;
//Start函數(shù)用于初始化
void Start()
{
//子線程初始化
detectTheard =new Theard(detectPattern);
pattern =new Pattern();
patternDetector =new PatternDetector();
//生成模式
patternDetector.buildPatternFromImage();
}
// update函數(shù)會在屏幕刷新的每一幀執(zhí)行
void Update()
{
//執(zhí)行屏幕渲染
if(isComplete == true;)
{
nextStep();
}
}//update
...
//detectPattern在detectTheard線程中執(zhí)行
void detectPattern()
{
if(isTheardRunning)
{
patternDetector.detectPattern();
if(patternDetector.patternFound == true)
{
isComplete =true;
isTheardRunning =false;
}
else
isComplete =false;
}
};
2.3.1 渲染性能對比算法
本文主要考慮的渲染性能參數(shù)有:f為每一秒屏幕的刷新幀數(shù);Ct為主線程當前占用CPU進行計算的時間絕對值,單位為s;Rt為GPU渲染線程花費時間,單位為s。對上述3個參數(shù)分別賦予不同權(quán)重參數(shù)P1、P2、P3,權(quán)重參數(shù)可根據(jù)對不同性能關(guān)注度的具體情況而定,在本文場景下,更加關(guān)注屏幕幀數(shù),具體如式(1)所示。
(p1=0.8,p2=0.1,p3=0.1)
(1)
2.3.2 實驗數(shù)據(jù)分析
保持其它條件不變,僅通過對多線程的引入進行多次實驗,結(jié)果如表1所示。從表中可以看出,在本文軟件環(huán)境下,多線程的引入對CPU和GPU影響較小,但能較好地提升渲染幀數(shù)。
表1 實驗數(shù)據(jù)
從實驗數(shù)據(jù)可以看出,在CPU、GPU相同的情況下,以及相同的環(huán)境參數(shù)下,使用多線程將增強現(xiàn)實應(yīng)用中的屏幕渲染與圖像識別處理進行線程分離,可以有效提升畫面幀數(shù),提升幅度為25%,但同時可能增加約5%的CPU開銷,而GPU開銷基本不變。因此,在CPU占用量較小的圖像處理類增強現(xiàn)實應(yīng)用中,引入多線程可以明顯提升渲染性能。