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我們要在每個軸上移動多少。以下是如何創建一個平移矩陣的方法:
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
- 繪製我們的三角形
- 請求下一幀動畫
這樣,你就創造了一個在螢幕上移動的三角形。讓我們祝賀你!每個旅程都從一個單一的步驟開始——或者在我們的例子中,是一個移動的三角形。繼續練習,繼續嘗試,不久之後,你將能夠創造出以前認為不可能的移動和互動的3D圖形。
祝編程愉快,願你的三角形總是能找到回家的路!
Credits: Image by storyset