本篇文章主要向大家介紹GRLAA(GRadient Line Anti-Aliasing,梯度線抗混疊)技術(shù),這種縮寫是一種相對(duì)簡(jiǎn)單且高效的用來(lái)區(qū)分別名的方法,而且經(jīng)常會(huì)在汽車導(dǎo)航應(yīng)用中見(jiàn)到。
在信號(hào)處理的準(zhǔn)則中,存在一個(gè)特定的采樣頻率稱為奈奎斯特頻率 ,當(dāng)我們對(duì)某個(gè)信號(hào)的采樣頻率低于奈奎斯特頻率時(shí),那么從采樣點(diǎn)恢復(fù)恢復(fù)出的信號(hào)是與原始信號(hào)不同的。原始信號(hào)與重構(gòu)信號(hào)體現(xiàn)出的差別,這個(gè)效果成為“混疊”。
這里我們將與大家討論在計(jì)算機(jī)圖形中混疊效果最普遍的兩種體現(xiàn)。第一種就是鋸齒(如圖1所示),主要就是在斜直線的方向上呈現(xiàn)鋸齒狀的階梯。這是在顯卡光柵渲染階段像素之間產(chǎn)生的。
圖1:抗混疊效果對(duì)比(左:禁止,右:允許)
第二個(gè)是采樣混疊。當(dāng)較高頻率(快速變化)的紋理用于渲染遠(yuǎn)景的一些對(duì)象時(shí),比如圖2所示的棋盤模式,我們能夠清晰的看到一些混疊效果,稱為云紋圖案模式。
圖2:紋理混疊:雙線性濾波(左)和三線性濾波-MIP貼圖(右)
目前有多種算法能夠降低這些可見(jiàn)的混疊現(xiàn)象,甚至消除鋸齒效果。然而這些算法會(huì)占用相當(dāng)一部分的系統(tǒng)性能,當(dāng)然這與你使用的硬件平臺(tái)也有關(guān)系。
·超級(jí)采樣抗混疊(SSAA)技術(shù):這是一種比較“暴力”的方式,首先以較高的分別率(最終所期望的整數(shù)倍x2、x4)來(lái)渲染整個(gè)場(chǎng)景,然后對(duì)整個(gè)幀緩沖區(qū)進(jìn)行采樣最終生成我們需要的最終分辨率。最終效果顯示這種方法在質(zhì)量上有保證,而且優(yōu)化了鋸齒和紋理采樣,但是這個(gè)技術(shù)的實(shí)現(xiàn)成本代價(jià)很大。渲染的代價(jià)——包括光柵渲染、分片渲染以及相應(yīng)的帶寬——一般都是分辨率的平方,比如x2 SSAA對(duì)應(yīng)的代價(jià)就是x4,x4 SSAA對(duì)應(yīng)的代價(jià)就是x16。
·多采樣抗混疊(MSAA)技術(shù):這個(gè)方法會(huì)增加每個(gè)像素點(diǎn)的采樣數(shù)量,將渲染的圖像添加到緩沖區(qū),并且能夠存儲(chǔ)每個(gè)像素點(diǎn)的多個(gè)采樣值。然后通過(guò)緩沖區(qū)輸出符合我們所期望的圖像分辨率。這種技術(shù)在PowerVR硬件平臺(tái)上非常高效而且全部是在芯片內(nèi)部解決,節(jié)省了內(nèi)存帶寬。MSAA能夠優(yōu)化鋸齒但是對(duì)于采樣效果無(wú)能為力。
· 基于著色器(Shader)技術(shù)如快速近似抗混疊(FXAA)或亞像素形態(tài)抗混疊(SMAA),這兩種方式都是采用分析來(lái)檢測(cè)和模糊銳利的幾何特性。同時(shí)也會(huì)在顯示環(huán)節(jié)采用后處理算法,付出的代價(jià)一般都是固定的(單個(gè)全屏幕通過(guò))但是會(huì)需要更大的存儲(chǔ)帶寬,顯然這對(duì)于移動(dòng)和嵌入式設(shè)備來(lái)講是非常寶貴的。
梯度線抗混疊技術(shù)簡(jiǎn)介
Gerry Raptis是PowerVR SDK開(kāi)發(fā)團(tuán)隊(duì)的主管,是他開(kāi)發(fā)的GRLAA技術(shù)來(lái)改進(jìn)我們正在設(shè)計(jì)的導(dǎo)航應(yīng)用演示Demo。
GRLAA技術(shù)大幅度提升了道路幾何圖形邊沿的可視化質(zhì)量,所需要的計(jì)算成本也相對(duì)較低。除此以外這使得沒(méi)必要再添加道路輪廓了。輪廓能夠提升道路邊沿的可視化程度,方便用戶識(shí)別,更加清楚的區(qū)分道路邊界。
圖3:抗混疊道路圖形輪廓
這個(gè)方法背后的一般想法就是渲染道路的不透明區(qū),然后逐漸提升透明度,即在道路幾何圖形的上面或者邊緣提升像素的百分比。
任何分片的alpha通道都是基于兩個(gè)值。第一個(gè)是分片區(qū)與道路邊沿的距離,第二個(gè)是這個(gè)距離的變化率,即我們常說(shuō)的梯度,或者更正式的來(lái)說(shuō)就是距離的偏導(dǎo)數(shù)。
每個(gè)分片的RGB顏色數(shù)值是通過(guò)計(jì)算(0,0,0)三者之間的差值來(lái)確定的,生成一個(gè)固定的黑色輪廓(或者其他顏色的輪廓)和道路的平面顏色,然后將統(tǒng)一數(shù)據(jù)傳遞給分片的著色器。所有這些計(jì)算都是基于差值t,這個(gè)值時(shí)通過(guò)相對(duì)距離和變化率來(lái)計(jì)算確定的。后面的內(nèi)容會(huì)更加詳細(xì)的介紹如何推算這些數(shù)值,以及這些數(shù)值對(duì)GRLAA技術(shù)的重要性。
這個(gè)算法目前的形式可能沒(méi)有太大的價(jià)值,只適用于一些具有已知寬度的幾何圖形,比如一條路或者一條線等。
GRLAA技術(shù)詳細(xì)分析
為了確定正確的融合水平,這個(gè)算法需要知道距離道路邊沿的距離,因?yàn)檫@會(huì)影響融合的強(qiáng)度。這意味著數(shù)據(jù)集中每個(gè)幾何頂點(diǎn)需要附加額外的頂點(diǎn)補(bǔ)償數(shù)據(jù),必須是某個(gè)兩個(gè)常量值之一,即-1或1。這個(gè)賦值應(yīng)該在奇數(shù)和偶數(shù)之間變換,這表示道路的一側(cè)會(huì)接收基礎(chǔ)值-1而另一側(cè)則對(duì)應(yīng)基礎(chǔ)值1。這些數(shù)據(jù)會(huì)作為幾何頂點(diǎn)數(shù)據(jù)上傳給圖形卡硬件,經(jīng)過(guò)分片著色器計(jì)算才能確定最終的alpha通道值。
給每個(gè)頂點(diǎn)賦值的基礎(chǔ)值按道路的兩側(cè)來(lái)分是不同的,比如左手側(cè)和右手側(cè)。因?yàn)檫@些頂點(diǎn)數(shù)據(jù)會(huì)被分片著色器用于計(jì)算,它們自動(dòng)會(huì)被硬件進(jìn)行插值轉(zhuǎn)換。
圖4:代表幾何的基礎(chǔ)屬性值
插值轉(zhuǎn)換后的基礎(chǔ)值會(huì)用于計(jì)算當(dāng)前分片與道路邊沿的距離。比如道路中心的分片相對(duì)于道路的兩邊都是最遠(yuǎn)的,意味著相對(duì)距離如果是1,那么就能夠有效的接收不需要融合。隨著分片距離道路邊沿越來(lái)越近,相對(duì)距離會(huì)接近到0,隨之需要接收更多的融合。
float distance = 1.0 – abs(roadBaseVal);
既然我們已經(jīng)確定了道路邊沿相對(duì)道路寬度的相對(duì)距離,那么我們就需要確定渲染的道路輪廓的寬度。算法的第二大部分主要涉及需要渲染的分片百分比。
頂點(diǎn)數(shù)據(jù)的基礎(chǔ)插值作為標(biāo)準(zhǔn)的GLSL偏導(dǎo)(梯度)函數(shù)的參數(shù)。函數(shù)“dFdX”和“dFdY”一般分別用來(lái)計(jì)算給定值在X方向和Y方向上的變化率,而且通常由一個(gè)小型網(wǎng)格(2x2)的分片來(lái)確定的。
計(jì)算過(guò)程能夠輸出當(dāng)前分片距道路邊沿相對(duì)距離的變化速率,根據(jù)當(dāng)前分片與相鄰分片的偏導(dǎo)數(shù)來(lái)推算?;谥付ǚ制淖兓饰覀兡軌蛴?jì)算出合適的alpha通道值。最終結(jié)果則決定了分片的百分比,即定義了道路的邊沿,此外為了繪制一個(gè)平滑的輪廓,我們還需要處理更多個(gè)分片。
#define ANTIALIAS_STRENGTH 2. // Constant affects how much AA will be applied, a higher value //will increase blurring at the cost of reduced detail, while a lower value will reduce the //amount of blurring at the cost of more aliasing.
float blend_range = ANTIALIAS_STRENGTH * sqrt(dFdx(roadBaseVal) * dFdx(roadBaseVal) + dFdy(roadBaseVal) * dFdy(roadBaseVal));
float blend_halfrng = 0.5 * blend_range;
變化率非常的重要,只有它才能夠讓算法不必考慮顯示屏幕上道路的規(guī)模和尺寸。使用偏導(dǎo)數(shù)函數(shù)能夠確定某對(duì)象所占用屏幕空間的百分比,比如下面的情況:
· 如果對(duì)象占用屏幕空間比較?。s放),那么占用的像素點(diǎn)需要進(jìn)行融合渲染來(lái)實(shí)現(xiàn)比較光滑的邊沿效果,等同于占用較大百分比的屏幕像素空間。這是因?yàn)樽兓时容^大,基值是通過(guò)少量分片插值變換得出的。因此需要開(kāi)始渲染距離道路邊沿較遠(yuǎn)的分片,這時(shí)就可能出現(xiàn)鋸齒。
· 相反,如果對(duì)象占用屏幕空間比較大(放大),那么占用的像素點(diǎn)需要通過(guò)融合渲染來(lái)降低占用的總像素?cái)?shù)的百分比。這時(shí)變化率會(huì)比較低,基值的差值轉(zhuǎn)換會(huì)涉及到更多的分片。因此就需要開(kāi)始融合渲染距離道路邊沿比較近的分片。如果結(jié)果比需要的百分比大,那么道路就會(huì)變得模糊。
圖5:變化率,縮小vs放大
所有組件確定后就可以計(jì)算分片的最終顏色值,通過(guò)在輪廓顏色(這里主要是黑色)閾值和道路顏色(統(tǒng)一標(biāo)準(zhǔn))閾值之前進(jìn)行插值變換,我們才能夠計(jì)算出RGB組件的屬性值,插值變換是從相對(duì)距離和變化率衍生而來(lái)的。同時(shí)alpha組件的值也是通過(guò)相似的方式來(lái)計(jì)算,但是不需要進(jìn)行插值轉(zhuǎn)換。
#define OUTLINE_WIDTH 0.25 //How large our outline will be relative to the road width
float outline_distance = clamp(((distance – OUTLINE_WIDTH – blend_halfrng) / blend_range) + 0.5, 0.0, 1.0);
float blend_distance = clamp(((distance – blend_halfrng) / blend_range) + 0.5, 0.0, 1.0);
oColour.rgb = mix(vec3(0.0, 0.0, 0.0), roadColour.rgb, outline_distance);
oColour.a = blend_distance;
相比之前基于紋理抗混疊方法,GRLAA最主要的優(yōu)勢(shì)就是mip-map不需要任何依賴?;诩y理的方法會(huì)在抗混疊像素的數(shù)量上有一定的限制,尤其當(dāng)幾何圖形被最小化后,因此我們采用基于mip-map的圖形技術(shù),本篇文章介紹的算法在處理任何尺寸的幾何圖形時(shí)都不會(huì)有問(wèn)題,能夠輸出非常清晰高質(zhì)量的抗混疊效果的邊緣輪廓,而且不受對(duì)象尺寸和方向的限制。
第二個(gè)優(yōu)勢(shì)就是這個(gè)算法不需要任何的紋理資源,這樣就會(huì)降低整體的存儲(chǔ)帶寬。這絕對(duì)是一個(gè)好消息,因?yàn)獒尫诺囊恍┐鎯?chǔ)帶寬可以用于其他功能,尤其占用較多紋理資源的技術(shù)。
最后,就循環(huán)計(jì)算操作來(lái)講這個(gè)算法的代價(jià)相對(duì)還是比較小的,因此不會(huì)明顯增加計(jì)算負(fù)擔(dān)。我們經(jīng)過(guò)測(cè)量發(fā)現(xiàn)執(zhí)行所有的著色器大概需要20個(gè)操作循環(huán)。此外根據(jù)你所采用的圖像卡核心,設(shè)置中等精確度會(huì)進(jìn)一步降低循環(huán)操作。
評(píng)論