icon
what-is-webgl-learn-the-concept-of-website-3d-interaction

2023年1月27日星期五 下午12:41

什麼是WebGL?學習在網站上實現3D交互的基礎概念

近年來嘅網站應用都趨向與手機應用睇齊,務求提高使用者交互嘅體驗。唔單止要載入速度快,仲要界面元素有反饋。當中又有元宇宙、NFT、虛擬實境等的熱話,呢啲趨勢都指明咗三維嘅技術會越來越常見。
雖然話就話三維元素係近幾年黎先慢慢開始看得多,但係其實呢啲技術係再早十年前已經有了。呢篇筆記就會講下三維技術嘅背景,同埋背後大概係點樣實現的。

WebGL的背景

WebGL全稱是 Web Graphics Library,是一個被主流瀏覽器支援的標準 JavaScript 接口(API)。就如其名字所指,WebGL可以讓開發者在網站上顯示交互2D和3D元素並且交互,而瀏覽器會利用使用者電腦中的GPU去渲染三維模型。

WebGL是基於OpenGL之上創建出來的,更準確來說是基於 OpenGL ES 的。所以也可以說是OpenGL ES的網頁版。

OpenGL

OpenGL (Open Graphics Library)是一個編寫圖形程序的接口(API),作用是提供指令給開發者去編寫圖形話程式,其特性是支援跨平台的使用,例如Windows、macOS、Linux等的操作系統。

OpenGL是從1992年出現的,隨著一直的新增功能,當中有很多複雜的算法。那麼對於手機、遊戲主機、平板等裝置,可能就沒有必要使用到這麼複雜的東西。所以在更好善用資源的原因下,他們的開發團體 Khronos Group 更是專門獨立分開了一套接口 OpenGL ESOpenGL for Embedded Systems),那其實也就是OpenGL的閹割版。

OpenGL ES相當於是OpenGL的子集,主要是用於手機應用以及網頁應用。

WebGPU

可能是因為WebGL太遲起步了,又或者是基於OpenGL的,由下方圖片可見,WebGL的版本更新追不上最新版本的OpenGL。加上GPU的技術也提升了很多。所以接口並沒有支援相對應的新功能,導致WebGL的應用不能夠很好地利用GPU的最佳效能。

google-webgl-issues.webp

而且從2015年開始就有以下三家公司的接口陸續加入戰場,就是Apple的 Metal、Microsoft的 DirectX 12 和Khronos的 Vulkan。所以由各科技公司頂流人才雲集的W3C組織就提出了把上述三個接口打包成為WebGPU,這樣就可以更好地展現GPU的效能。

與其說WebGPU是WebGL的新版本,它的定位更應該是全新的新一代網站圖形API。

雖然可以看到WebGL將會被WebGPU取代的計劃,但是相信在很久的未來當中也經常會看到WebGL的應用,因為現在和過去有很大量由WebGL編寫的網站應用。基於JavaScript的向後兼容理念,也就是現在能跑的程式,在未來任何版本都是能夠正常運行。所以短期內也會繼續看到WebGL的身影。

WebGL背後原理

其實WebGL中最重要的元素就是頂點,三維物件的頂點坐標。WebGL會通過我們提供的頂點以及其他的資訊(例如光源、鏡頭、材質等的全局變量)在二維的空間去渲染出三維物件的效果。簡而言之就是由點連成線,再由線併成面(三角形),最後由不同的三角形組成我們用戶能看到的三維模型。

渲染流程

大概的渲染流程圖可以在下方圖片看到。首先引擎會把開發者提供的一串頂點數組從CPU放入GPU的緩存,然後通過Vertex Shader去計算出所有頂點的坐標。由於Geometry Shader是選用的,所以這裡會跳過它。再來就是光柵化,把頂點連成的面當中的每一個像素計算出來(插值)。之後會通過Fragment Shader去把每一個對應的像素上顏色、光影、材質等的資訊。在渲染出圖像前需要計算出與其他物體的關係,例如深度,物體是否被遮擋了。最後則是把數據都放進緩存區(Framebuffers),準備把數據渲染在用戶的瀏覽器上。

著色器

著色器其實就是一段段的程式代碼,使用一種由C和C++寫出來的語言 GLSL。例如把頂點數組轉換成頂點坐標的 Vertex Shader ,把每一個面中的所有像素逐個上顏色的 Fragment Shader

gl-pipeline.webp
渲染流程圖,來源於duriansoftware的這篇文章。

其餘重要的變量

除了頂點數據以外,渲染引擎還需要很多重要的數值,例如材質、頂點顏色等,詳情可以看這篇文章,裡面講述了渲染引擎還需要什麼資料以及幾種方法去傳值和修改。

小結

WebGL的代碼其實是相當底層的,即是我們需要花費很多時間在編寫一些類似而複雜的代碼才能實現一個簡單的三角形。所以如果不是特別需要注重效能與研發自家框架的開發者,我們一般會使用由大佬們寫好的Library去實現三維的效果。

比較多人使用的是 Three.js,他們把WebGL的代碼打包成比較簡易的函數,這樣就不用花幾十行代碼只能渲染出一個不同三角形。很好地提高了開發速度,對新手入門的門檻也更低。

另外在更多前端框架的出現後,為了讓開發者能在這些前端框架中使用 Three.js,很多大佬也整合了進前端框架就例如 React@react-three/fiber,這些整合也很大程度地簡易了 Three.js 的代碼,所以開發者更能夠把精力放在如何實現吸引用戶的三維交互!

參考資料

  1. A Comparison of Modern Graphics APIs - https://alain.xyz/blog/comparison-of-modern-graphics-apis
  2. WebGPU,下一代 Web 图形技术 - https://www.youtube.com/watch?v=y2dZYG5YTRU
  3. WebGL + GPU = Amazing Results! - https://www.youtube.com/watch?v=qkDg-Y9iHBA
  4. Learn WebGL: All you need in a Nutshell - https://www.youtube.com/watch?v=-nqIzV9OuQM
  5. WebGL Tutorial - Introduction to WebGL - https://www.youtube.com/watch?v=Z64kw2MlDLE
  6. Shaders and the Graphics Pipeline - https://www.youtube.com/watch?v=f2hbOfT12jU
  7. An intro to modern OpenGL. Chapter 1: The Graphics Pipeline - https://duriansoftware.com/joe/an-intro-to-modern-opengl.-chapter-1:-the-graphics-pipeline