ETH官方钱包

創作內容

25 GP

【程式】電子妖精與顯卡少女的合作——何謂GPU、Direct3D與OpenGL?

作者:Shark│2019-09-17 01:51:34│巴幣:232│人氣:5025
再寫一篇遊戲程式基礎知識介紹。

為什麼玩遊戲除了CPU以外還需要一個顯示晶片?大家常說的Direct3D和OpenGL是做什麼用的?本篇就來為大家解說。



前一篇「【程式】遊戲程式基本架構」裡提到,遊戲程式是一個迴圈不斷執行「取得輸入、計算邏輯、繪製畫面」,其中「繪製畫面」的計算量特別大。

實際算算看有多少工作量
假設有個畫面大小1024×768,類似AVG的對話系統,每畫上一張圖要更新多少像素。


重疊時為了做到半透明效果,每個像素都要把RGBA分量分開,做這樣的計算。
Cr = ArAa + Sr(1-Aa)
Cg = AgAa + Sg(1-Aa)
Cb = AbAa + Sb(1-Aa)


有3D畫面的話,計算更加複雜。
要用3D幾何學計算頂點在畫面上的位置,假如整個場景有20000個頂點,就要計算20000次。
且每個像素要根據3D空間裡的位置計算亮度,做出光照的效果,如果畫面是1024×768,要算786432次。


很複雜吧,由此可看出繪製畫面的計算有多繁重



—GPU的發明—

即使CPU日新月異,遊戲對畫面的要求也越來越高,只靠CPU無法負荷了。
於是……

有廠商發明新的硬體:顯卡少女……不,是圖形處理器,又稱為顯示晶片、Graphics Processing Unit、GPU。

除了CPU以外,把GPU和一塊專用的記憶體裝上去。


把繪圖要用的資料事先傳到顯示記憶體。

CPU可以做多樣的工作,而GPU做成專門做圖形相關計算,犧牲泛用性達到高速,加上GPU讀取顯示記憶體很迅速,如此就可以快速繪製畫面。

市面上賣的顯示卡,是將顯示晶片和輔助零件:記憶體、散熱器、輸入輸出介面、……整合在一塊電路板上,做成插到電腦上就可以使用的狀態。顯卡包裝上標示「NVIDIA GeForce GTX 960」或「AMD Radeon RX 460」之類的是其核心GPU,核心晶片是顯卡性能的關鍵,所以遊戲的系統需求標示都有顯示晶片這一項,玩遊戲時要注意遊戲可以在哪些晶片執行。



—獨立顯卡與集成顯卡—

上圖有分離記憶體的是獨立顯卡,還有一種做法是CPU和GPU共用主記憶體,稱為集成顯卡(內顯)。

由於存取記憶體跟CPU佔用同一條通道,效能會比同時期的獨顯差,但比較節省成本和電力。

至於集成顯卡實際放在哪裡,以前是主機板上除了CPU以外還要配置一個晶片,稱為晶片組,例如筆者以前有一臺筆電是Intel 915GM晶片組,是Pentium M CPU + GMA 900 GPU。
現在大多跟CPU做在同一塊晶片裡,不用額外的晶片了,如Intel HD Graphics、AMD APU、多數電玩主機、以及智慧型手機。

(手機對省電和省空間很要求,必須使用內顯)
(電玩主機把整臺機器都用來玩遊戲,不像PC要同時做很多工作,能用比PC低的配備跑相同的程式;而且製造成本要低,否則我們無法用10000元以內買到一臺主機,所以也使用內顯)

獨顯和內顯的定義是「是否有專用的顯示記憶體」,獨顯不一定真的有一張獨立的「卡」,筆電的獨顯通常也銲在主機板上。



—何謂Direct3D與OpenGL?—

寫程式時,下指令給顯卡少女叫她們工作的方法,不外乎呼叫函式填入參數。
生產GPU的廠商很多,PC有N牌、A牌、I牌,智慧型手機還有ARM、PowerVR等等更加多樣,假如每家廠商各自開規格呢?

例如把貼圖從主記憶體傳到顯示記憶體:


通用規格在科技業裡一向很重要,於是各大廠商因應需求討論,制定出通用規格。Direct3D與OpenGL就是用來控制GPU的通用規格,即電子妖精和顯卡少女溝通的語言。
有了通用規格以後,晶片廠商生產顯示晶片,以及程式人員寫程式就方便多了。

不管對方是哪家廠商做的,只要呼叫glTexImage2D(),顯卡少女就知道是要傳送貼圖資料。

