(WIP)Games101:Geometry(幾何)
Games101:Geometry(幾何)
這章我們要來看一些具體的幾何的例子,和一些不同的幾何表示方法,像是下圖玻璃的杯子,上面有各種不同的曲線,這些曲線該如何被描述呢?

再來是像下面這台車,在車頭的曲面上我們可看不到任何三角形,他是一個非常光滑的曲面,不管我們離多近,都看不到離散的三角形,這在圖學裡面又該如何被描述呢?

Ways to Represent Geometry
Implicit geometry
在圖學裡我們有兩種表示幾何的方法,第一種是隱式的幾何(Implicit geometry),另一種是顯式的幾何(Explicit geometry)。 隱式的幾何會以關係式來表示目標形體,例如一個三維空間裡面的單位球可以被寫成
隱式幾何的壞處在於,當今天給我們一個式子,我們難以看出他表示的是什麼形狀,例如下圖是一個圓環,但單看式子我們其實很難看出來他是一個圓環

而隱式幾何的優點在於,我們很容易地可以判斷一個點在不在幾何的面上,因為只需要把我們的座標帶入函數就可以算出來了,通常為 0 就代表在表面上,如果是個負數就代表在幾何內部,反之如果是個正數就代表在幾何外面。 當然,這還是要看你的式子怎麼定義的,但通常我們會設
Explicit geometry
顯式的幾何是比較典型的表示方法,我們之前用的三角形面就是顯式的表示方法,真的給我們一些點,組成三角形,進而將模型表現出來。 但還有另一種顯式的方法,稱為參數映射,以下圖為例,你可以看到我們定義了要如何將給定的

也就是說,我們可以定義一個函數,輸入是
再看一次圓環的例子:

這邊我們把
這就是為什麼他也叫顯式幾何,如果我們想知道這個幾何長怎樣,只要把
顯式幾何的缺點是,當給我們一個三維空間中的點,我們很難去判斷一個點在不在目標幾何的表面上,或說表面的內或外
Implicit Representations in Computer Graphics
現在我們再來多介紹一些隱式的幾何,如剛剛所講的,隱式的問題在於不直觀,例如下圖:

球面的公式我們可能可以看出來,而圓環的公式就已經有點勉強了,再到更右邊的心型就更難看了。 如果我們想要直接找到一個公式能代表上圖中的乳牛,那更是不可能
但還是有一些工具的幫助我們組合出幾何的形狀,所以接下來就來介紹一下
Constructive Solid Geometry
首先要介紹的方法叫做 Constructive Solid Geometry,簡稱為 CSG。 他做的事是透過一系列基本的幾何運算,來組合出一個新的幾何,見下圖:

圖中的 A、B 為一個圓柱和一顆球,他們的參數式很好求,而我們這邊透過布林運算將他們組合到了一起。 這邊的布林運算就與集合論裡面的操作是一樣的,做 intersection 就是取他們交集的部分,取 union 就是兩者的並集,而差集也可以定義,只要從 A 中間減去 B 所佔據的 A 的部分即可,反之同理
透過這些運算和一些簡單的基礎幾何,就可以向上圖下方那樣組出一些複雜的幾何,並輸出成參數式。 現代大部分的建模軟體,像是 Maya、Auto CAD 等都支持這個操作,是一個非常常見的做法
Distance Function
下一個要講的是距離函數,這也是一個用來描述幾何的方法,其表現能力非常強。 對於任何一個幾何,它都不會直接去描述它的表面,而是去描述任何一個點到這個表面的最近距離,這個距離可以是正的或負的
看個例子:

這裡你可以看到有兩個球,當他們逐漸靠近的時候,拓樸結構上會發生一些變化,最後融合起來。 這件事情就是通過對幾何的距離函數做 Blend(混合)達成的
再來看個比較具體的例子:

這邊用的距離函數被稱為 Signed Distance Function(SDF)。 我們的目的是要將 A 與 B 這兩個不同的方塊混合,他們各自擁有一部分的黑色區域與一部分的空白區域。 如果我們直接做線性的混合,那他會變成一個黑⭢灰⭢白的方塊,因為重疊的部分肯定最黑,而中間部分只有 B 有塗色,所以是灰的,而最右邊都沒塗色,所以是白的
但如果我們想要得到的結果是,左邊一半是黑的,右邊一半是白的,這樣的方塊,那就得用 SDF 了。 把 A 求出一個距離函數,B 求一個距離函數,混合後我們就能取到右下角方塊中間的那條黑線。 那條黑線代表的就是距離函數等於 0 的狀態,接下來我們就可以根據其他位置距離函數的值來判斷黑/白(左/右)
知道原理後再看這個例子,就可以知道為什麼會有這樣的結果了:

這個結果是分別求出兩個物體在這個平面空間內的距離函數,然後做 Blend,再恢復成面的結果,邊框處就是 SDF 的值是 0 的點
Level-set method
距離函數還可以配上一些其他的方法用,假設有個距離函數不好寫成參數式的形式,也就是不容易寫成 SDF 的格式,那也沒關係,只要能通過某種方法表述出來就可以了
在這邊我們介紹一種方法,叫做 level-set method,他的想法和距離函數一模一樣,只是他是將函數的結果寫在一個個的格子上的:

你可以看到函數在不同的地方有不同的值,接著我們只需要將值為 0 的地方連起來,就可以把整個物體的表面給表述出來了。 這個概念在地理上已經用了很久,就是所謂的等高線
我們也不一定得定義在二維的格子上,也可以在三維的格子上,結合紋理使用,就可以如下圖這樣描述出人體不同位置的密度訊息:

Fractals
最後,還有一種有名且特殊的隱式方法,就是分形。 分形指的是幾何的子集與和它的整體長得非常像,與我們學的遞迴是同一個道理。 例如說雪花,如果你有看過一些科普文章,就知道如果把雪花放大來看,它每一條邊上其實又都有一些小六邊形,而這些小六邊形的邊上又有更小的六邊性,就這麼不斷重複

分形比較麻煩的是在渲染的時候會引起強烈的走樣,因為它的變化頻率實在是太高了,其渲染是一個挑戰
Explicit Representations in Computer Graphics
顯式的幾何也是有各種不同的方法,像是:
- triangle meshes
- Bezier surfaces
- subdivision surfaces
- NURBS
- point clouds
後面我們會再來一一介紹,首先先從最簡單的開始:點雲
point clouds
點雲在做的事是,不以節點組成表面來描述一個物體,而是把物體表面的每個點都獨立表示出來。 這樣一來只要點足夠多,表示的就能足夠細緻,自然而然就看不到點與點之間的縫隙,也就形成表面了
而一個點自然以空間中的

以右邊的雕像來說,你可以看到它上半部分的點雲密度非常大,因此我們可以很清楚的看到物體的表面。 接著慢慢往雕像的下半部分看,你可以看到面中間已經開始有些縫隙了,點雲的密度慢慢變得稀疏了。 到了最下面,你已經看不出面的存在了。 由此可見,要用點雲表示出一個複雜的模型,會需要非常非常多的點
人們通常在做掃描建模的時候,得到的輸出都是點雲的形式,這自然而然會有個問題:要如何把點雲轉成三角形面? 這個有很多的研究在做