WebGL - 缩放:初学者指南
你好,有志于学习 WebGL 的开发者们!今天,我们将一起深入 WebGL 中缩放的世界。如果你是编程新手,不用担心——我会用我在课堂上多年的细心和耐心引导你完成每一个步骤。让我们一起开始这段激动人心的旅程!
WebGL 中的缩放是什么?
在我们跳入代码之前,让我们先了解在计算机图形学中缩放的意义。想象你有一个最喜欢的玩具人偶。缩放就像是拥有一根魔杖,可以让人偶变大或变小,同时保持其形状不变。在 WebGL 中,我们可以对我们的 3D 对象施展这样的魔法!
缩放的重要性
缩放在创建真实和动态的 3D 场景中至关重要。它允许我们:
- 调整对象大小以适应我们的场景
- 创建对象增长或缩小的动画
- 在复杂模型中保持正确的比例
WebGL 中缩放对象的必要步骤
要在 WebGL 中缩放对象,我们需要遵循一系列步骤。让我们分解一下:
步骤 | 描述 |
---|---|
1. 创建缩放矩阵 | 我们从创建一个特殊的矩阵开始,告诉 WebGL 如何缩放我们的对象 |
2. 与模型矩阵相乘 | 我们将缩放矩阵与对象的现有模型矩阵结合起来 |
3. 传递给着色器 | 我们将这个新矩阵发送到我们的着色器程序 |
4. 在顶点着色器中应用 | 着色器使用这个矩阵来调整每个顶点的位置 |
别担心这些步骤听起来复杂——我们将通过我们的示例详细探索每一个!
示例 - 缩放一个三角形
让我们通过缩放一个简单的三角形来将我们的学习付诸实践。我们将从一个基本的 WebGL 设置开始,然后添加缩放功能。
步骤 1:设置 WebGL 上下文
首先,我们需要设置我们的 WebGL 上下文。以下是如何操作:
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
console.error('WebGL 不支持');
return;
}
这段代码找到我们的画布元素并创建一个 WebGL 上下文。这就像在开始我们的艺术作品之前准备画布和画笔!
步骤 2:定义顶点着色器
现在,让我们创建我们的顶点着色器。这是缩放魔法发生的地方:
const vertexShaderSource = `
attribute vec2 a_position;
uniform mat3 u_matrix;
void main() {
vec3 position = u_matrix * vec3(a_position, 1);
gl_Position = vec4(position.xy, 0, 1);
}
`;
这个着色器取每个顶点位置并乘以我们的矩阵(这将包括我们的缩放)。就像给三角形的每个点提供移动指令。
步骤 3:定义片段着色器
片段着色器决定了我们的三角形颜色:
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0, 1); // 红色
}
`;
我们在这里保持简单——我们的三角形将是红色的。你可以自由地尝试不同的颜色!
步骤 4:创建并链接着色器程序
现在,让我们编译并链接我们的着色器:
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
这个过程就像组装一台机器——每个着色器都是一个组件,我们将它们组合起来创建我们的程序。
步骤 5:创建三角形数据
让我们定义我们的三角形:
const positions = new Float32Array([
0, 0.5,
-0.5, -0.5,
0.5, -0.5
]);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
这些坐标定义了一个简单的三角形。把它想象成在图表上标点来绘制我们的形状。
步骤 6:实现缩放
现在来到激动人心的部分——缩放我们的三角形!我们将使用一个函数来创建我们的缩放矩阵:
function createScaleMatrix(scaleX, scaleY) {
return new Float32Array([
scaleX, 0, 0,
0, scaleY, 0,
0, 0, 1
]);
}
// 示例:将三角形缩放到原来的两倍大小
const scaleMatrix = createScaleMatrix(2, 2);
这个矩阵就像一组指示 WebGL 如何拉伸或缩小我们的三角形在各个方向上的指令。
步骤 7:渲染缩放后的三角形
最后,让我们把所有东西放在一起并渲染我们的缩放三角形:
gl.useProgram(program);
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
const matrixUniformLocation = gl.getUniformLocation(program, 'u_matrix');
gl.uniformMatrix3fv(matrixUniformLocation, false, scaleMatrix);
gl.drawArrays(gl.TRIANGLES, 0, 3);
这段代码应用我们的缩放矩阵并绘制三角形。就像在所有的准备工作之后终于展示我们的艺术品!
结论
恭喜!你刚刚缩放了你的第一个 WebGL 三角形。记住,缩放只是你可以在 WebGL 中应用的许多变换中的一种。在你继续你的旅程时,你将发现如何将缩放与旋转、平移等结合起来,创建复杂和动态的 3D 场景。
熟能生巧,所以不要害怕尝试不同的缩放值和形状。谁知道呢?下一个大型视频游戏或 3D 网页应用可能就是从你缩放的三角形开始的!
快乐编码,愿你的 WebGL 对象总能达到新的高度!
Credits: Image by storyset