1. 程式人生 > >計算機圖形學-光柵渲染概述

計算機圖形學-光柵渲染概述

開篇

本篇主要講的是計算機圖形學中比較重要的主題之一,渲染,並且著重於講述光柵化的渲染方式。

當然,我們要了解光柵渲染這個細分領域(當然這個領域也是及其龐大的),就應該知道它在整個的知識框架中是出於一個什麼位置。

古希臘的哲學家亞里士多德曾說過,瞭解一個事物的最佳方式,就是不斷的把它進行分類,當分無可分的時候,你就能準確的理解這個事物了。

我們要了解光柵渲染,其實先要理解什麼是渲染。這必將引出它的上一層級,計算機圖形學。在圖形管道當中,渲染是作為最後一個主要步驟而存在的,是為模型或者動畫最終呈現外觀的主要步驟。渲染是計算機圖形學的主要的子主題之一,也是我們將要討論的重中之中,因為渲染在實踐中總是與圖形學的其他的模組有著很深的聯絡。

計算機圖形學,實際上是一個具有廣泛的學科關聯的科學體系,無法使用某種簡單的語句進行準確的定義。但這並不妨礙我們去理解它。 通俗來講,計算機圖形就是研究如何使用計算機來建立和顯示圖形的一門科學。

一. 渲染(Rendering)

  • 定義

  • 渲染是通過計算機程式從2D或3D模型生成影象的自動過程。

  • 作用

  • 渲染在建築,遊戲,模擬,電影或電視視覺效果以及設計視覺化的各種場景中都被充分的使用,而每個行業都採用不同的特徵和技術平衡。

  • 實現

  • 渲染的實現主要是封裝成一個個獨立的或者整合在其他遊戲、建模、動畫引擎或者其他軟體裡的渲染器。渲染器是一個基於與光學物理,視覺感知,數學和軟體開發混合而成的程式。

  • 分類

  • 根據實現的技術不同,渲染主要分為

  1. 光柵化( rasterization):將向量頂點組成的圖形進行畫素化的過程

  2. 光線投射(ray casting):正向投射。從影象的每一個畫素,沿視線方向發射光線,光線穿越整個影象序列,並在這個過程中,對影象序列進行取樣獲取顏色資訊,同時依據光線吸收模型將顏色值進行累加,直至光線穿越整個影象序列,最後得到的顏色值就是渲染影象的顏色。

  3. 光線跟蹤(Ray tracing):逆向跟蹤。沿著到達視點的光線的反方向跟蹤,經過螢幕上每一個象素,找出與視線相交的物體表麵點,並繼續跟蹤,找出影響點光強的所有光源,從而算出點上精確的光線強度。

  • 根據渲染的時機來分類

  1. 實時渲染:一般在3D遊戲中使用。指計算機邊計算畫面邊將其輸出顯示。優點是可以實時操控,缺點是犧牲畫質。

  2. 離線渲染:主要用於電影動畫。指計算出畫面時並不顯示畫面,計算機根據預先定義好的光線、軌跡渲染圖片,渲染完成後再將圖片連續播放,實現動畫效果。

一般來說,實時渲染的技術方式都是使用的光柵化渲染。我們講的光柵化就是日常 3D遊戲當中實時渲染出來的,是遍計算遍顯示,所以秒的幀數可能是不穩定的。

