WebGL - 翻译:在3D空间中移动对象
你好,有抱负的WebGL开发者们!今天,我们将踏上一段激动人心的旅程,进入3D图形的世界。我们将探讨WebGL中的平移概念,这实际上是一种花哨的说法,意思是“四处移动东西”。在本教程结束时,你将能够使对象在你的屏幕上像数字芭蕾一样跳舞!那么,让我们开始吧!
WebGL中的平移是什么?
在我们开始像棋子一样移动三角形之前,让我们先了解在计算机图形的背景下平移实际上意味着什么。
平移的基础知识
平移是在2D或3D空间中将对象从一个位置移动到另一个位置的过程。这就像从你的桌子上拿起一个杯子,然后把它放在架子上。杯子(我们的对象)从原来的位置移动到了一个新的位置。
在WebGL中,我们使用数学来实现这种移动。别担心如果你不是数学天才——WebGL为我们承担了大部分繁重的工作!
为什么平移很重要?
想象一下,一个角色无法移动的视频游戏,或者是一个对象固定在原位的3D建模软件。是不是很无聊?平移允许我们创建动态的、交互式的图形,这些图形可以响应用户输入或遵循预定的动画。
平移一个三角形的步骤
现在我们了解了什么是平移,让我们分解在WebGL中移动一个简单三角形的流程。我们将一步一步地进行,这样你就可以轻松地跟进。
步骤1:定义你的三角形
首先,我们需要创建我们的三角形。在WebGL中,我们使用顶点(角落点)来定义形状。以下是如何定义一个简单三角形的方法:
const vertices = [
0.0, 0.5, // 顶点
-0.5, -0.5, // 左下角顶点
0.5, -0.5 // 右下角顶点
];
这创建了一个顶点在(0, 0.5)处,底角在(-0.5, -0.5)和(0.5, -0.5)处的三角形。
步骤2:创建一个平移矩阵
要移动我们的三角形,我们需要创建一个平移矩阵。这个矩阵告诉WebGL如何在每个轴(x、y和z)上移动我们的对象。以下是如何创建一个平移矩阵的方法:
const translationMatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1
];
其中tx
和ty
是我们想要在x和y轴上移动的量。
步骤3:在顶点着色器中应用平移
现在到了激动人心的部分!我们需要修改我们的顶点着色器来应用平移。以下是一个包含平移的简单顶点着色器:
attribute vec2 a_position;
uniform mat4 u_translation;
void main() {
gl_Position = u_translation * vec4(a_position, 0, 1);
}
这个着色器取每个顶点位置,将其转换为4D向量(矩阵乘法所需),然后乘以我们的平移矩阵。
步骤4:更新平移值
为了使我们的三角形移动,我们需要随时间更新平移值。我们可以在JavaScript代码中做到这一点:
function updateAndDraw() {
tx += 0.01; // 向右移动
ty += 0.005; // 向上移动
// 更新平移矩阵
gl.uniformMatrix4fv(translationLocation, false, translationMatrix);
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);
requestAnimationFrame(updateAndDraw);
}
这个函数更新我们的平移值,将新矩阵发送到GPU,然后重新绘制我们的三角形。requestAnimationFrame
调用确保这一点能够平滑地进行,逐帧进行。
示例 - 平移一个三角形
让我们把所有内容放在一起,用一个完整的示例。这段代码将创建一个沿对角线穿过屏幕的移动三角形:
// 顶点着色器
const vertexShaderSource = `
attribute vec2 a_position;
uniform mat4 u_translation;
void main() {
gl_Position = u_translation * vec4(a_position, 0, 1);
}
`;
// 片元着色器
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0, 1); // 红色
}
`;
// 初始化WebGL
const canvas = document.getElementById('glcanvas');
const gl = canvas.getContext('webgl');
// 创建和编译着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
// 创建程序
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// 创建缓冲区并加载顶点数据
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// 设置属性
const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
// 设置统一变量
const translationLocation = gl.getUniformLocation(program, "u_translation");
// 平移变量
let tx = 0;
let ty = 0;
function updateAndDraw() {
// 清除画布
gl.clear(gl.COLOR_BUFFER_BIT);
// 更新平移
tx += 0.01;
ty += 0.005;
// 创建平移矩阵
const translationMatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1
];
// 将矩阵发送到着色器
gl.uniformMatrix4fv(translationLocation, false, translationMatrix);
// 绘制
gl.drawArrays(gl.TRIANGLES, 0, 3);
// 请求下一帧
requestAnimationFrame(updateAndDraw);
}
// 开始动画
updateAndDraw();
这段代码创建了一个沿对角线移动的红色三角形。让我们分解一下发生了什么:
- 我们定义了我们的着色器,其中包含平移矩阵。
- 我们设置WebGL,创建我们的程序,并加载我们的三角形顶点。
- 我们创建了平移变量(tx和ty)。
- 在我们的
updateAndDraw
函数中,我们:
- 清除画布
- 更新我们的平移值
- 创建一个新的平移矩阵
- 将这个矩阵发送到GPU
- 绘制我们的三角形
- 请求下一帧动画
就这样!你已经用WebGL创建了一个移动的三角形。恭喜你!
结论
WebGL中的平移一开始可能看起来很复杂,但它实际上只是以智能的方式移动对象。在这里,我们已经介绍了基础知识,但你还可以用平移做很多事情——结合旋转和缩放,创建复杂的动画,甚至构建交互式的3D环境。
记住,每一个旅程都是从第一步开始的——或者在我们的例子中,是第一个三角形的移动。继续练习,继续尝试,不久之后,你将能够创造出以你从未想象过的方式移动和交互的惊人的3D图形。
快乐编码,愿你的三角形总能找到回家的路!
Credits: Image by storyset