(詳細來講,各家晶片內部的電路畢竟還是不一樣,底層指令也不同,所以使用者還要安裝廠商提供的驅動程式(driver),呼叫glTexImage2D()時,驅動程式會產生晶片固有的指令給晶片執行)
(早期還有其他規格存在,如顯卡還沒有3D計算能力時的DirectDraw、曾與OpenGL競爭的Glide,現在已不再使用)

眾所周知,Direct3D是微軟開發的,只能在微軟的作業系統使用(Windows Desktop、Windows App、XBox系列),OpenGL與後述旳OpenGL ES則沒有限制哪個作業系統能使用它,所以其他作業系統大多用OpenGL。
遊戲機可能有自己的API,但現今各家主機GPU能做的事很相似,各家API大多能找到對應的功能。



—何謂shader?—

或許有人聽過shader這個詞,這又是什麼東西?

一開始控制GPU像是選擇題和填充題,只能在預先設計好的表格裡填參數。這稱為fixed-function pipeline,可翻譯為「固定流程管線」。

(為了便於說明,上面列的設定值比起實際有省略)

隨著3D軟體對畫面的需求增加,GPU必須加入越來越多功能,設定值也愈趨複雜,不斷地增加選項會讓API混亂難以使用。

於是有了另一個發明:shader,兩大陣營分別在D3D 8.0和OpenGL 2.0加入這個功能。

這是讓一部分步驟可以用程式語言寫指令,再把指令給GPU執行,變成像問答題和作文了,靈活度比以往高了很多。這稱為programmable pipeline,可翻譯為「可程式管線」。


有的文章把shader翻譯成著色器,這名稱其實不準確,它的功用不只著色,凡是寫給GPU執行的程式都稱為shader。但中文好像也想不到比較名副其實的名稱,所以平常都用英文shader稱呼。

以下先知道有這些東西存在就好了,詳細可以等真正開始寫shader再學:

最早出現的是vertex shader和pixel shader,把3D繪圖其中兩個步驟變成能寫程式控制,後來又增加了geometry、tessellation和compute三種。