二.GPU(graphics processing unit)

  • 為什麼要學習GPU

  • Gpu作為影象處理器,最初被設計時就是用來做實時的影象渲染(光柵化)的加速的。如果實時渲染器中只使用cpu的渲染器叫做軟光柵渲染器,速度慢,實際作用僅能當做學習熟悉渲染過程的手段而沒有實際的現實用途,所以我們要了解光柵渲染器,就必然要首先了解這個作為現代個人主機中造價最高的配件GPU。

  • 歷史

  • 硬體圖形加速器GPU首先出現於渲染管線的末端,首先執行的是三角面掃描線的光珊化。緊接著的下一代硬體沿著渲染管線上溯,到達一些更上級的層次,一些應用程式階段的演算法亦被囊括在硬體加速器的範圍內。致力於使用硬體唯一的好處是其超過軟體實現的速度,速度是它最關心的問題。

  • 在過去的十年,圖形硬體經歷了一個不可想象變革。第一塊包括硬體頂點處理的商業型圖形晶片(NIDIA的Geforce256)在1999年問世。NVIDIA杜撰了圖形處理單元(GPU)這一術語去區分Geforce256和之前其它只處理光珊化的晶片。在此後的幾年,GPU從原來複雜的可配置固定功能管線到高度可程式設計的實現,就像白紙一樣,開發者可在其上實現他們自己演算法。各種可程式設計著色器是GPU控制的主要手段。

  • 定義

  • 圖形處理單元(GPU)是專用電子電路,其被設計為快速操縱和改變儲存以加速在用於輸出到顯示裝置的幀緩衝器中的影象的建立。

  • 比較

  • CPU和GPU之所以大不相同,是由於其設計目標的不同,它們分別針對了兩種不同的應用場景。

  • CPU需要很強的通用性來處理各種不同的資料型別,同時又要邏輯判斷又會引入大量的分支跳轉和中斷的處理。這些都使得CPU的內部結構異常複雜。

  • GPU採用了數量眾多的計算單元和超長的流水線,但只有非常簡單的控制邏輯並省去了Cache。GPU的特點是有很多的ALU和很少的cache. 快取的目的不是儲存後面需要訪問的資料的。

  • 特點

  • GPU對於計算量大,但是單個計算難度簡單的,並且要重複多次的任務使用,這些可並行,且要反覆迭代收斂的東西,通常都是GPU相對擅長的領域。除了圖形加速,還有機器學習,人工智慧,平行計算等等,當然還可以挖礦這樣的。

  • 分類

  • GPU一般而言一般都是光柵化,不過英偉達今年新出了“光線追蹤”GPU Quadro RTX GPU。

三.渲染管線(概念,功能)

渲染是如何進行的呢?為什麼叫光柵化渲染呢?這就涉及到我們的渲染管線。這裡介紹的主要是必須完成的主要功能,是一種概念上的理論模型,而實際的GPU中可能略有不同。

定義:渲染管道或者渲染管線,是一個概念模型,描述了圖形系統在將3D場景渲染到2D螢幕時需要執行的步驟。

  • l 應用程式階段 The Application Stage(CPU)

應用程式階段一般是圖形渲染管線概念上的第一個階段,開發者通過程式的方式對圖元資料等資訊進行配置和調控,最後傳輸到下個階段。

作用:在應用程式階段通常可以實現的有碰撞檢測、加速演算法、輸入檢測,動畫,力反饋以及紋理動畫,變換、模擬、幾何變形,以及一些不在其他階段執行的計算,如層次視錐裁剪等加速演算法就可以在這裡實現。

  • 幾何階段 The Geometry Stage(GPU)

幾何階段主要負責大部分多邊形操作和頂點操作

  • 模型視點變換 Model & View Transform:由模型自己的座標系轉換到世界座標系,然後到視覺空間。由於座標系的的選取不同而進行的變換。

  • 頂點著色 Vertex Shading:什麼是著色呢,著色是指確定材質上的光照效果的這種操作,實際就是確定顏色。因為我們對於渲染而言的要求並不是說只是為了要一個形狀和位置,我們還要讓他真實或者其他的風格,這個時候就需要著色器來編寫顏色方程放在GPU裡執行,快速的進行顏色的確定。

  • 投影 Projection:從三維到二維空間的對映

  • 裁剪 Clipping:對於在螢幕空間外的物體,我們並沒有必要去計算它的顏色等等資訊

  • 螢幕對映 Screen Mapping:螢幕對映階段的主要目的,是將之前步驟得到的座標對映到對應的螢幕座標系上。

  • 光柵化階段 The Rasterizer Stage(GPU)

給定經過變換和投影之後的頂點,顏色以及紋理座標(均來自於幾何階段),給每個畫素正確配色,以便正確繪製整幅影象。這個過個過程叫光珊化(rasterization)。

  • 三角形設定(Triangle Setup)階段:計算三角形表面的差異和三角形表面的其他相關資料。

  • 三角形遍歷(Triangle Traversal)階段:到哪些取樣點或畫素在三角形中的過程通常叫三角形遍歷。

  • 畫素著色(Pixel Shading)階段:畫素著色階段的主要目的是計算所有需逐畫素計算操作的過程。

  • 融合(Merging)階段:融合階段的主要任務是合成當前儲存於緩衝器中的由之前的畫素著色階段產生的片段顏色。此外,融合階段還負責可見性問題(Z緩衝相關)的處理。

