Skip to content

Commit ade53e8

Browse files
committed
feat: webgl
1 parent ef95382 commit ade53e8

File tree

3 files changed

+50
-131
lines changed

3 files changed

+50
-131
lines changed

docs/canvas.md

+49-130
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,39 @@
11
# WebGL
22

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');
12211
```
12312

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+
12437
## OpenGL Shading Language(GLSL)
12538

12639
### Vertex Shader
@@ -134,6 +47,8 @@ void main() {
13447
}
13548
```
13649

50+
<img src="https://images2018.cnblogs.com/blog/669331/201803/669331-20180302113903143-870412752.png" alt="vs" />
51+
13752

13853

13954
### Fragment Shader
@@ -147,7 +62,7 @@ void main() {
14762
}
14863
```
14964

150-
65+
<img src="https://img-blog.csdn.net/20140917135608231" alt="fs" />
15166

15267
### atrribute
15368

@@ -173,6 +88,18 @@ void main() {
17388

17489
### 内置函数
17590

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+
176103

177104

178105
### 纹理(Texture)、UV坐标与采样
@@ -238,14 +165,6 @@ float random (vec2 st) {
238165

239166

240167

241-
## WebGL渲染管线
242-
243-
1. CPU提供数据(顶点、颜色、UV、法线、纹理等)
244-
2. 顶点着色器(MVP矩阵变换等)
245-
3. 图元装配与裁剪
246-
4. 光栅化
247-
5. 片元着色器
248-
249168

250169

251170
## 线性代数
@@ -311,9 +230,9 @@ float random (vec2 st) {
311230

312231

313232

314-
## MVP和裁剪空间
315233

316-
> TODO
234+
235+
317236

318237

319238

src/pages/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Link from "@docusaurus/Link";
55
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
66
import styles from "./index.module.css";
77
import HomepageFeatures from "@site/src/components/HomepageFeatures";
8-
import logo from "@site/static/img/头像.jpg";
8+
import logo from "@site/static/img/banana.jpg";
99
import noise from "@site/static/img/noise.png";
1010

1111
console.log(logo);
File renamed without changes.

0 commit comments

Comments
 (0)