定義一個寬高比(Aspect Ratio);還有垂直可視角度 vertical field-of-view (fovY) 。垂直可視角度即從相機原點到上頂中點和下底中點的連線的夾角,可視角度大可以類比成廣角相機,它張得就比較開,適合拍近距離的物體;可視角度小,透視投影就越不明顯,越像正交投影,就很容易能拍到遠處的物體。水平可視角度可以類比。
這就是說,如果我們想要定義一個視錐的話,定義一個垂直可視角度、定義一個寬高比,其他的變量就都可以轉化得到。
MVP 變換將三維物體投影到二維平面,所有物體都在 [ -1, 1 ]3 的空間里。那么下一步就是如何將這 [ -1, 1 ]3 的立方體在屏幕中顯示出來,這就是光柵化。
屏幕就是一個典型的光柵成像設備。
我們定義屏幕左下角是原點,向右是 x,向上是 y。所有像素點的位置從 ( 0, 0 ) 到 ( width - 1, height - 1 ) 。像素 ( x, y ) 的中心在 ( x + 0.5, y + 0.5 ) 。屏幕的范圍從 ( 0, 0 ) 到 ( width, height ) 。
我們首先不管 z 方向,只管 x、y 方向,即 [ -1, 1 ]2 轉化到 [ 0, width ] × [ 0, height ] 。
就做了一遍縮放和平移。這種變換就叫做視口變換,將 [ -1, 1 ]2 的空間轉化到 [ 0, width ] × [ 0, height ] 的屏幕空間。
那么接下來就是要真正把多邊形打散成像素,即光柵化過程。
使用三角形作為基礎形狀幾何體有眾多好處。三角形是最基礎的多邊形,再退化就變成線段了;任何其它的多邊形都可以拆分成三角形;三角形內部一定是平面的,比如四邊形就不能保證是平面;三角形內外是清晰的,比如多邊形內部如果有洞怎么辦,像甜甜圈那樣,如果不是凸多邊形怎么辦,其他多邊形就有各種各樣的問題,而三角形就可通過向量的叉乘來判斷一個點是否在內部還是外部;只要定義三角形三個頂點的屬性,在三角形內部就可做一個漸變來填充三角形內部所有像素的屬性。
三角形覆蓋的每一個像素點該如何取值呢?
這就是我們下一步要做的,光柵化中最重要的,即判斷一個像素的中心點與三角形的位置關系。
有一個最簡單的辦法來做光柵化,就是通過采樣(Sampling)的方法。采樣其實就是對一個函數離散化的過程,比如 f(x) = sin x ,就要拿各種各樣的點來問函數的值是多少。
那么我們拿像素中心來對屏幕空間進行采樣,就是要算出屏幕空間的函數在某一個像素中心它的值是多少。
我們定義一個 inside 函數:
向量做叉乘,判斷是否都在向量的左側,則在三角形內部,否則就在外部。
考慮一個三角形,按特定順序排列頂點 A、B、C,然后不斷做向量叉乘,要么 z 全是正的,要么 z 全是負的,在這兩種情況下才會判定像素點在三角形內部。
而如果一個點正好在三角形的邊上,那就是自己定義了,可以不做處理,也可以特殊處理。
而且也不需要遍歷所有的像素點,我們知道三角形三個頂點坐標后,就能確定一個最大的正方形區域,那是我們需要考慮的,其他的都不用處理。
光柵化也有其它的加速方法:
每一行我都找它的最左和最右,這樣的話我一個像素也不會多考慮。對於某些細長條的斜向的三角形就很適合用這種方法。
真實情況下的光柵化:
第二種是 Bayer Pattern,可以讓紅綠藍均勻地分布在屏幕空間上,可以看到綠色的點要更多,這是因為人眼本身對綠色最為敏感,比如在相機上也是這樣,對綠色的感光元件會設置更多,從而人眼看上去要更舒服。
在彩色打印機上會有更復雜的分布:
光柵化后能看到一個很明顯的現象,就是鋸齒(Jaggies)
鋸齒就是光柵化圖形學里面一直在致力於解決的嚴重問題。
可以初步分析,我們的采樣率對於信號來說是不夠高的,所以產生了信號的走樣問題(Aliasing)。所以我們下一步就是抗鋸齒,或者反走樣,這是圖形學中重大的技術。