離屏渲染在車載導航中的應用

2021-09-25 22:52:23 字數 3473 閱讀 9670

與手機導航不同,高德地圖的車機版(amap auto)直接面對各大車廠和眾多裝置商。這些b端使用者採用的硬體引數參差不齊,提出的業務需求涉及到渲染中諸多複雜技術的應用,這對渲染效能提出了極高的要求。

最初車機版沿用手機版的當前屏渲染模式,每一幀都需要實時的將地圖元素渲染出來。但在業務實踐過程中,我們發現在多屏渲染和多檢視渲染場景下,cpu負載急劇增高。以鷹眼圖場景為例,在鷹眼圖場景下,地圖存在多檢視渲染的狀態:一張是主地圖,一張是鷹眼小地圖,因此渲染引擎同時渲染了兩個地圖例項物件,下圖右下角即為鷹眼圖:

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

針對上述情況,除了對渲染細節、批次和紋理等進行常規優化外,我們還需要尋找一種全域性性的技術優化手段,大幅度提公升引擎的渲染效能。為此,我們深入地研究了離屏渲染技術,並結合導航業務,提出了一種基於離屏渲染技術對特定地圖的檢視進行效能優化的方法。

在opengl的渲染管線中,幾何資料和紋理通過一系列變換和測試,最終被渲染成螢幕上的二維畫素。那些用於儲存顏色值和測試結果的二維陣列被稱為幀緩衝區。當我們建立了乙個供opengl繪製用的窗體後,窗體系統會生成乙個預設的幀緩衝區,這個幀緩衝區完全由窗體系統管理,且僅用於將渲染後的影象輸出到視窗的顯示區域。我們也可以使用在當前螢幕緩衝區以外開闢乙個緩衝區進渲染操作。前者即為當前屏渲染,後者為離屏渲染。

與當前屏渲染相比,離屏渲染:

從上述對比可以看出,在穩定場景下使用離屏渲染的優勢較大。但因為地圖狀態隨時都在變化,所以地圖渲染通常處於前台動態渲染狀態。那麼有沒有相對穩定的場景呢?答案是肯定的,我們將地圖的狀態分為沉浸態和非沉浸態。顧名思義,在地圖處於變化狀態的稱為非沉浸態,進入穩定狀態稱為沉浸態。

進入沉浸態的地圖,為我們使用離屏渲染提供了條件。經過統計,地圖處於前台狀態的場景下,沉浸態時間基本上和非沉浸態時間相當,這樣我們採用一張紋理,即可將處於非沉浸態場景下的地圖渲染出來,大大降低了系統開銷。在鷹眼圖,向量路口大圖等特定的檢視場景下,地圖基本上均處於沉浸態。所以這些檢視下採用離屏渲染技術進行優化,取得的收益將是巨大的。

將以上的技術優化原理,代入到實際的導航應用中,流程如下:

離屏渲染通常使用fbo實現。fbo就是frame buffer object,它可以讓我們的渲染不渲染到螢幕上,而是渲染到離屏buffer中。但是通常的離屏渲染fbo物件不具備抗鋸齒能力,因此開啟了全屏抗鋸齒能力的opengl應用程式,如果採用離屏渲染fbo物件進行離屏渲染,會出現鋸齒現象。而在非沉浸態地圖的狀態下,是開啟全屏抗鋸齒能力的,所以我們必須使用具備抗鋸齒能力的離屏渲染技術來進行地圖渲染技術優化。

本節以ios系統為例,對抗鋸齒能力的離屏渲染技術進行簡述。ios系統對opengl進行了深度定製,其抗鋸齒能力就是建立在fbo基礎上的。如下圖所示,ios基於對抗鋸齒的幀快取(fbo)物件進行操作,從而達到全屏抗鋸齒的目的:

接下來具體介紹抗鋸齒fbo的建立步驟:

gluint sampleframebuffer;

glgenframebuffers(1, &sampleframebuffer);

glbindframebuffer(gl_framebuffer, sampleframebuffer);

gluint samplecolorrenderbuffer, sampledepthrenderbuffer;

glgenrenderbuffers(1, &samplecolorrenderbuffer);

glbindrenderbuffer(gl_renderbuffer, samplecolorrenderbuffer);

glframebufferrenderbuffer(gl_framebuffer, gl_color_attachment0, gl_renderbuffer, samplecolorrenderbuffer);

glgenrenderbuffers(1, &sampledepthrenderbuffer);

glbindrenderbuffer(gl_renderbuffer, sampledepthrenderbuffer);

glframebufferrenderbuffer(gl_framebuffer, gl_depth_attachment, gl_renderbuffer, sampledepthrenderbuffer);

glenum status = glcheckframebufferstatus(gl_framebuffer) ;

if(status != gl_framebuffer_complete)

至此,乙個具備抗鋸齒能力的離屏fbo已建立好,下面將應用這個fbo,步驟如下:

glbindframebuffer(gl_framebuffer, sampleframebuffer);

glclear(gl_color_buffer_bit | gl_depth_buffer_bit);

glviewport(0, 0, framebufferwidth, framebufferheight);

**如下:

glbindrenderbuffer(gl_renderbuffer, colorrenderbuffer);

[context presentrenderbuffer:gl_renderbuffer];

android系統基本思路一致,需要採用gles3.0介面提供的抗鋸齒能力來進行渲染,在此不做展開。

優化前的鷹眼圖渲染耗時火焰圖如下:

優化後的鷹眼圖渲染耗時火焰圖如下:

從前後對比圖可以看出,鷹眼圖渲染的耗時,幾乎已經消失不見。

從系統的渲染幀率上進一步得到驗證。從下圖可以看出幀率已經恢復到與不顯示鷹眼圖的情況相當:

需要注意的是,全屏抗鋸齒損耗資源,除了增加額外的視訊記憶體空間,抗鋸齒過程中也會產生一定的耗時。所以在取得收益的同時,也需要衡量其產生的代價,需要具體問題具體分析。在本案例中,如對比結果所示,採用抗鋸齒離屏渲染技術的優化產生的收益遠遠高於付出的代價。

離屏渲染在車載導航中的應用

與手機導航不同,高德地圖的車機版 amap auto 直接面對各大車廠和眾多裝置商。這些b端使用者採用的硬體引數參差不齊,提出的業務需求涉及到渲染中諸多複雜技術的應用,這對渲染效能提出了極高的要求。最初車機版沿用手機版的當前屏渲染模式,每一幀都需要實時的將地圖元素渲染出來。但在業務實踐過程中,我們發...

離屏渲染學習筆記

opengl中,gpu螢幕渲染有以下兩種方式 意為當前螢幕渲染,指的是gpu的渲染操作是在當前用於顯示的螢幕緩衝區中進行。意為離屏渲染,指的是gpu在當前螢幕緩衝區以外新開闢乙個緩衝區進行渲染操作。相比於當前螢幕渲染,離屏渲染的代價是很高的,主要體現在兩個方面 要想進行離屏渲染,首先要建立乙個新的緩...

iOS之離屏渲染

on screen rendering 意為當前螢幕渲染,指的是gpu的渲染操作是在當前用於顯示的螢幕緩衝區中進行。off screen rendering 意為離屏渲染,指的是gpu在當前螢幕緩衝區以外新開闢乙個緩衝區進行渲染操作。特殊的離屏渲染 如果將不在gpu的當前螢幕緩衝區中進行的渲染都稱為...