WebGL - Перевод: Передвижение объектов в 3D пространстве

Здравствуйте,future WebGL разработчики! Сегодня мы отправляемся в увлекательное путешествие в мир 3D графики. Мы будем исследовать концепцию переноса в WebGL, что по сути является изысканным способом сказать "перемещать вещи". К концу этого руководства вы сможете заставить объекты танцевать по вашему экрану, как в цифровом балете! Так что погружаемся в это!

WebGL - Translation

Что такое перенос в WebGL?

Прежде чем мы начнем передвигать треугольники, как фигуры в шахматах, давайте поймем, что на самом деле означает перенос в контексте компьютерной графики.

Основы переноса

Перенос - это процесс передвижения объекта из одной позиции в другую в 2D или 3D пространстве. Это как поднять кружку с вашего стола и поставить ее на полку. Кружка (наш объект) переместилась из своего исходного положения в новое.

В WebGL мы используем математику для достижения этого движения. Не волнуйтесь, если вы не expert по математике - WebGL делает за нас大部分 тяжелой работы!

Why is Translation Important?

Представьте себе видеоигру, где персонажи не могут двигаться, или программное обеспечение для 3D моделирования, где объекты застряли на месте. Pretty boring, right? Перенос позволяет нам создавать динамичные, интерактивные графики, которые реагируют на ввод пользователя или следуют заданным анимациям.

Шаги для переноса треугольника

Теперь, когда мы понимаем, что такое перенос, давайте разберем процесс передвижения простого треугольника в 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: Создайте матрицу переноса

Чтобы переместить наш треугольник, нам нужно создать матрицу переноса. Эта матрица tells 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: Примените перенос в вершиныном шейдере

Теперь comes the exciting part! Нам нужно изменить наш вершиныной шейдер, чтобы применить перенос. Вот простой вершиныной шейдер, который включает перенос:

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;  // Move right
ty += 0.005; // Move up

// Update the translation matrix
gl.uniformMatrix4fv(translationLocation, false, translationMatrix);

// Draw the triangle
gl.drawArrays(gl.TRIANGLES, 0, 3);

requestAnimationFrame(updateAndDraw);
}

Эта функция обновляет наши значения переноса, отправляет новую матрицу на GPU и затем перерисовывает наш треугольник. Вызов requestAnimationFrame обеспечивает это происходит плавно, кадр за кадром.

Пример – Перенос треугольника

Давайте соберем все вместе с полным примером. Этот код создаст треугольник, который движется по диагонали экрана:

// Vertex shader
const vertexShaderSource = `
attribute vec2 a_position;
uniform mat4 u_translation;

void main() {
gl_Position = u_translation * vec4(a_position, 0, 1);
}
`;

// Fragment shader
const fragmentShaderSource = `
precision mediump float;

void main() {
gl_FragColor = vec4(1, 0, 0, 1);  // Red color
}
`;

// Initialize WebGL
const canvas = document.getElementById('glcanvas');
const gl = canvas.getContext('webgl');

// Create and compile shaders
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);

// Create program
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);

// Create buffer and load vertex data
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);

// Set up attribute
const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

// Set up uniform
const translationLocation = gl.getUniformLocation(program, "u_translation");

// Translation variables
let tx = 0;
let ty = 0;

function updateAndDraw() {
// Clear the canvas
gl.clear(gl.COLOR_BUFFER_BIT);

// Update translation
tx += 0.01;
ty += 0.005;

// Create translation matrix
const translationMatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1
];

// Send matrix to shader
gl.uniformMatrix4fv(translationLocation, false, translationMatrix);

// Draw
gl.drawArrays(gl.TRIANGLES, 0, 3);

// Request next frame
requestAnimationFrame(updateAndDraw);
}

// Start the animation
updateAndDraw();

Этот код создает красный треугольник, который движется по диагонали экрана. Давайте разберем, что происходит:

  1. Мы определяем наши шейдеры, которые включают матрицу переноса.
  2. Мы настраиваем WebGL, создаем наш program и загружаем наши вершины.
  3. Мы создаем переменные для нашего переноса (tx и ty).
  4. В нашей функции updateAndDraw мы:
  • Очищаем канву
  • Обновляем наши значения переноса
  • Создаем новую матрицу переноса
  • Отправляем эту матрицу на GPU
  • Рисуем наш треугольник
  • Запрашиваем следующий кадр анимации

И вуаля! Вы создали движущийся треугольник в WebGL. Поздравления!

Заключение

Перенос в WebGL может показаться сложным сначала, но это просто о перемещении объектов умным способом. Мы рассмотрели основы здесь, но есть так много больше, что вы можете сделать с переносом - combine его с вращением и масштабированием, создавать сложные анимации или даже строить интерактивные 3D среды.

Помните, jedes Abenteuer beginnt mit einem einzigen Schritt - или в нашем случае, с передвижения одного треугольника. Continue практиковаться, continue экспериментировать, и antes de que te das cuenta, ты будешь создавать удивительные 3D графики, которые двигаются и взаимодействуют так, как ты never думал возможно.

Счастливого кодирования, и пусть твои треугольники всегда находят свой путь домой!

Credits: Image by storyset