前端 四種渲染技術(shù)的計(jì)算機(jī)理論基礎(chǔ)
本文轉(zhuǎn)載自微信公眾號(hào)「神光的編程秘籍」,作者神說(shuō)要有光zxg 。轉(zhuǎn)載本文請(qǐng)聯(lián)系神光的編程秘籍公眾號(hào)。
前端可用的渲染技術(shù)有 html + css、canvas、svg、webgl,我們會(huì)綜合運(yùn)用這些技術(shù)來(lái)繪制頁(yè)面。有沒(méi)有想過(guò)這些技術(shù)有什么區(qū)別和聯(lián)系,它們和圖形學(xué)有什么關(guān)系呢?
本文我們就來(lái)談一下網(wǎng)頁(yè)渲染技術(shù)的計(jì)算機(jī)理論基礎(chǔ)。
渲染的理論基礎(chǔ)
人眼的視網(wǎng)膜有視覺(jué)暫留機(jī)制,也就是看到的圖像會(huì)繼續(xù)保留 0.1s 左右,圖形界面就是根據(jù)這個(gè)原理來(lái)設(shè)計(jì)的一幀一幀刷新的機(jī)制,要保證 1s 至少要渲染 10 幀,這樣人眼看到畫面才是連續(xù)的。
每幀顯示的都是圖像,它是由像素組成的,是顯示的基本單位。不同顯示器實(shí)現(xiàn)像素的原理不同。
我們要繪制的目標(biāo)是矩形、圓形、橢圓、曲線等各種圖形,繪制完之后要把它們轉(zhuǎn)成圖像。圖形的繪制有一系列的理論,比如貝塞爾曲線是畫曲線的理論。圖形轉(zhuǎn)圖像的過(guò)程叫做光柵化。這些圖形的繪制和光柵化的過(guò)程,都是圖形學(xué)研究的內(nèi)容。
圖形可能做縮放、平移、旋轉(zhuǎn)等變化,這些是通過(guò)矩陣計(jì)算來(lái)實(shí)現(xiàn)的,也是圖形學(xué)的內(nèi)容。
除了 2D 的圖形外,還要繪制 3D 的圖形。3D 的原理是把一個(gè)個(gè)三維坐標(biāo)的頂點(diǎn)連起來(lái),構(gòu)成一個(gè)一個(gè)三角形,這是造型的過(guò)程。之后再把每一個(gè)三角形的面貼上圖,叫做紋理。這樣組成的就是一個(gè) 3D 圖形,也叫 3D 模型。
3D 圖形也同樣需要經(jīng)歷光柵化變成二維的圖像,然后顯示出來(lái)。這種三維圖形的光柵化需要找一個(gè)角度去觀察,就像拍照一樣,所以一般把這個(gè)概念叫做相機(jī)。
同時(shí),為了 3D 圖形更真實(shí),還引入了光線的概念,也就是一束光照過(guò)來(lái),3D 圖形的每個(gè)面都會(huì)有什么變化,怎么反射等。不同材質(zhì)的物體反射的方式不同,比如漫反射、鏡面反射等,也就有不同的計(jì)算公式。一束光會(huì)照射到一些物體,到物體的反射,這個(gè)過(guò)程需要一系列跟蹤的計(jì)算,叫做光線追蹤技術(shù)。
我們也能感受出來(lái),3D 圖形的計(jì)算量比 2D 圖形大太多了,用 CPU 計(jì)算很可能達(dá)不到 1s 大于 10 幀,所以后面出現(xiàn)了專門用于 3D 渲染加速的硬件,叫做 GPU。它是專門用于這種并行計(jì)算的,可以批量計(jì)算一堆頂點(diǎn)、一堆三角形、一堆像素的光柵化,這個(gè)渲染流程叫做渲染管線。
現(xiàn)在的渲染管線都是可編程的,也就是可以控制頂點(diǎn)的位置,每個(gè)三角形的著色,這兩種分別叫做頂點(diǎn)著色器(shader)、片元著色器。
總之,2D 或 3D 的圖形經(jīng)過(guò)繪制和光柵化就變成了一幀幀的圖像顯示出來(lái)。
變成圖像之后其實(shí)還可以做一些圖像處理,比如灰度、反色、高斯模糊等各種濾鏡的實(shí)現(xiàn)。
所以,前端的渲染技術(shù)的理論基礎(chǔ)是計(jì)算機(jī)圖形學(xué) + 圖像處理。
不同的渲染技術(shù)的區(qū)別和聯(lián)系
具體到前前端的渲染技術(shù)來(lái)說(shuō),html+css、svg、canvas、webgl 都是用于圖形和圖像渲染的技術(shù),但是它們各有側(cè)重:
html + css
html + css 是用于圖文布局的,也就是計(jì)算文字、圖片、視頻等的顯示位置。它提供了很多計(jì)算規(guī)則,比如流式布局很適合做圖文排版,彈性布局易于做自適應(yīng)的布局等。但是它不適合做更靈活的圖形繪制,這時(shí)就要用其他幾種技術(shù)了。
canvas
canvas 是給定一塊畫布區(qū)域,在不同的位置畫圖形和圖像,它沒(méi)有布局規(guī)則,所以很靈活,常用來(lái)做可視化或者游戲的開發(fā)。但是 canvas 并不會(huì)保留繪制的圖形的信息,生成的圖像只能顯示在固定的區(qū)域,當(dāng)顯示區(qū)域變大的時(shí)候,它不能跟隨一起放縮,就會(huì)失真,如果有放縮不失真的需求就要用其他渲染技術(shù)了。
svg
svg 會(huì)在內(nèi)存中保留繪制的圖形的信息,顯示區(qū)域變化后會(huì)重新計(jì)算,是一個(gè)矢量圖,常用于 icon、字體等的繪制。
webgl
上面的 3 種技術(shù)都是用于 2D 的圖形圖像的繪制,如果想繪制 3D 的內(nèi)容,就要用 webgl 了。它提供了繪制 3D 圖形的 api,比如通過(guò)頂點(diǎn)構(gòu)成 3D 的模型,給每一個(gè)面貼圖,設(shè)置光源,然后光柵化成圖像等的 api。它常用于通過(guò) 3D 內(nèi)容增強(qiáng)網(wǎng)站的交互效果,3D 的可視化,3D 游戲等,再就是虛擬現(xiàn)實(shí)中的 3D 交互。
所以,雖然前端渲染技術(shù)的底層原理都是圖形學(xué) + 圖像處理,但上層提供的 4 種渲染技術(shù)各有側(cè)重點(diǎn)。
不過(guò),它們還是有很多相同的地方的:
- 位置、大小等的變化都是通過(guò)矩陣的計(jì)算
- 都要經(jīng)過(guò)圖形轉(zhuǎn)圖像,也就是光柵化的過(guò)程
- 都支持對(duì)圖像做進(jìn)一步處理,比如各種濾鏡
- html + css 渲染會(huì)分不同圖層分別做計(jì)算,canvas 也會(huì)根據(jù)計(jì)算量分成不同的 canvas 來(lái)做計(jì)算
因?yàn)樗麄兊讓拥膱D形學(xué)原理還是一致的。
除此以外,3D 內(nèi)容,也就是 webgl 的內(nèi)容會(huì)通過(guò) GPU 來(lái)計(jì)算,但 css 其實(shí)也可以通過(guò) GPU 計(jì)算,這叫做 css 的硬件加速,有四個(gè)屬性可以觸發(fā)硬件加速:transform、opacity、filter、will-change。(更多的 GPU 和 css 硬件加速的內(nèi)容可以看這篇文章:這一次,徹底搞懂 GPU 和 css 硬件加速)
編譯原理的應(yīng)用
除了圖形學(xué)和圖像技術(shù)外,html+css 還用到了編譯技術(shù)。因?yàn)?html、css 是一種 DSL( domin specific language,領(lǐng)域特定語(yǔ)言),也就是專門為界面描述所設(shè)計(jì)的語(yǔ)言。用 html 來(lái)表達(dá) dom 結(jié)構(gòu),用 css 來(lái)給 dom 添加樣式都只需要很少的代碼,然后運(yùn)行時(shí)解析 html 和 css 來(lái)創(chuàng)建 dom、添加樣式。
DSL 可以讓特定領(lǐng)域的邏輯更容易表達(dá),前端領(lǐng)域還有一些其他技術(shù)也用到了 DSL,比如 graphql。
總結(jié)
前端領(lǐng)域的四種渲染技術(shù):html+css、canvas、svg、webgl 各有側(cè)重點(diǎn),分別用于不同內(nèi)容的渲染:
- html+ css 用于布局
- canvas 用于靈活的圖形圖像渲染
- svg 用于矢量圖渲染
- webgl 用于 3D 圖形的渲染
但他們的理論基礎(chǔ)都是計(jì)算機(jī)圖形學(xué) + 圖像處理。(而且,html+css 為了方便邏輯的表達(dá),還設(shè)計(jì)了 DSL,這用到了編譯技術(shù))
這四種渲染技術(shù)看似差別很大,但在理論基礎(chǔ)層面,很多東西都是一樣的。這也是為什么我們要去學(xué)計(jì)算機(jī)基礎(chǔ),因?yàn)樗梢宰屛覀儗?duì)技術(shù)有一個(gè)更深入的更本質(zhì)的理解。