溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

離屏渲染在車載導(dǎo)航中的應(yīng)用

發(fā)布時(shí)間:2020-08-11 02:37:47 來源:ITPUB博客 閱讀:144 作者:amap_tech 欄目:互聯(lián)網(wǎng)科技

導(dǎo)讀


與手機(jī)導(dǎo)航不同,高德地圖的車機(jī)版(AMAP AUTO)直接面對各大車廠和眾多設(shè)備商。這些B端用戶采用的硬件參數(shù)參差不齊,提出的業(yè)務(wù)需求涉及到渲染中諸多復(fù)雜技術(shù)的應(yīng)用,這對渲染性能提出了極高的要求。

最初車機(jī)版沿用手機(jī)版的當(dāng)前屏渲染模式,每一幀都需要實(shí)時(shí)的將地圖元素渲染出來。但在業(yè)務(wù)實(shí)踐過程中,我們發(fā)現(xiàn)在多屏渲染和多視圖渲染場景下,CPU負(fù)載急劇增高。以鷹眼圖場景為例,在鷹眼圖場景下,地圖存在多視圖渲染的狀態(tài):一張是主地圖,一張是鷹眼小地圖,因此渲染引擎同時(shí)渲染了兩個(gè)地圖實(shí)例對象,下圖右下角即為鷹眼圖:

離屏渲染在車載導(dǎo)航中的應(yīng)用

鷹眼圖繪制后,平均幀率下降了2幀,如下圖所示:

離屏渲染在車載導(dǎo)航中的應(yīng)用

離屏渲染在車載導(dǎo)航中的應(yīng)用

針對上述情況,除了對渲染細(xì)節(jié)、批次和紋理等進(jìn)行常規(guī)優(yōu)化外,我們還需要尋找一種全局性的技術(shù)優(yōu)化手段,大幅度提升引擎的渲染性能。為此,我們深入地研究了離屏渲染技術(shù),并結(jié)合導(dǎo)航業(yè)務(wù),提出了一種基于離屏渲染技術(shù)對特定地圖的視圖進(jìn)行性能優(yōu)化的方法。


優(yōu)化原理


在OpenGL的渲染管線中,幾何數(shù)據(jù)和紋理通過一系列變換和測試,最終被渲染成屏幕上的二維像素。那些用于存儲顏色值和測試結(jié)果的二維數(shù)組被稱為幀緩沖區(qū)。當(dāng)我們創(chuàng)建了一個(gè)供OpenGL繪制用的窗體后,窗體系統(tǒng)會生成一個(gè)默認(rèn)的幀緩沖區(qū),這個(gè)幀緩沖區(qū)完全由窗體系統(tǒng)管理,且僅用于將渲染后的圖像輸出到窗口的顯示區(qū)域。我們也可以使用在當(dāng)前屏幕緩沖區(qū)以外開辟一個(gè)緩沖區(qū)進(jìn)渲染操作。前者即為當(dāng)前屏渲染,后者為離屏渲染。

與當(dāng)前屏渲染相比,離屏渲染:

  • 在變化的場景下,因?yàn)殡x屏渲染需要創(chuàng)建一個(gè)新的緩沖區(qū),且需要多次切換上下文環(huán)境,所以代價(jià)很高;

  • 在穩(wěn)定的場景下,離屏渲染可以采用一張紋理進(jìn)行渲染,所以性能較當(dāng)前屏渲染有較大提升。

從上述對比可以看出,在穩(wěn)定場景下使用離屏渲染的優(yōu)勢較大。但因?yàn)榈貓D狀態(tài)隨時(shí)都在變化,所以地圖渲染通常處于前臺動態(tài)渲染狀態(tài)。那么有沒有相對穩(wěn)定的場景呢?答案是肯定的,我們將地圖的狀態(tài)分為沉浸態(tài)和非沉浸態(tài)。顧名思義,在地圖處于變化狀態(tài)的稱為非沉浸態(tài),進(jìn)入穩(wěn)定狀態(tài)稱為沉浸態(tài)。

