計算機圖學極為廣大,此內容可能還不到 1%,下面內容是由大學時期圖學課程零星印象整理的,可能有錯誤的敘述,歡迎指出(免責聲明QQQ 😂)

什麼是計算機圖學?

計算機圖學(Computer Graphics)又稱電腦圖學,是指用電腦所創造的圖形。更具體的說,就是在電腦上用專門的軟體和硬體用來表現和控制圖像資料。
計算機圖學是為了讓使用者能更容易與電腦互動,對多種媒體有深遠的影響,並徹底改變了動畫、電影和遊戲行業。

計算機圖學的主題包括用戶界面設計、精靈圖形、渲染、光線追踪、幾何處理、計算機動畫、矢量圖、3D建模、著色器、GPU設計、隱式曲面、可視化、科學計算、圖像處理、計算攝影、科學可視化、計算幾何和計算機視覺…還有更多。

計算機圖學、影像處理、電腦視覺、圖形辨識分不清?

有時候會遇到分不清楚計算機圖學、影像處理、電腦視覺、圖形辨識
可以從 input 和 output 的角度來看差異
參考網站 逍遙文工作室-什麼是計算機圖學?

哪裡可以知道最新的圖學趨勢呢?

美國計算機協會(ACM)專為圖學領域組了一個小組叫做 SIGGRAPH,每年都會舉辦會議,例如今年的虛擬會議連結 ( https://s2021.siggraph.org/ ),不僅有最新的圖學技術,也有很多人投稿論文,對學習圖學的人來說就像最高殿堂一樣。

不過由於越來越多人參與這項領域,導致後來又多出了 SIGGRAPH Asia 的會議。(https://sa2021.siggraph.org/en/)

此外還有個推薦的的網站,整理了歷屆 SIGGRAPH 的 Paper,而且是台灣人做的呢!(https://kesen.realtimerendering.com/)

動畫裡應用的計算機圖學?

皮克斯第一部動畫是 1995 年的《玩具總動員》 Toy Story

當年的畫面就包含細膩的陰影、直接照明、間接照明、反射效果,
每一個畫面(frame)依照畫面複雜度,需要一台電腦 45 分鐘到 30 小時畫出來,而且需要 114,240 個畫面,最後約需要 800,000 一台電腦一小時的工時。

當然隨著電腦運算能力飛快地成長,讓現在能計算出更漂亮的畫面,有更自然的光影、更真實的材質或毛髮,下面是玩具總動員 1 到 4 的進展。
https://www.insider.com/pixars-animation-evolved-toy-story-2019-6

遊戲裡應用的計算機圖學?

這是大約與玩具總動員同期1995年的遊戲畫面

而遊戲也跟動畫相同,電腦能力飛快地成長下,這兩年主打真實畫面的遊戲影片

然而遊戲本身關聯到技術就非常多,這邊網站提到一個遊戲引擎需要涵蓋的技術。
http://hightalestudios.com/2017/03/game-engine-architecture-2nd-edition-overview-ch-1-part-2/

那畫面到底是如何產生的呢?

為什麼常常聽到說玩遊戲一定要有 GPU,難道 CPU 不行嗎?

Nvidia 出了一個影片,真實的還原 CPU 和 GPU 是如何畫出圖片的?

GPU 會有如此快速的效果是運用到了硬體加速 ( Hardware acceleration ),簡單形容就是把程式碼軟體要做的事給硬體做,特化某些流程或演算法,其他像是專為機器學習設計的硬體晶片等等的。


我們先來看一下最簡單的繪圖管線 ( Graphics pipeline )

  1. Application: 由應用程式接收指令,執行載入或變換模型或場景

  2. Geometry: 有下列多個步驟要完成

  3. Rasterization: 由於電腦螢幕或圖片都是解析度去顯示,所以必須轉成一個一個點


後來為了能夠客製化畫圖的效果,導入了 Shader,並且有不斷改良過。
目前最重要的有三個,分別是 vertex shaders, geometry shaders, pixel shaders
詳細介紹可以看 https://cg2010studio.com/2011/06/30/geometry-shader/


回歸重點,GPU 的運作方式就像你事先準備好所有模型,設定好位置光源材質等等,最後就開始跑繪圖管線,由於所有的模型都會經過一樣的流程,因此把所有運算方式都寫在 Shader (剛剛提到的座標轉換、投影等等),直接用晶片每個計算單元針對每個點做平行運算,所以 Nvidia 的影片才會表達出所有 Pixel 會一起出來,像是蓋印章的感覺。

可以編寫什麼語言去呼叫 Graphics pipeline ?

我們直接來看遊戲引擎內支援的 Graphics pipeline 語言,下面以最平易近人的 unity 來看

https://docs.unity3d.com/Manual/GraphicsAPIs.html

看來目前是支援以下三種

題外話:常常會與其他用於平行運算用的語言搞混

  • OpenCL:https://zh.wikipedia.org/wiki/OpenCL
    • 可使用CPU、GPU、DSP、FPGA或其他類型的處理器與硬體加速器去進行平行計算,一樣由 Khronos 管理。
  • CUDA:https://zh.wikipedia.org/wiki/CUDA
    • 由 NVIDIA 所推出的一種整合技術,稱為 GPGPU,利用 GUP 來計算原本由 CPU 處理的通用計算任務,這些通用計算任務通常與圖形處理沒有任何關係。

來看看一個 OpenGL 的範例


如何畫出更真實的畫面?

前面提到的 Graphics pipeline 下的繪圖方式稱為 光柵化( Rasterization)技術,雖然運算速率非常快速,這也是為什麼遊戲畫面可以 60 fps / 120 fps 的原因。

有時候需要的是更真實更漂亮的畫面,所以發展出另一套的方式叫做 光線追蹤 ( Ray Tracing )。
原理就是模擬光源照亮我們在現實世界裡看到的 3D 立體物體,光子會在物體間彈跳,然後再進入觀看者的眼睛。
某些物體可能會遮住光線而造成陰影,或者光線會從一個物體反射到另一個物體上,像是我們看到一個物體的影像反射在另一個物體的表面上。
還有折射,指光線穿過玻璃或水這些透明或半透明物體時發生變化的情況。

https://blogs.nvidia.com.tw/2018/03/19/whats-difference-between-ray-tracing-rasterization/


但實際上光線追蹤”理想的作法無法做到“,可以看下面影片得知,無法窮舉所有從光源出發的光線,折射反射等等,並且還會有大量的光線浪費。

後來 Path Tracing 的方式簡化 Ray Tracing,它是基於 蒙地卡羅 的方法 ( 運用統計和機率分佈的概念 ),從鏡頭出發對每個像素點做多次取樣,每次遇到平面則利用 BRDF / BTDF,進行反射或折射單一光線,過程中會牽扯到很多物理數學運算,而取樣越多次或是 Tracing 的路徑越深就越真實。(http://web.cs.wpi.edu/~emmanuel/courses/cs563/write_ups/zackw/realistic_raytracing.html)

因此光線追蹤只是個精神,並沒有定義如何做到,市面上的遊戲宣稱用到光線追蹤,也是用各種優化方式簡化算法,在速度允許的情況下盡量不失真,還原大部分光源對環境的影響。

也就是 光柵化 + 光線追蹤

利用 99 行程式碼寫出 Path Tracing

雖然畫面簡單,但仔細看一下畫面有非常細緻的間接照明、反射折射、和聚光的效果。
https://www.kevinbeason.com/smallpt/

每一個遊戲引擎為了達到全域照明有各種不同算法和工具

在真實世界中,所有的物體都會同時受到直接光線 (直接來自某個光源並照亮某個物體的光線粒子) 和間接光線 (來自某個光源、照射至某個物體後又反射至另一個物體,因此照亮該物體的光線粒子)的照射。「全域照明 (GI)」此一專有名詞,是指建構此效果模型的照明系統。若缺乏間接照明,場景會看起來粗糙和缺乏真實感,然而,直接接收的光線在計算上容易許多,間接照明的計算則極為複雜且運算負荷頗重。 - [Link]