四.GPU渲染管線(實際)

前面所講的渲染管線,並不是真正意義上實際的細分步驟,而是一種概念上的理論,那麼實際中GPU是如何進行的呢。

GPU實現了之前所描述的幾何和光珊化的所有概念管線。

這些階段被分割成數個硬體實現的階段,這些階段支援不同程度的可配置性或可程式設計性的。下圖中通過不同的顏色展示了其可程式設計性和可配置性。在這裡可能和之前的概念模型略有不同。

綠色為完全可程式設計,黃色為可配置,藍色為固定功能

可以說,收到我們關注度最高的,應該是三個綠色的著色器階段。

1.可程式設計著色器(名詞解釋):

現代的著色器DirectX10及後面出現的)是用來實現影象渲染的,用來替代固定渲染管線的可編輯程式。

著色器使用與C語法相似的著色語言如HLSL,Cg和GLSL等進行程式設計。這些程式碼被編譯成獨立於計算機硬體的組合語言,亦叫作中間語言。這些組合語言通常在驅動程式中轉換成機器碼。這種設計能相容不同的硬體實現。這種組合語言可被視為定義了一以著色語言編譯器為目標的虛擬機器。

這虛擬機器是一個帶有各種暫存器和資料來源的處理器,它使用一套指令進行程式設計。因為很多的圖形操作是使用短整形的向量(長度為4),處理器有四道的SIMD(單指令多資料)能力。每個暫存器包含四個獨立的數值。32位單精度浮點標量和向量是基本的資料型別;現在也加入了對32位整形數的支援。浮點數何量通常包含了位置(XYZW),法線,矩陣行,顏色(rgba)和紋理座標(uvwq)等資料。整形數通常用於計數器,索引或位掩碼。集合資料型別例如結構件,陣列和矩陣等亦被支援。為了方便向量的使用,拌和技術(swizzling)——向量成員的復現,亦被支援。這是何量的單元可以被任意地重排或重複。相似地,掩蔽技術(masking)即使用所指定的向量單元也是被支援的。

在圖形計算中常用的操作都能在當代的GPU上是高效地執行的。例如,最快的操作是標量和向量的乘法、加法和它們的混合,例如乘加和點積。另一些操作,例如倒數,平方根,正弦,餘弦,指數和對數,相較而言會消耗更多時間,但仍然是相當快速的。

著色語言通過操作符提供了這些普遍的操作(例如通過操作符*和+提供加法和乘法)。其餘則通過內建函式提供,例如atan(),dot()log()及其它。內建函式亦處理更復雜情況,例如向量的單位化和反射,叉積,矩陣轉置和行列式等。

著色器程式可在程式被裝載前離線編譯也可以在執行時編譯。像其它任何的編譯器一樣,這有關於不同輸出檔案和不同程式碼優化水平的設定。編譯好的著色器被以文字字串形式儲存,通過驅動程式傳遞到GPU。

2.著色器的歷史

關於可程式設計著器框架的想法可追溯到1984所Cook的著色樹。Render Man著色語言就是建基於這種想法,它產生於80年代末而時至今天仍廣泛用於電影場景的渲染。在GPU原生地支援可程式語言之前,已有一些以多渲染路徑實現實時可程式設計著色操作的嘗試。1999年的《雷神之錘III:競技場》的指令碼語言是第一個在這方面取得普遍的商業化成功的例子。

在2000年,Peercy等人描述一個將Render Man著色器翻譯並執行在圖形硬體的多個渲染路徑的系統。他們發現GPU缺少兩項能使這個方法變得非常普遍的特性:像紋理座標那樣使用計算結果(附屬紋理貼圖讀取),以及支援擴充套件和精度的紋理和顏色緩衝資料型別。所提出的新型資料(在當時)是16位的浮點數。在那個時候,沒有任何商業化的GPU支援可程式設計著色,雖然大部分已經有高度可配置的管線。

