內卷年代,是該學學WebGL了

語言: CN / TW / HK
ead>

theme: smartblue

前言

大部分公司的都會有可視化的需求,但是用echarts,antv等圖表庫,雖然能快速產出成果,但是還是要知道他們底層其實用canvas或svg來做渲染,canvas瀏覽器原生支持,h5天然支持的接口,而svg相比矢量化,但是對大體量的點的處理沒有canvas好,但是可以操作dom等優勢。canvas和svg我們一般只能做2d操作,當canvas.getContext('webgl')我們就能獲取webgl的3d上下文,通過glsl語言操作gpu然後渲染了。理解webgl,可以明白h5的很多三維的api底層其實都是webgl實現,包括對canvas和svg也會有新的認知。

canvas和webgl的區別

canvas和webgl都可以做二維三維圖形的繪製。底層都會有對應的接口獲取。cancvas一般用於二維ctx.getContext("2d"),三維一般可以通過canvas.getContext('webgl')

窺探WebGL

理解建模

如果你有建模軟件基礎的話,相信3dmax、maya、su等軟件你一定不會陌生,本質其實就是點、線、面來組成千變萬化的事物。打個比方球體就是無數個點連成線然後每三根線形成面,當然有常見的四邊形,其實也是兩個三邊形組成,為什麼不用四邊形,因為三邊形更穩定、重心可計算、數據更容易測算。

所以核心也就是點、線、三角面

瞭解WebGL

WebGL可以簡單理解為是openGL的拓展,讓web端通過js可以有強大的圖形處理能力。當然為了與顯卡做交互你必須得會glsl語言。

GLSL

glsl着色器語言最重要的就是頂點着色器和片元着色器。簡單理解為一個定位置一個添顏色。

簡單繪製一個點

webgl會有大量的重複性前置工作,也就是創建着色器 -> 傳入着色器源碼 -> 編譯着色器 -> 創建着色器程序 -> 綁定、連接、啟用着色器 -> 可以繪製了!

一般而言我們是不會重複寫這個東西,封裝好了直接調用就行。

```js function initShader (gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE) { const vertexShader = gl.createShader(gl.VERTEX_SHADER);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);

gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE);
gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE);

//編譯着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);

//創建程序對象
const program = gl.createProgram();

gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);

gl.linkProgram(program);
gl.useProgram(program);

return program;

} ```

```js

Document

不支持canvas

``` 繪製效果如下:

image.png

相信看了上面有段代碼會有疑惑

image.png

gl_position代表座標,vec4就一個存放個4個float的浮點數的容量,定義座標, 分別對應x、y、z、w,也就是三維座標,但是w就等於比例縮放xyz而已,一般在開發中,我們的瀏覽器的座標要跟這個做個轉換對應上,gl_POintSize是點的大小,注意是浮點數

image.png

gl_flagColor渲染的像素是紅色,是因為這類似於比例尺的關係需要做個轉換, (R值/255,G值/255,B值/255,A值/1) -》(1.0, 0.0, 0.0, 1.0)

繪製動態點

```html

Document

不支持canvas

```

vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0; 注意這裏的座標轉換,從canvas轉為ndc座標,其實就是看範圍就行,[0, 1] -> [0, 2] -> [-1, 1]。上面總體的流程總結下就是,定義着色器,定義glsl着色器源碼 -> 通過api獲取canvas的信息轉換座標系 -> 監聽點擊事件傳遞變量到glsl中 -》通過pointer緩存 -> drawArrays繪製。但是這種方法,很明顯有大量的重複渲染,每次遍歷都要把之前渲染的重複執行。

大致效果

動畫.gif

總結

通過簡單的webgl入門,已經有了初步的認知,大致的流程為:着色器初始化 -> 着色器程序對象 -> 控制變量 -> 繪製,為了更好的性能,後面會使用緩衝區來解決重複渲染的問題,包括我們的頂點不會一個一個設置,一般是會涉及到矩陣的轉換,如平移、縮放、旋轉、複合矩陣。