Skip to content

Commit d8e277c

Browse files
committed
check_first_article_and_amend_lastest_article
2 parents f905e3f + 38ba2d7 commit d8e277c

30 files changed

+20676
-190
lines changed
+175-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,176 @@
1-
# WebGL 2D Translation
1+
# WebGL 2D 平移(Translation
22

3+
在开始进入 3D 之前我们先在 2D 停留一段时间。请各位耐心听我说,这篇文章或许对一些同学来说极其浅显,但我还是会用一些篇幅由点到面地加以叙述。
4+
5+
这篇文章是由 <a href="/fundamentals/webgl-fundamentals.html" target="_blank">WebGL Fundamentals</a> 开始的一系列延续的内容。如果你还没有阅读过这一部分,我建议你至少先阅读第一部分,然后再回来这里。
6+
7+
平移(Translation)的本质是一些复杂的数学计算,平移的基本意义是“去移动”一些东西。我认为将一个句子从英语翻译(Translation)成日语也符合定义,但在这个情况下,我们只讨论移动(Translation)几何体。使用我们之前在<a href="/fundamentals/webgl-fundamentals.html" target="_blank">第一篇教程中</a>给出的示例代码你可以通过改变传递给 `setRectangle` 的参数很快地完成矩形的平移。这里给出一个基于<a href="/fundamentals/webgl-fundamentals.html" target="_blank">之前例子</a>的代码示例。
8+
9+
<!-- more -->
10+
```
11+
// 首先让我们使用一些变量来存储矩形的宽度、高度和平移量
12+
var translation = [0, 0];
13+
var width = 100;
14+
var height = 30;
15+
16+
// 然后让我们定义一个函数来重绘所有内容。
17+
// 在我们更新矩形的平移设置后我们可以调用这个函数进行重绘操作。
18+
19+
// 绘制场景。
20+
function drawScene() {
21+
// 清除 canvas 的内容。
22+
gl.clear(gl.COLOR_BUFFER_BIT);
23+
24+
// 设置一个矩形
25+
setRectangle(gl, translation[0], translation[1], width, height);
26+
27+
// 绘制矩形。
28+
gl.drawArrays(gl.TRIANGLES, 0, 6);
29+
}
30+
```
31+
32+
在下面的例子中,我将一对滑动器(slider)与平移的变量绑定在一起,它们会更新 `translation[0]``translation[1]` 并且每次它们发生改变时都会调用 `drawScene` 函数。通过拖动滑动器去平移矩形。
33+
34+
<iframe src="http://webglfundamentals.org/webgl/webgl-2d-rectangle-translate.html" frameborder="0" style="border: 1px solid; width: 100%; height: 200px;"></iframe>
35+
36+
<a href="http://webglfundamentals.org/webgl/webgl-2d-rectangle-translate.html" target="_blank">点击这里在新窗口查看例子</a>
37+
38+
到目前为止,一切都好。但试想一下,假如现在我们想要对更加复杂的形状做同样的事情。
39+
40+
假设我们想要去绘制一个如下图所示的由 6 个三角形组成的字母“F”。
41+
42+
<img src="http://webglfundamentals.org/webgl/resources/polygon-f.svg" width="200" height="270">
43+
44+
那么,接下来我们得将 `setRectangle` 函数改成像下面的代码那样。
45+
46+
```
47+
// 用表示字母“F”的顶点数组填充 buffer
48+
function setGeometry(gl, x, y) {
49+
var width = 100;
50+
var height = 150;
51+
var thickness = 30;
52+
gl.bufferData(
53+
gl.ARRAY_BUFFER,
54+
new Float32Array([
55+
// 左边的一列
56+
x, y,
57+
x + thickness, y,
58+
x, y + height,
59+
x, y + height,
60+
x + thickness, y,
61+
x + thickness, y + height,
62+
63+
// 上边的一横
64+
x + thickness, y,
65+
x + width, y,
66+
x + thickness, y + thickness,
67+
x + thickness, y + thickness,
68+
x + width, y,
69+
x + width, y + thickness,
70+
71+
// 中间的一横
72+
x + thickness, y + thickness * 2,
73+
x + width * 2 / 3, y + thickness * 2,
74+
x + thickness, y + thickness * 3,
75+
x + thickness, y + thickness * 3,
76+
x + width * 2 / 3, y + thickness * 2,
77+
x + width * 2 / 3, y + thickness * 3]),
78+
gl.STATIC_DRAW);
79+
}
80+
```
81+
82+
你可以满怀希望的看到这段代码并不能很好的进行拓展。如果我们想要绘制一些有着成百上千条线段的非常复杂的几何体,我们必须写上一些很复杂的代码。除此之外,每一次绘制 JavaScript 都必须更新所有的顶点数据。
83+
84+
这里有一个相对简单的方法。只需要上传几何体然后在着色器中进行平移。
85+
86+
下面是新的着色器代码
87+
88+
```
89+
<script id="2d-vertex-shader" type="x-shader/x-vertex">
90+
attribute vec2 a_position;
91+
92+
uniform vec2 u_resolution;
93+
uniform vec2 u_translation;
94+
95+
void main() {
96+
// 增加平移变量
97+
vec2 position = a_position + u_translation;
98+
99+
// 将矩阵大小从像素单位转换到区间 0.0 到 1.0 之间
100+
vec2 zeroToOne = position / u_resolution;
101+
...
102+
}
103+
</script>
104+
```
105+
106+
我们将稍微重构一下代码。使得我们只需要设置一次几何体。
107+
108+
```
109+
// Fill the buffer with the values that define a letter 'F'.
110+
function setGeometry(gl) {
111+
gl.bufferData(
112+
gl.ARRAY_BUFFER,
113+
new Float32Array([
114+
// left column
115+
0, 0,
116+
30, 0,
117+
0, 150,
118+
0, 150,
119+
30, 0,
120+
30, 150,
121+
122+
// top rung
123+
30, 0,
124+
100, 0,
125+
30, 30,
126+
30, 30,
127+
100, 0,
128+
100, 30,
129+
130+
// middle rung
131+
30, 60,
132+
67, 60,
133+
30, 90,
134+
30, 90,
135+
67, 60,
136+
67, 90]),
137+
gl.STATIC_DRAW);
138+
}
139+
```
140+
141+
然后我们只需要在我们绘制之前更新 `u_translation` 变量就能得到我们想要的平移效果。
142+
143+
```
144+
...
145+
var translationLocation = gl.getUniformLocation(
146+
program, "u_translation");
147+
...
148+
// Set Geometry.
149+
setGeometry(gl);
150+
..
151+
// Draw scene.
152+
function drawScene() {
153+
// Clear the canvas.
154+
gl.clear(gl.COLOR_BUFFER_BIT);
155+
156+
// Set the translation.
157+
gl.uniform2fv(translationLocation, translation);
158+
159+
// Draw the rectangle.
160+
gl.drawArrays(gl.TRIANGLES, 0, 18);
161+
}
162+
```
163+
164+
注意 `setGeometry` 函数只被调用一次。它不再在 `drawScene` 里面。
165+
166+
示例如下。再一次,通过拖动滑动器对几何形体进行平移。
167+
168+
<iframe src="http://webglfundamentals.org/webgl/webgl-2d-geometry-translate-better.html" frameborder="0" style="border: 1px solid; width: 100%; height: 200px;"></iframe>
169+
170+
<a href="http://webglfundamentals.org/webgl/webgl-2d-geometry-translate-better.html" target="_blank">点击这里在新窗口查看例子</a>
171+
172+
现在当我们进行绘制的时候,WebGL 几乎帮我们完成所有的事情。我们所需要的事情只有设置平移变量然后请求绘制。即使我们的几何体有数以万计的顶点,主要的代码也会照常运行。
173+
174+
如果你想要,你可以比较一下<a href="http://webglfundamentals.org/webgl/webgl-2d-geometry-translate.html" target="_blank">上面提到的比较复杂的更新所有顶点的 JavaScript 版本</a>和现在的版本。
175+
176+
我希望这个例子不会太平淡无奇。在 <a href="webgl-2d-rotation.html">下一篇文章中我们将开始进入旋转(Rotation)</a>。

0 commit comments

Comments
 (0)