1
1
# WebGL
2
2
3
- ``` html
4
- <canvas width =" 500" height =" 500" ></canvas >
5
- <script >
6
- const canvas = document .querySelector (" canvas" );
7
- const gl = canvas .getContext (" webgl" );
8
-
9
- // 颠倒图片
10
- gl .pixelStorei (gl .UNPACK_FLIP_Y_WEBGL , true );
11
-
12
- const vsSource = `
13
- precision mediump float;
14
-
15
- attribute vec2 aPosition;
16
- attribute vec2 aUV;
17
-
18
- varying vec2 vUV;
19
- varying vec2 vPos;
20
-
21
- void main() {
22
- gl_Position = vec4(aPosition, 0.0, 1.0);
23
- vUV = aUV;
24
- vPos = aPosition;
25
- }
26
-
27
- ` ;
28
- const fsSource = `
29
- precision mediump float;
30
-
31
- uniform sampler2D uTexture;
32
- uniform float uVar;
33
-
34
- varying vec2 vUV;
35
- varying vec2 vPos;
36
-
37
- void main() {
38
- vec4 sample_color = texture2D(uTexture, vUV);
39
-
40
- if (vPos.x > uVar) {
41
- gl_FragColor = vec4(sample_color.xyz, 0.8);
42
- } else {
43
- gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
44
- }
45
- }
46
- ` ;
47
-
48
- const vs = gl .createShader (gl .VERTEX_SHADER );
49
- gl .shaderSource (vs, vsSource);
50
- gl .compileShader (vs);
51
-
52
- const fs = gl .createShader (gl .FRAGMENT_SHADER );
53
- gl .shaderSource (fs, fsSource);
54
- gl .compileShader (fs);
55
-
56
- const program = gl .createProgram ();
57
- gl .attachShader (program, vs);
58
- gl .attachShader (program, fs);
59
- gl .linkProgram (program);
60
- gl .useProgram (program);
61
-
62
- const buffer = gl .createBuffer ();
63
- gl .bindBuffer (gl .ARRAY_BUFFER , buffer);
64
- gl .bufferData (
65
- gl .ARRAY_BUFFER ,
66
- new Float32Array ([
67
- 1.0 , 1.0 , 1 , 1 , - 1.0 , 1.0 , 0 , 1 , - 1.0 , - 1.0 , 0 , 0 , - 1.0 , - 1.0 , 0 , 0 ,
68
- 1.0 , - 1.0 , 1 , 0 , 1.0 , 1.0 , 1 , 1 ,
69
- ]),
70
- gl .STATIC_DRAW
71
- );
72
-
73
- const location1 = gl .getAttribLocation (program, " aPosition" );
74
- gl .vertexAttribPointer (location1, 2 , gl .FLOAT , false , 16 , 0 );
75
- gl .enableVertexAttribArray (location1);
76
- const location2 = gl .getAttribLocation (program, " aUV" );
77
- gl .vertexAttribPointer (location2, 2 , gl .FLOAT , false , 16 , 8 );
78
- gl .enableVertexAttribArray (location2);
79
-
80
- const image = new Image ();
81
- image .src = " ./touxiang.JPG" ;
82
- image .onload = function () {
83
- const texture = gl .createTexture ();
84
- gl .bindTexture (gl .TEXTURE_2D , texture);
85
- gl .texImage2D (
86
- gl .TEXTURE_2D ,
87
- 0 ,
88
- gl .RGBA ,
89
- gl .RGBA ,
90
- gl .UNSIGNED_BYTE ,
91
- image
92
- );
93
-
94
- // 宽高非2的幂时会返回纯黑图片
95
- gl .texParameteri (gl .TEXTURE_2D , gl .TEXTURE_MIN_FILTER , gl .LINEAR );
96
- gl .texParameteri (gl .TEXTURE_2D , gl .TEXTURE_WRAP_S , gl .CLAMP_TO_EDGE );
97
- gl .texParameteri (gl .TEXTURE_2D , gl .TEXTURE_WRAP_T , gl .CLAMP_TO_EDGE );
98
-
99
- const uniform1 = gl .getUniformLocation (program, " uTexture" );
100
- gl .uniform1i (uniform1, 0 ); // texture0
101
-
102
- let value = 0.0 ;
103
- function draw () {
104
- const uniform2 = gl .getUniformLocation (program, " uVar" );
105
- if (value <= 1.0 ) {
106
- gl .uniform1f (uniform2, (value += 0.01 ));
107
- } else {
108
- value = - 1.0 ;
109
- gl .uniform1f (uniform2, value);
110
- }
111
-
112
- gl .viewport (0 , 0 , gl .canvas .width , gl .canvas .height );
113
- gl .clearColor (0 , 0 , 0 , 0 );
114
- gl .clear (gl .COLOR_BUFFER_BIT );
115
- gl .drawArrays (gl .TRIANGLES , 0 , 6 );
116
-
117
- requestAnimationFrame (draw);
118
- }
119
- draw ();
120
- };
121
- </script >
3
+ 浏览器所提供的WebGL给予了我们图形绘制的能力,WebGL本质上基于OpenGL ES2.0,而后者实际上是OpenGL的一个精简子集,缺少了一部分的能力(如几何着色器等)。
4
+
5
+ 近年来WebGL2的实现也逐渐稳定,它基于OpenGL ES3.0。
6
+
7
+ ``` js
8
+ const canvas = document .querySelector (' canvas' );
9
+ const webgl = canvas .getContext (' webgl' );
10
+ const webgl2 = canvas .getContext (' webgl2' );
122
11
```
123
12
13
+
14
+
15
+ ## 渲染管线
16
+
17
+ 1 . CPU准备工作。着色器的编译、链接;顶点数据、顶点颜色、顶点UV坐标、顶点法线等数据的写入;纹理数据的写入等。
18
+
19
+ 2 . 顶点着色器。逐顶点执行,我们的顶点数据通常由3D建模软件导出,我们会先通过** 模型矩阵Model** 将模型空间转变为世界空间,再通过** 视图矩阵View** 将世界空间转变为观察空间,再通过** 投影矩阵Projection(透视投影或正交投影)** 转变为** 齐次裁剪空间(Clip Space)** 。以上的变换统称MVP变化。裁剪空间中坐标的XYZ三维都位于[ -1,1] 之间,W分量通常为1。后续(在第三步裁剪之后)GPU内部会通过** 透视除法** 将四维顶点转化成三维的** 标准化设备坐标(NDC)** 。
20
+
21
+ <img src =" https://img-blog.csdn.net/20171229111837073?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmllemhpaHVh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast " />
22
+
23
+ 3 . 图元装配、裁剪。根据指令将顶点组装成图元(线、三角形),并把齐次裁剪空间外的内容剔除。
24
+
25
+ 4 . 光栅化。
26
+
27
+ ![ img] ( https://img-blog.csdnimg.cn/b26e74a5ee5b4f8781cbe684ac25ebaa.png )
28
+
29
+ 5 . 片元着色器。GPU会将通过** 视口变化** 将NDC坐标转化成** 屏幕空间(Screen Space)** 坐标,并传入给片元着色器的` gl_FragCoord ` 。片元着色器逐屏幕像素执行,通常在此时实现滤镜(如通过LUT)或后处理(各种特效、模糊、边缘检测),最终将数据写入帧缓冲(显存)中。
30
+
31
+ 6 . 深度测试
32
+
33
+
34
+
35
+
36
+
124
37
## OpenGL Shading Language(GLSL)
125
38
126
39
### Vertex Shader
@@ -134,6 +47,8 @@ void main() {
134
47
}
135
48
```
136
49
50
+ <img src =" https://images2018.cnblogs.com/blog/669331/201803/669331-20180302113903143-870412752.png " alt =" vs " />
51
+
137
52
138
53
139
54
### Fragment Shader
@@ -147,7 +62,7 @@ void main() {
147
62
}
148
63
```
149
64
150
-
65
+ < img src = " https://img-blog.csdn.net/20140917135608231 " alt = " fs " />
151
66
152
67
### atrribute
153
68
@@ -173,6 +88,18 @@ void main() {
173
88
174
89
### 内置函数
175
90
91
+ - ` abs(x) ` ,绝对值。
92
+ - ` floor(x) ` ,获取整数部分。
93
+ - ` fract(x) ` ,获取小数部分。
94
+ - ` ceil(x) ` ,向上取整。
95
+ - ` max(x, y) ` ,` min(x, y) ` ,` clamp(x, min, max) `
96
+ - ` mix(a, b, t) ` ,混合(线性组合),` mix(a, b, t) ` 表示` a * (1 - t) + b * (t) ` 。
97
+ - ` step(edge, x) ` ,当` x ` 小于` edge ` 时返回0,否则返回1。
98
+ - ` smoothstep(edge0, edge1, x) ` ,当` x ` 小于` edge0 ` 时返回0,当` x ` 大于` edge0 ` 时返回1,否则返回的值为` edge0 ` 到` edge1 ` 的插值。
99
+ - ` length(vec) ` ,返回向量的长度。
100
+
101
+
102
+
176
103
177
104
178
105
### 纹理(Texture)、UV坐标与采样
@@ -238,14 +165,6 @@ float random (vec2 st) {
238
165
239
166
240
167
241
- ## WebGL渲染管线
242
-
243
- 1 . CPU提供数据(顶点、颜色、UV、法线、纹理等)
244
- 2 . 顶点着色器(MVP矩阵变换等)
245
- 3 . 图元装配与裁剪
246
- 4 . 光栅化
247
- 5 . 片元着色器
248
-
249
168
250
169
251
170
## 线性代数
@@ -311,9 +230,9 @@ float random (vec2 st) {
311
230
312
231
313
232
314
- ## MVP和裁剪空间
315
233
316
- > TODO
234
+
235
+
317
236
318
237
319
238
0 commit comments