3D繪圖流程
現在顯示卡主要就是玩3D遊戲,而遊戲畫面是屬於3D「即時繪圖」(Realtime Rendering)的領域,它不像工業設計、動畫電影那樣需要超高解析度和精確度,遊戲的3D畫面只要快,一秒至少要畫出30張(動畫電影可能是一兩個小時畫一張),打電動的人才不會覺得延遲,所以娛樂用的GPU都會有很多取巧。而拆解到最簡單,3D繪圖可分成「建立骨架」、「貼圖」和「輸出畫面」三個步驟。
1.建立骨架
由於一些我也不太確定的歷史原因,現在3D繪圖是以三角形或「多邊形」(Polygon)為基礎來建構物體的外型,遊戲裡「所有的」物體都是由一片片三角形堆疊出來的,而每個三角形都是由三個頂點(Vertex)構成,比如附圖的那個人頭骨架,仔細看就會發現它是由數萬個三角形組合而成。這也是為什麼早期遊戲的物體都讓人覺得稜稜角角的,因為需要大量的三角形才能組成近似圓弧狀的物體,若顯示卡不夠力就沒辦法處理大量多邊形,只用少量的多邊形建構外型,就會出現稜稜角角的物件。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-638a24fd99956cc3b9ebda66091a27b6.png)
仔細看這個人頭,他的骨架其實是由數十萬個三角形組合而成。
註1:每一個三角形需要三個頂點,但每「兩個」三角形只需要四個頂點,所以廠商標的GPU規格的三角形組合速度是以每四個頂點形成兩個三角形來計算的
註2:過去曾有「非」多邊形運算為基礎的GPU,它們是以方程式來建構物體外型,方程式可以非常簡單的畫出圓弧,但卻不容易畫出方正的物體,由於自然界或人造物體大多偏方正,也許這是最後採用多邊形的原因。
2.材質貼圖
用三角形建立出物體的骨架之後,物體就有線條式的骨架了,但如果要讓人知道它到底是什麼,一定要貼上一層皮,也就是材質貼圖(Texture),附圖就是貼上皮膚、眼睛、眉毛的材質,其實材質就是圖片,由一點一點的像素(Pixel)構成,貼上之後原來的骨架就會變成人頭了。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-5e592ad786185ca5a29fcd6adc0c95ac.png)
貼上材質再做處理之後,就變成一顆人頭了。
3.輸出畫面
你螢幕是3D的嗎?我相信99.999%正在看這篇文章的人都只有平面的螢幕,但以上兩個步驟運算完會得到一顆真正全3D的人頭,但因為螢幕只有2D平面,所以GPU最後一步就是把這個3D的場景,依照你所看到的視角(攝影機視野),投射成一張2D的畫面,並輸出到螢幕上。
以上就是3D繪圖超簡化流程,GPU要做的就是把多邊形組合起來,在正確的地方貼上正確的圖片,然後輸出畫面到螢幕上,變成下面的遊戲圖。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-dc4e11605ac63b3c72d42a9f5fb481d1.png)
GPU平行運算
仔細看一下遊戲圖,右上角的房子跟右下角的槍其實沒什麼關連,它們根本就是兩組多邊形的骨架,也有各自的貼圖,在遊戲中這兩樣東西也不會互動,如果能把槍和房子的運算分離開來,GPU內裝兩組運算單元,那不就可以同時運算畫面的不同部分,加快運算速度了?事實上,無論3D或2D畫面,會彼此相關的通常只有緊接相鄰的部分,大範圍來看,其實很多地方都是可以各自獨立運算的,也因為如此,GPU才會很早就有SLI或Crossfire這種串連技術的存在。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-10cf2b8e6de541b69257946b35bc78f3.png)
GPU最基本的運算方式就是將畫面上各個像素做獨立運算,很像現在雙核心CPU的的處理方式,但GPU至少都數十或上百個核心,所以平行運算會更徹底。
註3:實際上,GPU運算並非像上圖那樣把畫面分割,那只是簡化說明的示意圖。現在GPU通常是以很小的4x4的區域,16個像素一起做運算(16個只是「通常」,實際數字依各GPU的設計而不同),讓有可能彼此相關的相鄰像素一起運算,但畫面是依序執行的,並沒有真的「分割」,只是一次每16個像素依序丟進運算單元裡,當運算單元大量複製時,就可以同時運算數百甚至上千個像素,彼此大多互不相干。就某種意義上來看,就是運算畫面的不同部分,只是這個「部分」是很微小的區域,真正「大範圍的分割畫面做運算」主要是用在SLI或Crossfire串連技術上。
因此,「平行運算」(Parallel Processing)是GPU最基本的運算概念,就像現在流行的雙核心CPU可一次做兩件事,最新的GPU已經高度平行化到數百個運算單元(可類比成有數百個簡單核心)。由於3D畫面上不同區域的彼此關聯性不高,在很久很久以前,GPU就開始在內部平行拆成好幾個部分,就好像有好幾個核心在一起運算,過去大家常說的「管線」(Pipeline)就是有多少條平行化的部分,從多邊形組合、貼圖到輸出畫面,這樣的3D畫面「生產線」可能有四或八條同時運作,愈多當然就愈快。
和CPU不同的是,GPU的平行運算是自發的,程式人員不需要特別去寫,3D運算本身就有平行化的天性,GPU自己會在內部拆開來做運算,
Shader是什麼?
但現在新的GPU已經不是管線的架構了,從DirectX 8.0開始引進Shader運算的概念之後,現在GPU的運算幾乎全部集中在Shader處理上。Shader是多邊形組合或貼圖之後,GPU再對多邊形與材質做進一步的處理,簡單的說就是各種數學公式(化到最基本,就是加減乘除而已),依照不同的演算法技巧,原本靜態的貼圖或多邊形就會變成動態的特效,比如大家現在在遊戲中常看到水面起伏和物體的反光/凹凸效果,就是利用Shader調整頂點的位置或像素的顏色。
現在遊戲超大量使用Shader,所以GPU硬體也跟著改變,處理材質和輸出畫面的單元並不多,但大幅增加Shader運算單元,比如新的高階GPU至少都上百個Shader單元,但通常只有數十個輸出畫面的單元,因為瓶頸通通卡在Shader上,增加輸出畫面的單元也只是浪費晶片面積而已。因此,看新一代的GPU架構的話,都是一大片Shader運算單元,搭配少量的材質和畫面輸出單元,這已經不是相同的管線有好幾條,而是依照需求量高低做各種單元的配置。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-5516a286240b34eb78639d71efd8c8c3.jpg)
現在遊戲中Shader使用已經無所不在,就這一張單純的場景,見到的每一個表面紋路(地板、牆壁、樹幹、招牌),都是先用單純的圖片,再套上記錄材質高度資訊的檔案,以光源和視角計算光影位置,最後產生這種凹凸的紋路,而計算的程式碼就是Shader。
GPU主要規格
現在,把多邊形、像素、材質、畫面輸出、平行化、Shader記在心裡,GPU的規格和這些息息相關,關於規格的我只能挑出幾項最重要的,GPU的細部技術有幾十項,一時也說不完。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-b429fc653690ed677f8defe101442d78.jpg)
還沒焊到顯示卡上的晶片,廠商朋友送我的,好像是ATI Radeon HD 2600的樣子。我記得前年曾到NVIDIA總部參觀他們的實驗室,垃圾桶裡有一堆這種晶片,就看到全球各大媒體在翻垃圾桶找紀念品,要不是裡面不淮拍照,我一定把那一堆乞丐(包括我)拍下來。
GPU-Z
看CPU資訊的CPU-Z大家都知道,最近出現一支 GPU-Z 則是看顯示晶片的各種資訊,GPU-Z的作者和CPU-Z好像不一樣,只是取了一個很類似的名字,讓大家一看就懂它的功能。目前GPU-Z還在很初期的版本,但我試了NVIDIA和ATI的新卡都沒問題,連最近才剛出的2900 Pro都可以正確辨識。
GPU-Z會秀出幾個主要的GPU規格,包括代號、die size、時脈、頻寬、Shader數量、ROP等等。不過GPU-Z會存取系統資訊,卡車司機防毒軟體會擋下來,讓它通過沒關係,大家可以對照GPU-Z秀出來的規格,往下看各規格的說明。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-f4c33ec05245ceac0df70dd9f84e12b6.png)
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-2f384ce0f08b82542a21c425571521af.png)
支援DirectX版本
DirectX是顯示卡與遊戲溝通的標準,硬體通常通常會向下相容,但GPU和遊戲所用的DirectX版本必須對應才能顯示所有特效。現在最新的DirectX到10.0,遊戲大多還是用DirectX 9.0。DirectX 9.0的GPU是可以玩DirectX 10的遊戲,但就秀不出只有DirectX 10才支援的特效。每一版DirectX 10都會增加新的特色或指令,可以創造出更真實的畫面,而就像GPU已轉變成處理Shader為主,DirectX最重要的部分就是各種Shader指令,最新的DirectX 10不止可以用Shader改變頂點(Vertex Shader)、像素(Pixel Shader),還能移動、產生或砍掉整片多邊形(Geometry Shader),這可以做出物體無限增長(如藤蔓、頭髮、流體等等)的特效。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-93f82d5112f2445fd1e934e4dc442bc3.jpg)
這是DirectX 10的一個demo,場景的地形可以一直增長改變形狀,DirectX 9不是做不到,但DirectX 10做起來會比較輕鬆。
GPU核心時脈
GPU就跟CPU一樣是半導體製程下的產物,但製程方式並不同,且GPU因為高度平行化,運算單元可以大量複製,所以GPU的電晶體數量都輕鬆超越CPU,晶片面積每一代都在挑戰製程的極限,高階GPU的電晶體已經達七億之譜,最高階的CPU還不到一半。GPU靠著平行化的運算,時脈不用太高就有超高的運算能力,目前大約在400~800MHz左右,近期應該還不會突破1GHz的關卡。GPU負責前面所講的3D運算流程,因此直接影響3D效能,但不同架構的GPU不能互相比較時脈,因為它們單一時脈週期所做的事不一樣,NVIDIA的600Mhz和ATI的600Mhz代表意義可能大不相同,對NVIDIA來說,600MHz可能算高,但對ATI可能只是一般時脈而已。
記憶體頻寬
這是顯示卡第二重要的規格,記憶體頻寬(Memory Bandwidth)的計算方式是「記憶體匯流排介面 x 記憶體時脈」,記憶體介面(Memory Bus Width)和時脈的講解可參考「3-1.認識記憶體,時脈和時序的意義」,這裡就不再重複,顯示記憶體和系統不同點是介面和時脈都比較高,介面至少是64位元起跳,目前最高是512位元,時脈則從400MHz~2000MHz以上不等,會因為不同的時脈而採用不同的記憶體,從DDR2到GDDR4都有,「版本」愈高,時脈就愈快。
顯示卡的記憶體介面和時脈分開看並沒有很大意義,相乘的頻寬才是最重要的,由於GPU高度平行化,代表它內部可同時運算很多資料,但也代表後端必須能一次進出大量的資料。在運算3D畫面時,多邊形、材質貼圖、畫面等等都要反覆進出顯示卡的記憶體,容量反而是影響效能的次要因素,頻寬速度才是決定顯示卡的效能的主因之一(僅次於核心規格),若GPU的單元超多,但記憶體頻寬卻跟不上,沒辦法餵飽或支援GPU的話也沒用,所以高階卡一定有較寬的介面與較高的記憶體時脈,組合出超高的頻寬,每秒將近100GB的傳輸速度也不稀奇。
記住一個原則,愈是平行化的系統,就愈需要記憶體頻寬來同時輸出輸入大量資料,但像CPU這種核心較少的循序處理器,就愈需要高速、低延遲的記憶體來輔助(但CPU再往多核心繼續發展下去,頻寬的重要性也會愈來愈突顯)。GPU要的是資料的「量」,CPU要的是資料到達的「時間」。
Stream Processor
在這一代產品之前,GPU內部都還有區分處理頂點和像素的Shader運算單元,但這一代NVIDIA和ATI都統一成Stream Processor(串流處理器),SP不管頂點或像素Shader,通通都可以運算。GPU做成SP不止是為了Shader運算,還有更長遠的用途,但那之後再說。總之,SP就相當於非常簡化的CPU核心,負責Shader裡的數學運算,現在GPU的SP數量從數十到數百不等,依顯示卡的定位價格不同,數量愈多,平行化愈徹底,速度自然就愈快。
目前ATI和NVIDIA對於SP的設計很不一樣,ATI是採取量大但低時脈的方向,NVIDIA則是小量但高時脈,ATI新Radeon HD 2000系列通常有較多的SP,但SP時脈跟核心時脈一樣;NVIDIA GeForce 8的SP數目很少,但時脈至少都有1GHz以上,等於是在GPU核心時脈之外,另外有一個區域跑較高的時脈,加速Shader的運算。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-1119ef6d3d575e189359635335a82cc1.jpg)
現在新的GPU都採用Unified Shader(統一Shader)架構,不再分像素或頂點,這樣不管畫面是多邊形複雜、或是像素特效複雜的,GPU內的Shader運算單元都能保持在滿載狀態,不會浪費。
材質單元和畫面輸出
材質單元負責把遊戲需要的貼圖從記憶體載到核心之中,另外也負責材質的過濾(Texture Filtering),常聽到的AF(Anisotropic filtering,非等向性過濾)就是材質過濾的其中一種演算法,材質要過濾是因為在3D世界裡,物體有遠近之分,遠的物體就只需要較小的貼圖,材質過濾是把大圖片縮成小圖片,貼在遠處的物體上,材質單元的數目會影響貼圖速度和遊戲畫質,愈多當然愈好,不過現在的3D運算趨勢是單一材質做大量Shader處理,所以材質單元反而主要是影響過濾後的畫質。
畫面輸出通常稱為ROP(Raster Opteration)或Render Backend,這是把3D的場景依視角「掃瞄」成2D平面的一張圖片,這會影響GPU的「像素填充速度」(Pixel Fillrate),但一樣,現在3D運算的效能瓶頸都在Shader上,畫面輸出速度已經無所謂了。現在ROP最重要功用是做反鋸齒(Anti-Aliasing)和後處理,反鋸齒是消除畫面輸出時所產生的鋸齒,後處理特效很多,常見的例子就是HDR高動態光源特效。
![[小惡魔的電腦教室] 4-2.顯示卡規格解說,附帶該死的3D圖學](http://attach.mobile01.com/attach/200710/mobile01-9935e205bf8acac120c3a0d9828ed820.jpg)
HDR特效之前並不多,但現在愈來愈多遊戲採用了,圖中有強烈反光的地方,也有很陰暗的角落,這就是HDR高動態光源的成果。
記憶體容量
最後,也是我覺得不大重要的記憶體容量,現在顯示卡的記憶體已經無關2D顯示,主要是存放3D遊戲所需的資料,也就是角色多邊形、貼圖等等,一般來說,低中高階大約是128MB、256MB、512MB以上。記憶體容量會影響效能,但通常是「限制效能」而非「增加效能」,比如高階卡可開更高的特效和解析度,就需要大容量的記憶體,如果容量不夠就會限制晶片的一些效能,因為得透過PCI-E介面從系統主記憶體抓資料;但是低階卡只需要128MB或256MB左右,加到512MB也不會提升效能(在他們所適用的解析度下),反而換上高時脈的記憶體提升頻寬會有用的多。
現在顯示卡的成本有很大一部分是來自於高速記憶體,記憶體的發展速度已經跟不上GPU改朝換代的速度,所以上廠商開始會用記憶體容量來限制原本晶片的能力,並以此來區分價格和定位。
結語

ATI Radeon HD 2600的架構圖,中間一大塊就是Shader運算單元,其他每個區塊都有它的功用。
這篇我只挑了GPU「最重要」的規格來講,其實GPU內部是各種演算法和專利的綜合體,為什麼現在會殺到只剩下兩家大廠,其他如VIA、Intel、Matrox、XGI都黯然退出或只能打打入門市場,因為GPU的進入門檻實在太高了。先不講最複雜的Shader運算單元,光是反鋸齒的演算法、剔除不必要多邊形的技術(3D世界下,因為視角關係很多東西會相互重疊,最好在運算之前就去除)、材質壓縮的方法、或甚至運算平行化時要讓多少相鄰像素一起計算等等,就都是NVIDIA和ATI多年累積的研發經驗,很難在短短一篇文章裡全部講完。
下一篇會專講2D影片加速的部分,這是新一代GPU最為強調的重點之一,也是目前NVIDIA和ATI口水戰打的最猛烈的一塊。