至於寫shader用的程式語言,Direct3D制定的語言稱為HLSL,OpenGL的是GLSL,寫法跟給CPU執行的程式語言(C、C#、Python等)很不一樣。
有些繪圖引擎有自訂的shader語言,像Unity的就是Cg (一個由NVIDIA開發的語言) 加一些客製化而來,引擎內部會把它轉換成D3D和OpenGL看得懂的型式。



—Direct3D與OpenGL的世代演進—

隨著科技演進GPU的功能越來越多,Direct3D與OpenGL也配合新功能推出新版本,常有新功能可以做到≧舊功能,舊功能就不需要的情況。例如有了shader之後打光計算改由shader控制,OpenGL裡glLightfv()、glMaterialfv()之類設定打光的函式就不需要了。

但科技業另一個令人頭痛的問題是向後相容,有些舊程式已經找不到作者或公司改寫成新規格了,但還是有需要使用,要讓這些程式在新硬體也能執行,所以也不能把舊的函式直接移除。

假如把從古到今的功能完全保留在規格書中,這樣規格書裡有一大半是「不建議使用 (deprecated)」、「有替代方法」的,有好幾種方法不知道要用哪一個,會讓人混亂。

因應這個需求,D3D和OpenGL分別做了兩次廢除舊規格的改版:

Direct3D在第10版做了破釜沈舟的改版,使用方法跟D3D9以前完全不一樣,且廢除固定流程管線,使用它一定要學習HLSL,所以D3D10剛出來的時候有很多人說用不慣新的東西。
現在的Windows裡同時裝有D3D10和D3D9的DLL,程式初始化時可以選擇要用哪一個,D3D10是只用新功能,D3D9是可以相容舊功能。
之後的D3D11跟D3D10大同小異。

OpenGL則在3.2版引入了core profile和compatibility profile兩個模式,程式初始化時可以選擇要用哪一個。core是只用新功能,一樣是廢除固定流程管線,必須使用GLSL,用compatibility則是相容舊功能。
OpenGL有個為了手持裝置特製的版本OpenGL ES,也大致是刪除一些可廢除的舊功能,讓規格簡化。
(以前想用用看OpenGL 3.3,花了點時間研究才知道必須建立core profile才能使用,初始化的方法跟以往不同:【程式】新開發機的相容性問題(上))

第二次是Direct3D 12,把10的規格又大改了一次。OpenGL團隊則是開發一個新標準:Vulkan。由於筆者手上有些開發機不支援新標準,目前沒打算使用,對這兩者不是很熟。

學習已經沒有人在用的東西用處不大,不如把時間拿去學習有用的東西,所以假如以後我要寫D3D和OpenGL教學,會從D3D11和OpenGL 3.3教起,不會再用舊版。



—DirectX—

順便提一下DirectX,講到遊戲程式通常都會提到它,這是Windows內建的多媒體函式庫,包含很多部分。
除了用來控制GPU的Direct3D,簡介一下筆者知道的部分。

個人認為目前有使用價值的:
Direct2D 跟Direct3D名稱很像,但並不是用來控制GPU,而是用CPU做2D繪圖,前身是GDI和GDI+。
DirectWrite 繪製點陣或向量字型,必須跟Direct2D同時使用。
XAudio2 用來播放聲音,可以模擬3D場景中,聲音在不同位置發出的效果。
DirectSound 用來播放聲音。照理說可以用XAudio2取代,但Windows 7並沒有內建XAudio2,必須另外裝個runtine才能用,所以我的自製遊戲還是用DirectSound。
DirectCompute 利用GPU的高速運算能力,做圖形以外的數值計算。算是Direct3D的一部分,使用方法是先建立一個D3D device物件,然後寫shader給GPU執行。

個人認為不需要用,或已經被其他東西取代的:
DirectDraw 顯示晶片還沒有3D加速的時代,用來控制顯示晶片的,被Direct3D取代。
DirectInput 讀取鍵盤、滑鼠、手把輸入。Windows API可做到相同的事。
XInput 用在Xbox 360手把或其他廠商做的相容手把(在3C賣場可以看到不少)。應該是為了方便遊戲作者把遊戲從Xbox 360移植到PC上而做的。
DirectPlay 用在網路通訊。用socket也可以做到網路連線。
DirectShow 聲音或影片解碼。被Media Foundation取代。



這次有事耽擱,隔了久一點才發新東西。

雜談:現在有D3D和OpenGL這樣的通用規格,不論PC、遊戲機、手機,控制顯示晶片的方法很一致。查了一些早期遊戲機的資料,即使還沒有3D的時代也有個輔助晶片處理繪圖,那個時代不同主機的CPU和GPU規格差很多,要移植遊戲到不同平臺應該很辛苦吧。

也看過一個Sega Saturn模擬器作者說SS的系統跟PC差很多,有很多獨自功能在現在的D3D、OpenGL無法重現出來,因此SS模擬器很難以開發。



關於插圖:

這幾位是同人場上另一個作品《顯卡少女》的角色,本篇跟顯示卡有關係便讓她們客串一下,從目前有的7個角色裡挑幾個來用。(有跟作者知會過會拿他的角色來用)

作者:哭哭喵的小屋
《顯卡少女》介紹

不過他目前設計的角色都是同一世代的晶片,沒有設計同一家廠商的新舊版,也沒有內顯和智慧型手機晶片的角色,所以插圖有一部分不符合實際情況。

左邊那位「前一個版本」是我自己想的,試著把原來的角色減少一些裝飾。
引用網址:http://www.jamesdambrosio.com/TrackBack.php?sn=4531702
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:程式|遊戲製作|Direct3D|OpenGL|顯卡少女|DirectX

留言共 3 篇留言

哭哭喵
看到自己繪製的角色能夠在其它作者的創作中登場真是莫大的榮幸,Direct3D和OpenGL現在市面上的遊戲幾乎都會用到這篇文章也很清楚的介紹其功能!

09-17 14:32

Shark
想問一下,顯卡少女這個作品有打算繼續創作嗎?像是畫一些短篇故事,或是增加其他類型的角色(不同世代的晶片、內顯等等)讓產品線完整一些。09-20 02:43
哭哭喵
會的,不過這還需要在規劃(因為現在科技產品換代迅速外加我現在繪圖時間很少)。不過在內顯的部分已經有打算把Intel和AMD的CPU加入進這個系列,當然也有和電子妖精聯動的部分。若開始繪製這個系列新本子時有專用知識的部分也需要你的協助了(畢竟在程式部分是我的弱項)[e24]

09-21 19:29

小丑FOOL
你知道 一個叫做極客灣的頻道嗎xd

09-24 18:51

Shark
以前不知,在discord看到才知道的09-26 01:29
我要留言提醒:您尚未登入,請先登入再留言

25喜歡★shark0r 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:FF34遊戲攤位一覽... 後一篇:sprite動畫練習...


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情? 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】