通過OpenGL理解前端渲染原理(1)
一、OpenGL
OpenGL,是一套繪製3D圖形的API,當然它也可以用來繪製2D的物體。OpenGL有一大套可以用來操作模型和圖片的函式,通常編寫OpenGL庫的人是顯示卡的製造者。我們買的顯示卡都支援特定版本的OpenGL。
下圖是用OpenGL做的旋轉的立方體。
二、渲染原理
2.1 渲染管道
在OpenGL中,所有東西都在一個3D的空間裡,而我們的螢幕和視窗都是2D的,所以OpenGL需要將3D的座標轉換成2D的座標,做這件事的是OpenGL中的渲染管道(graphics pipeline)。
渲染管道可以分成兩大部分:第一部分將3D座標轉換成2D座標;第二部分把2D的座標轉換成實際的畫素。
2.2 著色器
通常來說,渲染管道把一組3D座標轉換成螢幕上帶有顏色的2D畫素需要經過很多步。上一步的輸出作為下一步的輸入,所有步驟都是高度專一的,每步都有一個特定的函式,且可以很容易地併發執行。顯示卡有數千個處理核心來快速處理渲染管道中的資料,而這些是在每個步驟中通過執行在GPU上的多個小程式來處理的,這些小的程式被稱之為程式著色器(shader)。
其中的一些著色器是可以配置的,開發者可以根據需求配置自己的著色器去替代已經存在的那些,這就讓我們能夠更自由和細粒度地控制渲染的過程。同時,因為它們執行在GPU上,又給我們保留了珍貴的GPU時間,在平時的開發中,我們也要充分利用GPU渲染來提高軟體效能。
著色器通常使用GLSL來寫,全稱是OpenGL Shading Language。
2.3 舉個例子
下圖展示了一個抽象的渲染管線中的步驟,其中藍色部分是我們可以注入自己的著色器。
通過上圖我們發現,要把頂點資料轉換成全渲染的畫素要經過很多步,接下來我們對每一個步驟和程式碼進行簡單的解釋。
我們在渲染管線中傳入一組可以組成三角形的3D座標資料,這組資料即頂點資料。頂點資料是頂點的集合,而一個頂點是一個3D座標的集合。
渲染管線的第一步是頂點著色器(Vertex Shader)。我們這裡傳入的是一個簡單的頂點,頂點著色器可以讓我們做一些基礎的處理操作,比如頂點的屬性。
在初始裝配階段,也就是Shape Assembly階段,從頂點著色器中輸出的頂點會形成一個原始的形狀。本例中,輸出的頂點形成的是一個三角形。
從初始裝配階段到geometry shader階段,我們可以通過發散其他頂點來形成新的圖形,本例中形成了第二個三角形。
在Tessellation Shader階段,可以把上一階段給出的原型圖再分割成若干個小的原型圖。本例中,可以形成更多的三角形來創造一個更加平坦、順滑的環境。這麼說可能難以理解,我們結合下圖來進一步闡述,這就是細分曲面著色器的作用。
細分曲面著色器的下一階段是光柵化階段(Rasterzation stage),在這一階段會對最終的原型和呈現在螢幕上的對應畫素做一個對映,形成fragment,供下一階段的fragment shader使用。
Fragment shader最主要的使命是計算出一個畫素的最終顏色,在這個階段我們可以使用OpenGL中一些高階的特效。通常fragment shader會包含3D介面的多個資料,包括燈光、陰影、顏色等等。
當所有對應的顏色都確定以後,最終的原型將會被傳入最後一個步驟,我們稱之為Alpha test and blending階段。這個階段會判斷相應的深度,比如一個物體可能在另一個物體的後面,那它可能採用其他的顏色;或者如果該物體被遮擋,可能會被裁掉。
如上文所述,我們可以看到整個渲染管線的步驟和邏輯是十分複雜的,這其中包含了很多個可以改變的步驟,但我們一般只操作Vertex Shader 和 fragment shader,其他的著色器我們會直接採用預設的。在實際的OpenGL程式設計中,我們至少需要定義一個Vertex Shader和Fragment shader。(需要說明的是,OpenGL 3.1之前的版本包含了固定管線,從3.1版本開始,固定管線從核心中刪掉了,因此我們必須使用著色器去工作)。
三、總結
本文為該系列文章的第一篇,先簡單介紹OpenGL的一些原理,後續文章中會新增新的程式碼分析,包括著色器(Shader)、紋理(Textture)、變形(transformation)、座標系統(Coordinate systems)、相機(Camera)等。
作者:崔曉迪
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69918724/viewspace-2652314/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- OpenGL/OpenGL ES入門: 影象渲染實現以及渲染問題
- OpenGL實現GPU體渲染GPU
- 你應該知道的前端--渲染原理前端
- 前端渲染過程的二三事前端
- Opengl ES之YUV資料渲染
- Lab_1:練習1——理解通過make生成執行檔案的過程
- OpenGL/OpenGL ES入門: 渲染流程以及固定儲存著色器
- 簡述大前端技術棧的渲染原理前端
- React 服務端渲染原理及過程React服務端
- OpenGL光照計算中法線矩陣原理及推到過程矩陣
- 前端路由原理解析和實現前端路由
- 詳解 OpenGL ES 2.x 渲染流程
- OpenGL 3D 模型載入和渲染3D模型
- vue原理:diff、模板編譯、渲染過程等Vue編譯
- 通過一個案例理解 JWTJWT
- OpenGL入門(1)——建立一個OpenGL專案
- 通過實驗理解PG邏輯結構:1 使用者(角色)
- 理解前端打包工具原理,不在話下前端
- Android硬體加速(二)-RenderThread與OpenGL GPU渲染AndroidthreadGPU
- 瀏覽器渲染過程與原理淺析(一)瀏覽器
- OkHttp原理解析1(框架流程篇)HTTP框架
- Flutter渲染之通過demo瞭解Key的作用Flutter
- 通過 bilibili 的 discovery 理解下 cap
- 透過日誌判斷 Uno Platform 是否在 X11 使用 OpenGL 渲染加速的方法Platform
- 淺談:前端路由原理解析及實踐前端路由
- 前端通過 post 下載檔案前端
- 單步除錯理解webpack裡通過require載入nodejs原生模組實現原理除錯WebUINodeJS
- 前端路由和後端路由,前端渲染和後端渲染前端路由後端
- 原理解析-過擬合與正則化
- Https原理解析及詳細推演過程HTTP
- Shiro原理解析(三)--再談過濾器過濾器
- 服務端渲染到前端渲染,再到“服務端渲染”服務端前端
- CesiumJS 2022^ 原理[3] 渲染原理之從 Entity 看 DataSource 架構 - 生成 Primitive 的過程JS架構MIT
- 通過例項理解 JDK8 的 CompletableFutureJDK
- 螢幕影像渲染原理
- 瀏覽器渲染原理瀏覽器
- 一文詳解 OpenGL ES 3.x 渲染管線
- 實時渲染不是夢:通過共享記憶體優化Flutter外接紋理的渲染效能記憶體優化Flutter