日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

webgl 游戏_如何选择 WebGL 框架和引擎?

發(fā)布時(shí)間:2023/12/10 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 webgl 游戏_如何选择 WebGL 框架和引擎? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

數(shù)據(jù)可視化Sugar-百度智能云?cloud.baidu.com

Sugar 是我們從零開始開發(fā)的 BI 產(chǎn)品,可以不用寫 SQL 制作報(bào)表及大屏頁面,上半年我們發(fā)布了三維場(chǎng)景功能,可以放到大屏中展現(xiàn):

為了實(shí)現(xiàn)這個(gè)功能,我們調(diào)研了大量 WebGL 相關(guān)框架和庫,整理了這篇文章,或許以后對(duì)你有幫助,趕緊先收藏吧。

引擎類型

WebGL 框架和引擎按照定位可以分成這三種類型:

  • WebGL 封裝,定位是簡(jiǎn)化 WebGL 開發(fā),最大的特點(diǎn)是必須自己寫 GLSL 才能用。
  • 渲染引擎,定位是三維物體及場(chǎng)景展示,一般會(huì)抽象出場(chǎng)景、相機(jī)、燈光等概念,上手門檻低,不需要自己寫 GLSL。
  • 游戲引擎,定位是游戲開發(fā),在前面的渲染引擎基礎(chǔ)上,還提供了骨骼動(dòng)畫、物理引擎、AI、GUI 等功能,以及可視化編輯器來設(shè)計(jì)關(guān)卡,支撐大型游戲的開發(fā)。

WebGL 封裝

先說 WebGL 封裝,這種庫主要解決的問題是 WebGL 的 API 過于繁瑣。

WebGL 源自 OpenGL,它最早可以追溯到 1992 年,那個(gè)時(shí)候還是以 C 這種面向過程式的語言為主,所以 OpenGL 的 API 也是過程式的,對(duì)于熟悉面向?qū)ο蟮拈_發(fā)者來說,它的代碼看起來冗長(zhǎng)且可讀性差,因此有必要對(duì)其進(jìn)行封裝和簡(jiǎn)化。

twgl.js

twgl.js?github.com

twgl.js 就是最典型的做法,比如創(chuàng)建一個(gè)最常見物體在 WebGL 中需要這樣寫,其中反復(fù)調(diào)用 bindBuffer 和 bufferData,很容易寫錯(cuò):

const positions = [1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1]; const normals = [1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1]; const texcoords = [1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1]; const indices = [0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23];const positionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); const normalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW); const texcoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoords), gl.STATIC_DRAW); const indicesBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

而使用 twgl.js 就能簡(jiǎn)化成這樣:

const arrays = {position: [1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1],normal: [1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1],texcoord: [1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1],indices: [0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23], }; const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);

twgl 的定位只是減少重復(fù)代碼,并沒有進(jìn)一步抽象,所以使用它和直接用 WebGL 在學(xué)習(xí)成本上沒太大區(qū)別,因此非常適合初學(xué)者,但也意味著它沒什么獨(dú)特的功能。

regl

regl?github.com

和 twgl 單純簡(jiǎn)化代碼相比,regl 提供了跟高層的抽象,將原本的過程式轉(zhuǎn)成了函數(shù)式,使得看起來更符合直覺,比如下面這個(gè)入門三角形比原生 WebGL 要少很多代碼。

const drawTriangle = regl({frag: `void main() {gl_FragColor = vec4(1, 0, 0, 1);}`,vert: `attribute vec2 position;void main() {gl_Position = vec4(position, 0, 1);}`,attributes: {position: [[0, -1], [-1, 0], [1, 1]]},count: 3 })

regl 的原理是動(dòng)態(tài)生成 WebGL 相關(guān)的 JavaScript 代碼然后執(zhí)行,所以它比 twgl 能提供更加簡(jiǎn)化的代碼,也能更靈活地設(shè)計(jì)對(duì)外 API,減少 WebGL 本身過程式帶來的限制,功能也更多,比如能自動(dòng)處理狀態(tài)丟失。

從工程角度看 regl 做得很不錯(cuò),文檔詳盡,有 30000 單元測(cè)試,覆蓋率達(dá)到了 95%,還有工具來追蹤性能變化,可以很放心地使用。

但由于做了一層封裝,導(dǎo)致使用它和原生 WebGL 寫法差異較大,因此不適合對(duì) WebGL 還不熟悉的初學(xué)者,但對(duì)于熟悉 WebGL 的開發(fā)者來說使用它的開發(fā)體驗(yàn)不錯(cuò)。

OGL

oframe/ogl?github.com

OGL 的定位比較特別,它有點(diǎn)介于 WebGL 封裝和渲染引擎之間,比如它最簡(jiǎn)單的這個(gè)例子:

import {Renderer, Camera, Transform, Box, Program, Mesh } from 'ogl'; const renderer = new Renderer(); const gl = renderer.gl; document.body.appendChild(gl.canvas); const camera = new Camera(gl); camera.position.z = 5; const scene = new Transform(); const geometry = new Box(gl);const program = new Program(gl, {vertex: `attribute vec3 position;uniform mat4 modelViewMatrix;uniform mat4 projectionMatrix;void main() {gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,fragment: `void main() {gl_FragColor = vec4(1.0);}`, });const mesh = new Mesh(gl, {geometry, program}); mesh.setParent(scene); renderer.render({scene, camera});

可以看到它一方面提供了渲染引擎才有的場(chǎng)景樹、相機(jī)等概念,另一方面又沒有材質(zhì)和光源,所以需要自己寫 Shader 來完成基本渲染。

因此我覺得它比較適合 TA(Technical Artist) 使用,基于它開發(fā)可以不用了解太多 WebGL 的細(xì)節(jié),專注于圖形學(xué)算法,而且它的 Uniform 變量名和 Three.js 是一樣的,網(wǎng)上找基于 Three.js 寫的例子都能直接用。

不過如果當(dāng)成 WebGL 封裝,它成熟度不如 regl,因?yàn)槿狈卧獪y(cè)試使得預(yù)計(jì)會(huì)有不少 bug,而如果當(dāng)成渲染庫在功能上又沒法和 Three.js 比,因此主要優(yōu)勢(shì)似乎只有體積小了。

luma.gl

luma.gl?luma.gl

luma.gl 是 Uber 開發(fā)的,主要用它開發(fā)地理可視化框架,比如 Desk.gl 和 Kepler.gl,還有無人車數(shù)據(jù)可視化 AVS。

使用前面幾個(gè)庫要同時(shí)支持 WebGL 2.0 和 1.0 需要自己做兼容,而 luma.gl 可以自動(dòng)解決這個(gè)問題,方便在支持 WebGL 2.0 的設(shè)備上優(yōu)先使用 WebGL 2.0,比如直接調(diào)用 createVertexArray,不過這種 api 沒幾個(gè),所以這個(gè)亮點(diǎn)倒是不顯著。

它的獨(dú)特功能其實(shí)是 Shader 模塊化拆分,這對(duì)于寫復(fù)雜的 Shader 很有幫助。


渲染引擎

由于 WebGL 本身只是光柵引擎,基于它開發(fā)需要了解矩陣變換并編寫著色器,所以 WebGL 學(xué)習(xí)門檻很高,光入門就要看特別長(zhǎng)的文檔,比如 WebGL Fundamentals 這個(gè)教程系列就有 60 多篇文章。

WebGL Fundamentals?webglfundamentals.org

相比之下使用渲染引擎就容易得多,它將其中的矩陣變化封裝成了相機(jī)、場(chǎng)景樹,并提供了材質(zhì)和光源,運(yùn)行時(shí)自動(dòng)生成對(duì)應(yīng)的 GLSL,使得即使完全不懂 WebGL 也能用,大大降低了門檻。

對(duì)于大部分應(yīng)用而言,比起前面的 WebGL 封裝,最好還是選擇渲染引擎,因?yàn)榇蟛糠咒秩疽嬉蔡峁┝俗远x Shader 功能,也提供了 GPU 實(shí)例等功能,只是一般不能改渲染管線。

Filament

google/filament?github.com

Filament 是 Google 基于 C++ 開發(fā)的跨平臺(tái)物理渲染引擎,支持 Android、iOS、Windows、Mac 等系統(tǒng),還提供了基于 WebAssembly 的 Web 版本,它用在了 Google 地圖和搜索這兩個(gè)核心 APP 中,因此大概率會(huì)長(zhǎng)期維護(hù),不用擔(dān)心棄坑。

值得一提的是 Filament 的文檔寫得極好,相當(dāng)于一本如何實(shí)現(xiàn) PBR 的教材,可以學(xué)到很多圖形學(xué)的知識(shí)。

Physically Based Rendering in Filament?google.github.io

盡管只是順帶支持 Web,但完善的實(shí)現(xiàn)使得它的渲染效果很突出,在渲染管線上使用了較為新穎的 Clustered forward renderer,因此能支持大量光源。

它生成的 wasm 文件有 2M,不算太大,我原本打算將它引入到 Sugar 中,但這個(gè)渲染庫在 Web 上使用有兩個(gè)缺點(diǎn):

  • 核心是 C++ 寫的,如果功能不滿足只能去改 C++,而這幾乎是必須的,因?yàn)楸┞督o JavaScript 的 API 很少,最簡(jiǎn)單的點(diǎn)擊交互都不支持,各個(gè)組件的設(shè)置也很少,比如相機(jī)要實(shí)現(xiàn)無交互時(shí)自動(dòng)旋轉(zhuǎn)就得改 C++ 代碼,不熟悉 C++ 將寸步難行。
  • 只支持 WebGL 2.0,這點(diǎn)比較致命,導(dǎo)致無法在 iOS 的瀏覽器上使用,看了一下它有調(diào)用 glDrawBuffers,但不清楚用于做什么。
  • 整體上我覺得它是學(xué)習(xí) PBR 渲染實(shí)現(xiàn)原理的優(yōu)秀項(xiàng)目,雖然暫時(shí)不適合在 Web 上用,但值得繼續(xù)關(guān)注。

    Claygl

    ClayGL?claygl.xyz

    Claygl 是 ECharts 核心開發(fā)者 pissang 大神的開發(fā)的 WebGL 游戲引擎,它還用在了 ECharts-gl 項(xiàng)目中,使得 ECharts 在三維圖表方面遠(yuǎn)超所有競(jìng)品,這點(diǎn)我在《如何挑選數(shù)據(jù)可視化框架及平臺(tái) - 前端篇》里介紹過。

    在我看來它最大的亮點(diǎn)是支持延遲著色,目前除了前面提到的 Filament 和后面的 LayaAir,其它 WebGL 引擎都是傳統(tǒng)的前向著色,這種管線在渲染時(shí),會(huì)對(duì)每個(gè)物體計(jì)算所有光照的貢獻(xiàn),類似如下的寫法:

    for node of nodes:for light of lights:output += bdrf(node, light)

    這種實(shí)現(xiàn)的復(fù)雜度隨著光源和場(chǎng)景中對(duì)象的增加而增加,導(dǎo)致光源越多性能越差,這也是為什么在 Web 上看到的三維效果大部分都只使用一個(gè)主光源,類似下面這種效果,只有一個(gè)太陽光:

    來自 https://demos.littleworkshop.fr/infinitown

    如果想實(shí)現(xiàn)接近現(xiàn)實(shí)世界的效果就必須支持多光源,尤其是室內(nèi)和夜晚,比如類似下面這種,使用前向渲染性能太差,無法做到實(shí)時(shí)渲染。

    來自 https://github.com/google/filament

    要解決這個(gè)問題只能使用延遲著色或者分簇(Clustered)前向著色,目前主流的桌面游戲引擎都是使用延遲著色,并配合前向著色來支持透明物體,相關(guān)細(xì)節(jié)推薦看看 lygyue:延遲渲染,ClayGL 也是目前唯一實(shí)現(xiàn)這種管線的開源渲染引擎。

    不過在 WebGL 中實(shí)現(xiàn)延遲著色最大的問題是兼容性,因?yàn)樗蕾?MTR(Multiple Render Targets) 技術(shù),只有在 WebGL 2.0 下原生支持,在 WebGL 1.0 中必須依賴「WEBGL_draw_buffers」擴(kuò)展,但它的兼容性較差,目前桌面瀏覽器的支持率也只有 71%,在手機(jī)上更是只有 2%,想在手機(jī)上使用只能等 WebGL 2.0 普及,但 iOS 一直默認(rèn)不開啟,不知道要再等幾年了。

    Litescene.js

    https://github.com/jagenjo/litescene.js?github.com

    Litescene.js 主要用于開發(fā) WebGL 場(chǎng)景編輯器 WebGLStudio,它其中有些 API 就是專門給編輯器用的,WebGLStudio 是少有的開源 WebGL 編輯器,功能很豐富,但使用體驗(yàn)不好,給我的感受是必須用過 Unity 等編輯器才會(huì)用,上手門檻有點(diǎn)高。

    這個(gè)項(xiàng)目的作者也是不容易,幾乎一個(gè)人開發(fā)了從 WebGL 到前端的所有功能,還開發(fā)了個(gè)前端 UI 庫 litegui,不過技術(shù)棧比較古老,一個(gè)人精力還是有限,代碼中有不少地方都沒空整理,比如加了個(gè)新文件但老的還沒空刪,而且也沒有 release 版本,所以不建議使用。

    Hilo3d

    https://github.com/hiloteam/Hilo3d?github.com

    Hilo3d 是來自支付寶的項(xiàng)目,在 github 上最早提交時(shí)間是 2019 年 8 月,所以是這里面出現(xiàn)最晚的渲染引擎,在它之上還有個(gè)游戲引擎 Sein,它支持使用 Unity 作為場(chǎng)景編輯器,和 LayaAir 類似,但這個(gè)即是優(yōu)點(diǎn)也是缺點(diǎn),雖然省去了編輯器的開發(fā),但導(dǎo)出效果很可能不一致,要反復(fù)調(diào)整。

    這個(gè)渲染引擎最初目的是用于支付寶里自己研發(fā)的小游戲,所以重點(diǎn)是支持移動(dòng)端,但這也將會(huì)是它的限制,比如追求體積小,圖形方面更重視性能而不是視覺效果,以及后期特效比較少等。

    從提交看目前基本只有一個(gè)人,但看起來并不在 github 上開發(fā),更像是拿 github 來定期發(fā)布版本。

    osgjs

    https://github.com/cedricpinson/osgjs?github.com

    ogsl 借鑒了 OpenSceneGraph 的 API,很適合拿來構(gòu)建三維場(chǎng)景,但這個(gè)項(xiàng)目已經(jīng)停止了,主要原因是核心人員跑去創(chuàng)業(yè)了,它的核心開發(fā)人員之一成為了著名在線三維模型網(wǎng)站 Sketchfab 的 CTO,Sketchfab 的模型渲染器就是在它基礎(chǔ)上開發(fā)的,加上了后期特效等功能,算是 Web 領(lǐng)域效果最好的渲染器了。

    xeogl

    xeolabs/xeogl?github.com

    xeogl 很適合用來展示建筑及工業(yè)模型,它提供了標(biāo)注、公告板以及相機(jī)動(dòng)畫等功能,這些功能在其他引擎中都得自己實(shí)現(xiàn)。

    不過這個(gè)項(xiàng)目作者不打算繼續(xù)維護(hù)了,估計(jì)是開源項(xiàng)目收益太小,作者目前主要在開發(fā) xeokit,這個(gè)兩個(gè)項(xiàng)目的定位是一樣的,但 xeokit 商用要收費(fèi),一次性收 €2999,它對(duì)建筑類的項(xiàng)目很友好,內(nèi)置了許多 BIM 相關(guān)的定制功能,比如對(duì) ifc 格式和 BIMServer 的支持,還有支持截面瀏覽,所以使用它可以節(jié)省大量開發(fā)成本。

    不過它在渲染效果方面的功能不多,后期特效只有一個(gè) SAO,因此更適合樸實(shí)無華的工程項(xiàng)目展示。

    A-Frame

    aframevr/aframe?github.com

    A-Frame 是專注做 VR 的渲染庫,最早是 Mozilla 開發(fā)的,目前主要是 Supermedium 的兩個(gè)工程師和一個(gè)谷歌的工程師兼職開發(fā),它的底層渲染基于 Threejs,提供了 inspector 功能,能很方便測(cè)試效果。

    不過我每次玩 VR 都暈到吐,所以再也不關(guān)注這個(gè)領(lǐng)域了,暈問題是人腦的機(jī)制,只能靠幾萬年的進(jìn)化來解決,而且還得是不暈的人比暈的人有生存優(yōu)勢(shì),所以我是等不到 VR 會(huì)火的那天了。


    游戲引擎

    游戲引擎在渲染器的基礎(chǔ)上增加了面向游戲開發(fā)的各種功能,包括 AI、物理、編輯器等,工作量巨大,比起圖形學(xué)算法,更重要還有工程能力,完整的游戲引擎功能可以參考《Game Engine Architechture》這本書,下面的架構(gòu)圖就是來自這本書,可以看到它所覆蓋的面相當(dāng)廣。

    Unreal Engine

    目前最火的游戲引擎是 Unreal Engine 和 Unity,它們都可以使用 Emscripten 編譯出 WebAssembly 版本的項(xiàng)目,直接運(yùn)行在瀏覽器中。

    幾年前在 WebGL 領(lǐng)域中最讓人印象深刻的 demo 就是 Unreal 就和 Firefox 合作的這個(gè)項(xiàng)目,當(dāng)時(shí)我也試過,在等了十幾分鐘加載幾十 M 的 JS 文件后終于跑起來了,但非常卡。

    知乎視頻?www.zhihu.com

    這個(gè) demo 是 2014 年的,但渲染效果放到今天來看都很驚艷,秒殺絕大部分基于 Three.js/Babylon.js 開發(fā)的項(xiàng)目,甚至再過幾年 Three.js/Babylon.js 也做不到,因?yàn)樾枰烤庉嬈鱽韮?yōu)化間接光照。

    前段時(shí)間我嘗試編譯過專門給移動(dòng)端的 SunTemple 項(xiàng)目,在我的黑蘋果 RX 5700 XT 上雖然不卡了,但體積太大,光引擎本身的 wasm 文件就有 82MB,數(shù)據(jù)文件也有 180MB,這樣的體積是不可能放在 Web 上運(yùn)行的,難怪沒人用。

    估計(jì)也是因?yàn)闆]什么人用,Unreal Engine 從 4.24 版本開始不默認(rèn)提供這個(gè)功能,只作為擴(kuò)展存在,交給社區(qū),要用得自己編譯一個(gè),所以 Unreal Engine 目前已經(jīng)基本放棄了 HTML5 版本。

    Unity

    相比之下 Unity 編譯出來的體積小得多,自帶的簡(jiǎn)單 3D 項(xiàng)目編譯出 wasm 只有 4M,所以雖然也很少人用,但至少在線上有真實(shí)見到過幾個(gè)。

    值得一提的是 Unity 還在開發(fā)專門針對(duì)小游戲的 Project Tiny 版本,相當(dāng)于一個(gè)精簡(jiǎn)版的 Unity,它輸出的體積更小,比如這個(gè)官方的 Tiny Racing 項(xiàng)目 wasm 只有 607k,即便是所有模型和圖片加起來的體積也只有 4.4M,雖然這個(gè)項(xiàng)目還在預(yù)覽階段,很多重要功能缺失,但 Unity 目前普及度高,所以它未來有不小潛力,但它在國(guó)內(nèi)的發(fā)展取決于官方的是否重視,比如會(huì)不會(huì)支持微信等。

    Godot

    https://godotengine.org/?godotengine.org

    Godot 是目前最火的開源游戲引擎,它有 1182 個(gè)貢獻(xiàn)者,提交很頻繁,最近在開發(fā)的 4.0 版本,將支持 Vulkan API,并在渲染方面做了加強(qiáng),比如支持 SDFGI。

    它也能導(dǎo)出 WebGL 版本,但只是「能導(dǎo)出」,并沒有專門優(yōu)化過,拿幾個(gè)材質(zhì)測(cè)試了一下生成的 wasm 有 20M,但性能太差,在我的 i9 + RX 5700 XT 上都卡成 PPT,而且卡頓這個(gè)問題官方也不打算修了,預(yù)計(jì) Godot 短期不會(huì)在 Web 領(lǐng)域有所發(fā)展,只能等它未來或許會(huì)支持 WebGPU 了。

    Three.js

    https://threejs.org/?threejs.org

    Three.js 是最知名的 WebGL 項(xiàng)目,Contributions 人數(shù)高達(dá) 1313,和 React 是一個(gè)量級(jí)的,盡管它自身的定位只是渲染引擎,但社區(qū)硬是把不少游戲引擎的功能都加上了,比如物理引擎、貼花、動(dòng)畫等,在源碼中有大量例子,很適合學(xué)習(xí),但不少重要功能,比如 gltf 加載器,都是放在 examples 目錄里,讓人感覺很不正式。

    Three.js 的歷史幾乎和 WebGL 一樣長(zhǎng),它早在 2010 年 7 月 7 日就支持 WebGL 渲染了,那個(gè)時(shí)候 WebGL 規(guī)范還在草案中,要等到 2011 年 3 月才正式發(fā)布,恐怕這就是為什么提到 WebGL 大家都會(huì)想到 Three.js,它大概是第一個(gè)支持 WebGL 的引擎。

    由于知名度最高,Three.js 最大的優(yōu)勢(shì)就是社區(qū)強(qiáng)大,搜索問題能找到很多答案,也有非常多開源和商業(yè)項(xiàng)目使用,比如 Google 的 WebGL Globe、model-viewer、NASA 的 WorldWind、Autodesk 的 Forge Viewer 等。

    但 Three.js 在版本管理方面很不專業(yè),到現(xiàn)在都還沒采用 semver 版本命名規(guī)范,每次發(fā)布都是一個(gè)叫 rXXX 的版本,我見過不少基于 Three.js 的項(xiàng)目都是固定在某個(gè)版本不敢升級(jí)了,比如 Autodesk 就提到過。

    雖然 Three.js 有很多人使用,但因?yàn)檎w代碼質(zhì)量一般,我只推薦用來學(xué)習(xí),而不是用在正式項(xiàng)目中。

    PlayCanvas

    https://github.com/playcanvas/engine?github.com

    PlayCanvas 雖然開源了游戲引擎,但編輯器只有在線服務(wù),所以它的文檔都是介紹如何使用在線編輯器來制作三維場(chǎng)景,并沒有直接使用這個(gè)引擎的入門文檔,要用只能通過 example 和 api 來了解,看起來官方并不希望大家直接使用引擎,所以如果不想用它的在線編輯器,這個(gè)引擎就只適合學(xué)習(xí)過其它引擎的開發(fā)者。

    從引擎功能角度看弱于 Three.js 和 Babylon,但成熟度比 Three.js 好,Three.js 的很多功能是第三方貢獻(xiàn)的,質(zhì)量參差不齊,注釋也很少。

    雖然它沒使用延遲著色,但提供了運(yùn)行時(shí) bake 的功能,也能高效支持靜態(tài)多光源。

    PlayCanvas 其實(shí)在 2017 年被 Snap 悄悄收購了,被期望于制作 Snap 上的 HTML5 游戲。

    Egret

    egret-labs/egret3d?github.com

    Egret 和后面介紹的 LayaAir 和 cocos 都是國(guó)內(nèi)創(chuàng)業(yè)公司開發(fā)的游戲引擎,Egret 最早是通過一款《圍住神經(jīng)貓》的 HTML5 游戲莫名其妙火的,它最早只支持 2D,但也在 2018 年 5 月推出了開源的 Egret 3D。

    Egret 3D 引擎使用了 ECS 架構(gòu),所以它的編輯器提供了類似 Unity 那樣添加組件的能力。

    但 Egret 3D 開源后沒多久就陷入停滯狀態(tài)了,最新發(fā)布的版本是 2018 年 9 月,據(jù)說是在重構(gòu)新版,然而已經(jīng)過去一年了,可能 3D 并不是公司的重點(diǎn),開源的版本甚至連 license 都沒說明,加上文檔比較簡(jiǎn)陋,所以不推薦使用。

    LayaAir

    https://github.com/layabox/LayaAir?github.com

    LayaBox 公司最早推出的是 LayaFlash 工具來將 Flash 頁游裝成 HTML5 版本,隨著 Flash 的沒落,他們又開發(fā)了基于 Web 技術(shù)的 LayaAir 引擎。

    LayaAir 的三維編輯器主要依賴 Unity,它甚至不能直接使用 WebGL 中最常用的 glTF 格式,要使用三維模型必須先導(dǎo)入到 Unity 中,然后再通過插件轉(zhuǎn)成 LayaAir 所使用的格式。

    比起 Three.js/Babylon,LayaAir 有兩個(gè)比較大的優(yōu)勢(shì),一個(gè)是對(duì)小程序支持友好,這個(gè)算是國(guó)內(nèi)特色,Three.js/Babylon j的核心開發(fā)者也沒條件測(cè)試,所以實(shí)際用起來容易遇到 bug,玩玩需要改引擎本身代碼才能解決;另一個(gè)是近期實(shí)現(xiàn)了 Clustered Forward 渲染,可以支持大量光源。

    LayaAir 還提供了生成原生 Android/iOS 程序的 LayaNative,這里并非使用 WebView,所以更容易過審。

    但需要注意 LayaAir 只是源碼開放,并不是真正的開源項(xiàng)目,使用前需要仔細(xì)閱讀它的協(xié)議,比如未經(jīng)授權(quán)是不允許對(duì)引擎代碼進(jìn)行修改的,免費(fèi)使用需要加 LayaBox 的 logo。

    從提交歷史看,LayaAir 提交量最多的開發(fā)者在今年 4 月份忽然停止了,似乎是被阿里挖走了,不知道對(duì)引擎本身的發(fā)展會(huì)有多大影響。

    cocos

    Cocos引擎_游戲開發(fā)引擎?www.cocos.com

    cocos 曾經(jīng)是最流行的 2D 手游引擎,但隨著游戲逐漸轉(zhuǎn)向 3D,它在 3D 方面和 Unity 差距太大,就漸漸淡出大家的視野了。

    cocos 所屬的觸控科技本來打算 2014 年在美國(guó)上市,但由于對(duì)估值不滿意,尤其是 cocos2d-x 的 MIT 協(xié)議被認(rèn)為價(jià)值幾乎為零,所以最后放棄了上市,具體細(xì)節(jié)可以看看創(chuàng)始人的回答cocos2dx 還有未來么? - 陳昊芝的回答,其中還提到了和 Unity 的故事,比如本來還想收購 Unity 但被拒了,在放棄上市后,觸控經(jīng)歷了很多危機(jī),人數(shù)也收縮為之前的 1/5,從那時(shí)起 cocos2d-x 其實(shí)就在走下坡路了,逐漸被 Unity 超越。

    盡管很艱難,觸控一直沒放棄引擎的開發(fā),在 2019 年 10 月發(fā)布了 Cocos Creator 3D,和 cocos2d-x 基于 C++ 不同,Cocos Creator 3D 是基于 TypeScript 開發(fā)的 WebGL 引擎。

    在協(xié)議方面,Cocos Creator 3D 吸取了 cocos2d-x 的教訓(xùn),和 LayaAir 一樣只是源碼開放,它也有一份定制的協(xié)議,有很多限制,需要仔細(xì)閱讀。

    盡管 Cocos Creator 3D 很想成為 Unity,編輯器在很多細(xì)節(jié)點(diǎn)上都參考了 Unity,比如資源管理的 .meta 文件,基于 ECS 的組件機(jī)制等,但 WebGL 的限制使得它只能用做小游戲的引擎,因?yàn)?OpenGL ES 2.0 功能的缺失,雖然可以發(fā)布到微信、百度、支付寶等平臺(tái)上,但在重度游戲領(lǐng)域沒法和 Unity 競(jìng)爭(zhēng)。

    引擎方面功能和 LayaAir 類似,不過它有動(dòng)畫、例子編輯器,在編輯器方面比 LayaAir 好得多,不依賴 Unity,不過因?yàn)槭褂昧饲跋蛑?#xff0c;同樣不能支持多光源,雖然它基于 AABB 包圍盒做了光源裁剪,但這種方式的性能比較依賴場(chǎng)景光源和物體的分布情況,比如物體很大又有很多小光源的時(shí)候,幾乎裁剪不掉幾個(gè)光源。

    Babylon

    https://babylonjs.com/?babylonjs.com

    最后壓軸的是 Babylon,它也是 Sugar 最終采用的 WebGL 引擎,不僅功能強(qiáng)大,代碼質(zhì)量也很高,TypeScript 類型完善,幾乎每個(gè)函數(shù)都有注釋。

    我個(gè)人的使用體會(huì)是 Babylon 雖然入門要復(fù)雜點(diǎn),但功能成熟度要比 Three.js 高不少,Three.js 至今在 gLTF 的支持上還有 bug,而 Babylon 是唯一通過所有測(cè)試的框架,如果要深入使用 gLTF,Babylon 是最好選擇,因?yàn)樗€支持大量擴(kuò)展,比如 KHR_mesh_quantization、KHR_draco_mesh_compression、KHR_texture_basisu、MSFT_lod 等,這些擴(kuò)展能顯著減小體積和提升性能。

    Babylon 在材質(zhì)方面功能豐富,除了基礎(chǔ)的 PBR,還提供了用于皮膚的次表面渲染 SubSurface、用于車漆的 ClearCoat、用于布料的 Sheen,以及用于光盤之類的各向異性材質(zhì) Anisotropy 等等。

    在后期特效方面有 Lut 顏色校正、Tonemap 映射、SSAO、鏡面反射、Bloom 等常見特效,還有基于屏幕的反射 SSR(Screen Space Reflections)。

    目前 Babylon 在渲染方面也是使用最傳統(tǒng)的前向著色,如果要改造成類似 ClayGL 那樣的延遲著色成本太高,兼容性也不好,所以最好的選擇是用分簇來減少光源,這個(gè)想法在 2017 年就有提出,但然后就沒有然后了。

    除了在渲染方面的功能很多,Babylon 的周邊工具也很豐富,最近還推出了類似 UE4 藍(lán)圖的材質(zhì)編輯器。

    我個(gè)人不喜歡使用藍(lán)圖這種方式來開發(fā)業(yè)務(wù)邏輯,因?yàn)閺?fù)雜場(chǎng)景下信息密度太低了,大量線條看起來很累,但用藍(lán)圖來開發(fā)材質(zhì)卻很方便,因?yàn)橹鞑缓谜{(diào)試,而在藍(lán)圖中可以方便預(yù)覽每個(gè)節(jié)點(diǎn)的效果,極大提升效率,不過也可能是我在著色器方面比較水。

    不過 Babylon 的這個(gè)材質(zhì)編輯器目前功能還比較弱,缺少流程控制語句等功能,和 Unreal Engine 差距很大。

    另一個(gè) Babylon 中最實(shí)用的工具是 Inspector,它可以像瀏覽器的開發(fā)者工具那樣,選中場(chǎng)景中的某個(gè)節(jié)點(diǎn),就能查看和修改它的屬性和材質(zhì)等,實(shí)時(shí)看到效果,比不斷改代碼調(diào)整方便多了。

    另外 Babylon 還開發(fā)了可以直接運(yùn)行在桌面的 BabylonNative,和 LayaNative 類似,基于封裝了跨平臺(tái)的渲染(基于 bgfx)、網(wǎng)絡(luò)等接口,這樣編譯出一個(gè)桌面 Babylon 項(xiàng)目就不需要像 Electron 那樣附帶一個(gè)百兆的 Chromium 了,然而在桌面領(lǐng)域游戲引擎多如牛毛,競(jìng)爭(zhēng)過于激烈,BabylonNative 看起來希望不大。

    Babylon 最后一個(gè)亮點(diǎn)是正在開發(fā) WebGPU 版本,而其他引擎都沒開始做,所以等 WebGPU 發(fā)布后,Babylon 應(yīng)該是首批支持的,將得到更多關(guān)注。

    小結(jié)

    前面說了那么多,如果沒空看的話可以記一下我的看法:

    • 對(duì)于一般 WebGL 開發(fā),推薦使用 Babylon.js。
    • 如果要支持微信小程序,最好用國(guó)內(nèi)的 LayaAir 和 Cocos,但需要注意它們只是源碼開放,并不是無條件免費(fèi)使用,需要仔細(xì)閱讀使用協(xié)議。
    • 如果只想寫原生 WebGL 特效,建議用 regl。
    • 如想支持大量光源和后期特效,又不需要支持 iOS,用 Claygl。
    • 如果熟悉 Unity,直接用它導(dǎo)出 WebGL 也是可行的。

    后記:WebGL 為什么沒火起來?

    10 年前 WebGL 剛出來的時(shí)候我很期待,因?yàn)榭梢栽?Web 上做出酷炫的三維效果了,看起來前景一片光明,然而現(xiàn)在除了小游戲,其它地方幾乎沒有人使用,也很少前端工程師了解,為什么呢?在我看來主要是這幾方面的原因:

  • WebGL 和前端開發(fā)差異性太大,前端工程師學(xué) WebGL 相當(dāng)于刪號(hào)重練,除了繁瑣的 API,圖形學(xué)的數(shù)學(xué)知識(shí)也導(dǎo)致了門檻高,最基礎(chǔ)的 MVP 就能勸退不少初學(xué)者,更別說后面的輻射度量及采樣學(xué)知識(shí)了。
  • 網(wǎng)速發(fā)展太慢,Web 不能像桌面游戲那樣預(yù)先下載幾十 G 的模型和材質(zhì),在 Draco 壓縮技術(shù)出現(xiàn)前,隨便一個(gè)模型文件就要十幾 M,極大限制了 WebGL 能做的事情,沒人愿意打開個(gè)頁面還要先等幾分鐘加載。
  • JavaScript 本身的性能限制,除了 JavaScript 虛擬機(jī)的消耗,在調(diào)用 WebGL API 的時(shí)候還需要經(jīng)過一層轉(zhuǎn)換,而很多瀏覽器是基于 ANGLE 支持 WebGL 的,在 ANGLE 中又會(huì)做一層檢查,然后在 Windows 下還得將 GLSL 轉(zhuǎn)成 HLSL,在 CPU 上要做的額外工作大大高于桌面程序。
  • WebGL 2.0 相當(dāng)緩慢的發(fā)展,使得 WebGL 引擎的技術(shù)也停滯不前,前面提到過 WebGL 1.0 缺少很多重要功能,比如 Draw Buffers、Occlusion queries 等現(xiàn)代渲染引擎優(yōu)化性能所依賴的技術(shù),而 WebGL 2.0 的發(fā)展又極其緩慢,盡管啟動(dòng)于 2013 年,但直到 2017 年才正式推出,要知道 OpenGL 的替代者 Vulkan 是在 2016 年推出的,所以 WebGL 2.0 還沒發(fā)布就面臨被淘汰,加上 Apple 的刻意打壓,至今 Safari 在桌面和 iOS 上都不默認(rèn)開啟 WebGL 2.0,所以 WebGL 2.0 幾乎沒人使用,用也只能用那些支持面比較廣的 WebGL 1.0 擴(kuò)展功能。
  • 經(jīng)濟(jì)方面的原因,前面提到的很多原因?qū)е铝?WebGL 只能開發(fā)小游戲,收益不高,收益不高投入就少,導(dǎo)致相關(guān)工具的缺乏,尤其是優(yōu)秀的場(chǎng)景編輯器,UE4 之所以能實(shí)時(shí)渲染逼真畫面,就是靠編輯器的烘焙和計(jì)算 Lightmass 來解決間接光照問題,編輯器開發(fā)成本極高,不如就只能等光線追蹤普及并標(biāo)準(zhǔn)化,預(yù)計(jì)至少五年。
  • Web 的下一代技術(shù)是 WebGPU,它能極大提升性能,具體提升多少呢,在 WebGPU 官方 wiki 中拿了 Babylon 的例子:

    https://www.babylonjs.com/demos/webgpu/forestwebgl?www.babylonjs.comhttps://www.babylonjs.com/Demos/WebGPU/forestWebGPU.html?www.babylonjs.com

    我測(cè)試后發(fā)現(xiàn) CPU 時(shí)間從 20ms 降到了 0.08ms,FPS 從 30 增加到了穩(wěn)定 60,提升非常明顯,是不是很期待 WebGPU 的未來?

    然而這個(gè)對(duì)比并不公平,這里的性能提升不完全是 WebGPU 帶來的,我猜是開發(fā)者在演講前發(fā)現(xiàn)效果不明顯,就先優(yōu)化了一下,下面這段代碼是 WebGPU 版本中多出的部分,如果加到 WebGL 版本中也能明顯提升性能,因?yàn)槊看窝h(huán)的時(shí)候不需要重新計(jì)算了,可以顯著減少 CPU 時(shí)間。

    // After all the meshes creation, freeze as much as we can to improve perfs. optimizeScene(scene);const optimizeScene = function(scene) {scene.freezeMaterials();scene.meshes.forEach((m) => {m.isPickable = false;m.alwaysSelectAsActiveMesh = true;m.freezeWorldMatrix();});setTimeout(() => {scene.freezeActiveMeshes();}, 1000); }

    后面有空我會(huì)單獨(dú)介紹 WebGPU,趕緊關(guān)注哈哈。

    總結(jié)

    以上是生活随笔為你收集整理的webgl 游戏_如何选择 WebGL 框架和引擎?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。