Antialiasing
實際的圖形學中是怎么實現反走樣的呢?
我們不希望實際產出的圖形有鋸齒效果,那怎么辦呢?
從采樣的理論開始談起吧?
Simpling theory
照片也是一種采樣,把景象打散成像素放到屏幕上的過程:
還可以在不同的時間(視頻):
?動畫是定義在幀數上的
一個專業術語:Artifacts(瑕疵)
采樣會產生很多問題,一個是鋸齒:
還有問題比如說摩爾紋:
它怎么產生的呢?
?比如說把左邊的奇數行奇數列都去掉變成小圖,顯示成和大圖一樣大,就能看到摩爾紋了(拿手機拍電腦顯示器)
還有一種有意思的叫車輪效應,也是采樣中出現的問題,比如人肉眼的采樣速度跟不上高速旋轉的物體:
我們如何反走樣呢?
在采樣之前做一個模糊(濾波),做一個模糊再采樣就可以反走樣:
?
注意順序是不能顛倒的,要先模糊再采樣,如果先采樣再模糊就變成了Blurred Aliasing:
?那為什么采樣的速度跟不上信號變換的速度就會走樣?
Antialiasing in practice
Frequency Domain
先來看看頻率吧:
調整前面的系數會得到不同的余弦波(頻率不同)?
介紹正余弦波:
為了介紹傅里葉級數展開(任何周期函數可以將其寫成正余弦函數的線性組合)
還有個東西叫傅里葉變換:
傅里葉變換:把函數變成不同頻率的段并且顯示出來:
?采樣還原出的函數在不同頻率下有出入,走樣本質是信號變化的太快導致采樣跟不上
?時域相乘,頻域卷積,必須要到達兩倍才不會走樣
上面的結果就是采樣兩種頻率完全不同的信號但是采樣結果完全一樣!
?這就是走樣。
Filtering
把某個特定的頻率給抹掉,說出對應信號如何變化
傅里葉變換就是從時域變到頻域:
?中心把其定義成低頻的區域,周圍全都是高頻的區域,在不同頻率的信息多少通過亮度表示
信息多集中在低頻段
水平和豎直方向有道,我們在分析信號的時候我們會認為它是周期性重復的信號,那么對于不周期性重復的信號怎么辦呢?
比如上圖哪里重復了,并不重復對吧,我們通過右邊界在重復左邊界的內容,在邊界會產生劇烈的變化從而產生極其高的高頻,頭頂位置和衣服下邊緣位置的圖像變化劇烈,導致高頻區域為白色
濾波是去掉一些頻率的內容,把低頻信號抹掉,高頻信號有意義:圖像內容的邊界
這種濾波叫高通濾波 (通過濾波器使只有高頻的濾波可通過)
為什么高頻信息就對應邊界呢?
是不是變化很劇烈的才叫邊界?
那就是高頻信息呀,我們如果過濾掉高頻只留下低頻呢?
會發現邊界模糊勒?
還可以做另外的實驗:去掉高頻。去掉低頻,留下中庸之道,就可以提取到一些不是很明顯的邊界特征(中通濾波):
卷積(Convolution)和濾波有關系,本質是一種點乘:
這是要做一個卷積操作(加權平均):
卷積定理: 時域卷積等于頻域相乘,在時域上的乘積相當于在頻域上的卷積:
?卷積操作進行均值模糊,時域的卷積等于頻域的乘積
濾波器本身是一個3×3的盒子,再×是為了不讓圖像整體的顏色值發生變化:
?上面的例子顯示出的結果是這個盒子是一個低通濾波器
時域上的一個小格子轉換成頻域,如果盒子在時域上變大了,那在頻域上該如何變化呢?
盒子在時域上變大,反而在頻域上變小:
?用越大的box做卷積會越來越模糊,如果用一個超級小的box就相當于根本沒有做濾波,也就是說所有東西都被留了下來
采樣是什么?是在重復頻域上的內容(×另外一個函數):
根據卷積定理,時域上的乘積對應到頻域上為卷積,時域卷積等于頻域乘積
采樣就是在重復原始信號的頻譜
1、左側一列的中間是一個周期沖激序列,它在t=nT上縱坐標為無窮大,且頻域(右中)仍是一個沖激序列,若用其與原信號相乘進行采樣,采樣的過程就不是讓左邊上中兩圖簡單相乘就行了,它需要再進行一個過程將其轉化為離散時間序列
2、實際采樣時一個常用的辦法是用一個在t=nT上縱坐標為1的采樣序列乘信號源,這樣可以直接得到采樣信號
3、右上和右中卷積得到右下是可證的
為什么會產生走樣就很顯然了:采樣的不同間隔會引起頻譜以另外一個不同的間隔移動:
?采樣不夠快,沖擊函數頻率低,卷積結果頻率低(原始信號和復制粘貼的信號重合在一起了:發生走樣,頻譜搬移發生混合)
提升分辨率走樣就會好很多(進行多的采樣)
Reduce Alising
怎么改善走樣呢?
1.提高分辨率
2.先去模糊再去采樣(模糊:低通濾波):
?那么在實際的操作中,我們采用什么樣的濾波器來進行卷積操作呢?
用一定大小的低通濾波器對其進行卷積:
?對像素覆蓋的面積求平均:
MSAA?
對更多采樣點進行反走樣(對反走樣的近似,不能嚴格意義上解決反走樣的問題),對大覆蓋的點的近似:
?
?
?
通過更多的樣本進行反走樣的第一步:模糊
?
?MSAA是采樣時提升了計算精度:
?
通過增大計算量抗鋸齒,還有其他抗鋸齒的方法:FXAA(Fast Approximate AA:替換成沒有鋸齒的邊界)、TAA(Temporal AA:找上一幀的信息)
Tips:Super resolution,超分辨率,把小圖放大看到的全是鋸齒,怎樣把采樣不夠的圖變得沒有鋸齒呢?可以通過深度學習的方法:DLSS(猜測)
Visibility/occlusion
首先需要談的問題就是關于可見性,很直觀的一種想法是先畫遠處的物體,再畫近處的物體(把遠處的物體遮擋住),由遠到近做光柵化:(Painter's Algorithm)畫家算法:
但是想要定義深度并不簡單,需要光柵化排序:
上面這種復雜的情況在深度上存在互相遮擋的關系,也就沒辦法用親愛的畫家算法,為了解決這個問題,在圖形學中引入了一個概念:Z-Buffering
Z-Buffering
深度緩沖
?對三角形的覆蓋關系不好判斷,但是可以面向像素排序,記錄像素離我們比較近的距離
最后得到的結果是要渲染出一幅畫面:
這兩幅圖永遠都是同時生成的,那算法在一開始的時候該如何進行呢?
看像素的具體情況,更新最淺深度:
深度緩存工作實例:
?
涂新顏色、更新最小深度值?
深度緩存算法有一個好處:與順序無關,不會有兩個浮點數的值完全一樣(出現深度完全一樣的情況),深度緩存算法被廣泛的應用于圖形學
?