進(jìn)入沉浸態(tài)的地圖,為我們使用離屏渲染提供了條件。經(jīng)過統(tǒng)計(jì),地圖處于前臺狀態(tài)的場景下,沉浸態(tài)時(shí)間基本上和非沉浸態(tài)時(shí)間相當(dāng),這樣我們采用一張紋理,即可將處于非沉浸態(tài)場景下的地圖渲染出來,大大降低了系統(tǒng)開銷。在鷹眼圖,矢量路口大圖等特定的視圖場景下,地圖基本上均處于沉浸態(tài)。所以這些視圖下采用離屏渲染技術(shù)進(jìn)行優(yōu)化,取得的收益將是巨大的。


工程實(shí)踐


將以上的技術(shù)優(yōu)化原理,代入到實(shí)際的導(dǎo)航應(yīng)用中,流程如下:

離屏渲染在車載導(dǎo)航中的應(yīng)用

離屏渲染通常使用FBO實(shí)現(xiàn)。FBO就是Frame Buffer Object,它可以讓我們的渲染不渲染到屏幕上,而是渲染到離屏Buffer中。但是通常的離屏渲染FBO對象不具備抗鋸齒能力,因此開啟了全屏抗鋸齒能力的OpenGL應(yīng)用程序,如果采用離屏渲染FBO對象進(jìn)行離屏渲染,會出現(xiàn)鋸齒現(xiàn)象。而在非沉浸態(tài)地圖的狀態(tài)下,是開啟全屏抗鋸齒能力的,所以我們必須使用具備抗鋸齒能力的離屏渲染技術(shù)來進(jìn)行地圖渲染技術(shù)優(yōu)化。


抗鋸齒離屏渲染技術(shù)簡述


本節(jié)以iOS系統(tǒng)為例,對抗鋸齒能力的離屏渲染技術(shù)進(jìn)行簡述。iOS系統(tǒng)對OpenGL進(jìn)行了深度定制,其抗鋸齒能力就是建立在FBO基礎(chǔ)上的。如下圖所示,IOS基于對抗鋸齒的幀緩存(FBO)對象進(jìn)行操作,從而達(dá)到全屏抗鋸齒的目的:

離屏渲染在車載導(dǎo)航中的應(yīng)用

接下來具體介紹抗鋸齒FBO的創(chuàng)建步驟:

  • 創(chuàng)建FBO并綁定:

GLuint sampleFramebuffer ;
glGenFramebuffers ( 1 , & sampleFramebuffer );
glBindFramebuffer ( GL_FRAMEBUFFER , sampleFramebuffer );

  • 創(chuàng)建一個(gè)顏色幀緩沖區(qū),在顯存中開辟一個(gè)具有抗鋸齒能力的對象,并將顏色緩沖區(qū)掛載到開辟的對象上。創(chuàng)建一個(gè)深度模版渲染緩沖區(qū),開辟具有抗鋸齒能力的顯存空間,并和幀緩沖區(qū)進(jìn)行綁定:

GLuint sampleColorRenderbuffer , sampleDepthRenderbuffer ;
glGenRenderbuffers ( 1 , & sampleColorRenderbuffer );
glBindRenderbuffer ( GL_RENDERBUFFER , sampleColorRenderbuffer );
glRenderbufferStorageMultisampleAPPLE ( GL_RENDERBUFFER , 4 , GL_RGBA8_OES , width , height );
glFramebufferRenderbuffer ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER , sampleColorRenderbuffer );

glGenRenderbuffers ( 1 , & sampleDepthRenderbuffer );
glBindRenderbuffer ( GL_RENDERBUFFER , sampleDepthRenderbuffer );
glRenderbufferStorageMultisampleAPPLE ( GL_RENDERBUFFER , 4 , GL_DEPTH_COMPONENT16 , width , height );
glFramebufferRenderbuffer ( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER , sampleDepthRenderbuffer );

  • 測試創(chuàng)建的環(huán)境是否正確,避免如顯存空間不足等造成創(chuàng)建失敗的可能:

GLenum status = glCheckFramebufferStatus ( GL_FRAMEBUFFER ) ;
if ( status != GL_FRAMEBUFFER_COMPLETE ) {
  return false ;
}

至此,一個(gè)具備抗鋸齒能力的離屏FBO已創(chuàng)建好,下面將應(yīng)用這個(gè)FBO,步驟如下:

  • 先清除抗鋸齒幀緩存空間重的內(nèi)容:

glBindFramebuffer ( GL_FRAMEBUFFER , sampleFramebuffer );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glViewport ( , , framebufferWidth , framebufferHeight );

  • 開始進(jìn)行一系列的渲染函數(shù)操作,比如準(zhǔn)備頂點(diǎn)數(shù)據(jù),紋理數(shù)據(jù),VBO,IBO,矩陣,狀態(tài)等,并執(zhí)行一系列的渲染指令,選擇指定的shader,及其傳輸數(shù)據(jù)狀態(tài);

  • FBO不是一個(gè)具備直接渲染能力的幀緩存空間,在執(zhí)行完2的操作之后,需要將抗鋸齒的FBO內(nèi)渲染的內(nèi)容通過合并每個(gè)像素,轉(zhuǎn)換到屏幕渲染所在的幀緩存空間去。原理如下圖所示:

離屏渲染在車載導(dǎo)航中的應(yīng)用

代碼如下:

glBindFramebuffer ( GL_DRAW_FRAMEBUFFER_APPLE , resolveFrameBuffer );
glResolveMultisampleFramebufferAPPLE ();
glBindFramebuffer ( GL_READ_FRAMEBUFFER_APPLE , sampleFramebuffer );

  • 以上操作完成后,需要進(jìn)行一些Discard步驟, 將一些原先在當(dāng)前幀緩存中的內(nèi)容忽略掉:

glBindRenderbuffer ( GL_RENDERBUFFER , colorRenderbuffer );
[ context presentRenderbuffer : GL_RENDERBUFFER ];

Android系統(tǒng)基本思路一致,需要采用gles3.0接口提供的抗鋸齒能力來進(jìn)行渲染,在此不做展開。


優(yōu)化對比


優(yōu)化前的鷹眼圖渲染耗時(shí)火焰圖如下:

離屏渲染在車載導(dǎo)航中的應(yīng)用

優(yōu)化后的鷹眼圖渲染耗時(shí)火焰圖如下:

離屏渲染在車載導(dǎo)航中的應(yīng)用

從前后對比圖可以看出,鷹眼圖渲染的耗時(shí),幾乎已經(jīng)消失不見。

從系統(tǒng)的渲染幀率上進(jìn)一步得到驗(yàn)證。從下圖可以看出幀率已經(jīng)恢復(fù)到與不顯示鷹眼圖的情況相當(dāng):

離屏渲染在車載導(dǎo)航中的應(yīng)用

需要注意的是,全屏抗鋸齒損耗資源,除了增加額外的顯存空間,抗鋸齒過程中也會產(chǎn)生一定的耗時(shí)。所以在取得收益的同時(shí),也需要衡量其產(chǎn)生的代價(jià),需要具體問題具體分析。在本案例中,如對比結(jié)果所示,采用抗鋸齒離屏渲染技術(shù)的優(yōu)化產(chǎn)生的收益遠(yuǎn)遠(yuǎn)高于付出的代價(jià)。

離屏渲染在車載導(dǎo)航中的應(yīng)用

關(guān)注高德技術(shù),找到更多出行技術(shù)領(lǐng)域?qū)I(yè)內(nèi)容


向AI問一下細(xì)節(jié)
AI