WebGL - 缩放:初学者指南

你好,有志于学习 WebGL 的开发者们!今天,我们将一起深入 WebGL 中缩放的世界。如果你是编程新手,不用担心——我会用我在课堂上多年的细心和耐心引导你完成每一个步骤。让我们一起开始这段激动人心的旅程!

WebGL - Scaling

WebGL 中的缩放是什么?

在我们跳入代码之前,让我们先了解在计算机图形学中缩放的意义。想象你有一个最喜欢的玩具人偶。缩放就像是拥有一根魔杖,可以让人偶变大或变小,同时保持其形状不变。在 WebGL 中,我们可以对我们的 3D 对象施展这样的魔法!

缩放的重要性

缩放在创建真实和动态的 3D 场景中至关重要。它允许我们:

  1. 调整对象大小以适应我们的场景
  2. 创建对象增长或缩小的动画
  3. 在复杂模型中保持正确的比例

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