在2001年的上半年,NVIDIA的GeForce3是第一顆支援可程式設計頂點著色器的GPU,可通過DirectX8.0和Open GL擴充套件去使用。這些著色器使用類似彙編的語言進行程式設計並由驅動程式轉換為機器碼。畫素著色器也包含在DirectX8.0中,但SM1.1中的畫素著色器並未達到真正意義上的可程式設計性——十分有限的“程式設計”的支援,即通過驅動程式,與硬體的“暫存器組合器”連線,去轉換紋理貼圖的混合狀態。這些程式不僅在長度上有限制(小於等於12個指令),而且缺少兩個Peercy等人指出的兩個關於可程式設計性極為關鍵的元素(附屬紋理讀取和浮點資料)。

2002年,DirectX9.0對外公佈,其包含著色器模型2.0(並擴充套件到2.X版本)。這個模型是真正的可程式設計頂點著色器及畫素著色器。相同的功能出現在OpenGL的各種擴充套件庫中。支援任意的附屬紋理讀取和16位浮點數儲存,最終完成了所有Peercy等人在2000年提出的一系列需求。有限的著色器資源例如指令,紋理和暫存器有所增加,使得著色器有能力處理更復雜的效果。增加了流程控制。增長中的著色器程式碼長度和複雜度使得彙編程式設計模型變復越來越笨拙和難以處理。幸好,DirectX9.0亦包括了一種新的著色器程式語言,叫HLSL(變級著色語言),HLSL由Microsoft與Nvidia合作研發的,Nvidia亦公開發布了其另一種跨平臺的變體,叫Cg。與此同時,OpenGL架構檢查委員會(Architecture Review Board)公佈與之類似OpenGL版本的語言,叫GLSL(亦被稱為GLslang)。這些語言受到了C程式語言的語法和設計理念以及Render Man著色語言的重大影響。

Shader Model 3.0在2004年被引入並逐步改進,將可選的特性轉化為模型的需求,更進一步的是增加資源的限值和對紋理讀取和頂點著色的有限支援。當新的一代遊戲主機在2005年下半年(微軟的Xbox360)和2006年(索尼的PS3)被引入時,它們都配置了支援Shader Model 3.0的GPU。固定功能管線並非完全廢除:2006年問世的任天堂的Wii遊戲主機則使用了固定功能GPU,但幾乎可以肯定的是這是最後一款這種型別的主機了,因為甚至移動裝置,例如手機亦可使用可程式設計的著色器了。

2007年,業界又向可程式設計方向邁出又一大步。著色器模型4.0(包括DirectX10.0和通過擴充套件的OpenGL)引入了一些主要特徵,例如幾何著色器和流輸出。

著色器模型4.0包括了一個針對所有著色器(頂點、畫素和幾何)的統一的程式設計模型,其公共著色器核心在關面已經描述過了。資源上限進一步增加,並加入了對整形資料型別的支援(包括位運算)。值得注意的是著色器模型4.0僅支援高層語言著色器(DirectX的HLSL和OpenGL的GLSL)——沒有像之前的版本那樣,提供使用者可寫的組合語言介面。

3.頂點著色器

  • 專門處理傳入的頂點資訊的著色器

  • 輸入:VertexBuffer,它由一個或多個頂點屬性流組成。

  • 輸出:顏色

  • 處理資訊:顏色、法線、紋理座標和位置

  • 處理

  • 1. 矩陣變換,從模型空間轉換到齊次裁剪空間。

  • 2.修改/建立/忽略頂點相關屬性的功能

4.幾何著色器

  • 高效地建立和銷燬幾何圖元

  • 把(一個或多個)頂點轉變為完全不同的基本圖形(primitive),從而生成比原來多得多的頂點

  • 輸入:以一個或多個表示為一個單獨基本圖形(primitive)的頂點作為輸入,比如可以是一個點或者三角形

  • 輸出:點線,三角形

  • 處理

  • 把(一個或多個)頂點轉變為完全不同的基本圖形(primitive),從而生成比原來多得多的頂點

5.畫素著色器

  • 進行畫素的處理,是針對光柵化之後的畫素操作

  • 輸入:進行插值後的各個畫素

  • 輸出:顏色

  • 處理資訊:顏色

  • 處理:

  • 處理場景光照和與之相關的效果(凸凹紋理對映和調色)

  • 通過紋理座標取得對應的顏色

  • 令人驚豔的 3D 效果動態光線效果大部分都是 使用片段著色器完成的