WebGL - Cơ bản: Giới thiệu thân thiện cho người mới bắt đầu

Xin chào các pháp sư WebGL tương lai! Tôi rất phấn khích được hướng dẫn các bạn trên hành trình thú vị vào thế giới của WebGL. Là một ai đó đã dạy đồ họa máy tính trong nhiều năm, tôi không thể chờ đợi để chia sẻ phép màu của WebGL với các bạn. Đừng lo lắng nếu bạn mới bắt đầu học lập trình - chúng ta sẽ bắt đầu từ đầu và xây dựng kiến thức từng bước. Vậy, hãy lấy một tách cà phê (hoặc trà, nếu đó là sở thích của bạn), và chúng ta cùng bắt đầu!

WebGL - Basics

WebGL là gì?

Trước khi chúng ta nhảy vào phần chi tiết, hãy hiểu WebGL là gì. WebGL (Web Graphics Library) là một API JavaScript mạnh mẽ cho phép chúng ta tạo ra những hình ảnh 3D tuyệt vời ngay trong trình duyệt web của mình. Nó giống như có một studio điện ảnh mini trong lòng bàn tay bạn!

Hãy nghĩ WebGL như một cây cầu giữa trình duyệt web của bạn và phần cứng đồ họa của máy tính. Nó cho phép chúng ta khai thác sức mạnh của GPU (Graphics Processing Unit) để render các cảnh 3D phức tạp với hiệu suất mượt mà. Đúng là tuyệt vời phải không?

Hệ tọa độ WebGL

Bây giờ, hãy nói về hệ tọa độ WebGL. Hãy tưởng tượng bạn đang đứng ở giữa một khối 3D vô hình khổng lồ. Đó chính là hệ tọa độ WebGL!

Hệ tọa độ Descartes

WebGL sử dụng một hệ tọa độ Descartes 3D. Nó tương tự như hệ 2D bạn có thể đã học trong lớp toán, nhưng với một chiều额外的:

  • Trục X: HORIZONTAL (từ trái sang phải)
  • Trục Y: VERTICAL (từ dưới lên trên)
  • Trục Z: Độ sâu (từ sau ra trước)

Dưới đây là một ví dụ đơn giản để giúp bạn hình dung:

// Định nghĩa một đỉnh (điểm trong không gian 3D)
var vertex = [
0.5,  // Tọa độ X
0.7,  // Tọa độ Y
0.0   // Tọa độ Z
];

Trong ví dụ này, chúng ta đang định nghĩa một điểm nằm hơi bên phải (0.5) và lên trên (0.7) từ trung tâm, và ngay trên bề mặt màn hình (0.0).

Không gian剪辑

Một đặc điểm kỳ lạ của WebGL là nó sử dụng một dải tọa độ đặc biệt gọi là "không gian剪辑". Tất cả các tọa độ phải nằm trong khoảng từ -1.0 đến 1.0 trên mỗi trục. Bất kỳ thứ gì ngoài phạm vi này sẽ bị "bị剪辑" (không được vẽ).

// Một điểm ở góc trên bên phải của không gian剪辑
var cornerPoint = [1.0, 1.0, 0.0];

// Một điểm sẽ bị剪辑 (không nhìn thấy)
var clippedPoint = [1.5, 0.5, 0.0];

Đồ họa WebGL

Bây giờ chúng ta đã hiểu hệ tọa độ, hãy nói về cách WebGL thực sự vẽ các vật thể.

Primitives

WebGL vẽ mọi thứ bằng các hình dạng đơn giản gọi là primitives. Ba loại chính là:

  1. Points: Các điểm đơn lẻ
  2. Lines: Các đường thẳng giữa các điểm
  3. Triangles: Các hình tam giác

Dưới đây là bảng tóm tắt các primitives:

Primitive Mô tả Trường hợp sử dụng
Points Điểm đơn lẻ Hiệu ứng hạt, vì sao
Lines Đường thẳng giữa các điểm Khung công tác, đồ thị
Triangles Hình tam giác Most 3D models, terrain

Hãy xem cách chúng ta có thể định nghĩa một tam giác đơn giản:

