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