var triangleVertices = [
0.0,  0.5,  0.0,  // Điểm trên
-0.5, -0.5,  0.0,  // Điểm dưới bên trái
0.5, -0.5,  0.0   // Điểm dưới bên phải
];

Mã này định nghĩa ba điểm của một tam giác. Mỗi điểm được đại diện bởi ba số (x, y, z).

Buffers

Để thực sự đưa tam giác của chúng ta lên màn hình, chúng ta cần sử dụng một thứ gọi là buffer. Hãy nghĩ buffer như một容器 chứa dữ liệu đỉnh và gửi nó đến GPU.

Dưới đây là cách chúng ta có thể tạo và điền một buffer:

// Tạo một buffer
var buffer = gl.createBuffer();

// Kết nối buffer (làm cho nó trở thành buffer hoạt động)
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

// Điền buffer với dữ liệu tam giác của chúng ta
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);

Đừng lo lắng nếu điều này có vẻ hơi rối rắm ngay bây giờ. Chúng ta sẽ phân tích chi tiết hơn khi chúng ta tiếp tục!

Chương trình Shader

Bây giờ chúng ta đã đến phần rất thú vị: shaders! Shaders là các chương trình đặc biệt chạy trên GPU. Chúng giống như những nhà máy nhỏ xử lý từng đỉnh và pixel của cảnh 3D của bạn.

Loại Shaders

Có hai loại shaders chính trong WebGL:

  1. Vertex Shaders: Xử lý từng đỉnh (điểm) trong cảnh 3D của bạn
  2. Fragment Shaders: Xác định màu sắc của từng pixel

Dưới đây là ví dụ đơn giản về mỗi loại:

// Vertex Shader
attribute vec4 a_position;

void main() {
gl_Position = a_position;
}

// Fragment Shader
precision mediump float;

void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);  // Màu đỏ tươi
}

Vertex shader lấy từng điểm (vertex) và quyết định nó nên nằm ở đâu trên màn hình. Fragment shader sau đó.fill vào tất cả các pixel giữa các điểm.

Biên dịch và Kết nối Shaders

Để sử dụng các shaders của chúng ta, chúng ta cần biên dịch chúng và kết nối chúng thành một chương trình:

// Tạo chương trình shader
var program = gl.createProgram();

// Kết nối và biên dịch shaders
var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);

// Kết nối chương trình
gl.linkProgram(program);

Quá trình này giống như biên dịch và kết nối một chương trình thông thường, nhưng nó diễn ra trên GPU!

Biến SL OpenGL ES

Cuối cùng, hãy nói về một số biến đặc biệt được sử dụng trong Ngôn ngữ Shading của OpenGL ES (ngôn ngữ mà các shaders của chúng ta được viết).

Attributes

Attributes là các biến đầu vào được sử dụng trong vertex shaders. Chúng thường chứa dữ liệu về từng đỉnh, như vị trí hoặc màu sắc.

attribute vec4 a_position;

Uniforms

Uniforms là các biến toàn cục không thay đổi cho tất cả các đỉnh và fragment. Chúng rất hữu ích cho các thứ như ma trận chuyển đổi hoặc thông tin ánh sáng.

uniform mat4 u_modelViewMatrix;

Varyings

Varyings là các biến truyền dữ liệu từ vertex shader đến fragment shader. Chúng được nội suy giữa các đỉnh.

varying vec4 v_color;

Dưới đây là bảng tóm tắt các loại biến:

Variable Type Used In Purpose
Attribute Vertex Shader Dữ liệu đầu vào cho từng đỉnh
Uniform Both Dữ liệu toàn cục
Varying Both Dữ liệu truyền từ vertex đến fragment shader

Và thế là xong! Chúng ta đã bao gồm các cơ bản của WebGL, từ tọa độ đến shaders. Nhớ rằng học WebGL giống như học vẽ - nó đòi hỏi sự thực hành và kiên nhẫn. Đừng nản lòng nếu mọi thứ không ngay lập tức hiểu được. Hãy tiếp tục thử nghiệm, và sớm bạn sẽ tạo ra những hình ảnh 3D tuyệt vời trong trình duyệt của mình!

Chúc mừng coding, các nhà vô địch WebGL tương lai!

Credits: Image by storyset