WebGL - Hình học
Sau khi có được ngữ cảnh WebGL, bạn phải xác định hình học cho nguyên thủy (đối tượng bạn muốn vẽ) và lưu trữ nó. Trong WebGL, chúng tôi xác định các chi tiết của một hình học - ví dụ, các đỉnh, chỉ số, màu của hình nguyên thủy - bằng cách sử dụng các mảng JavaScript. Để chuyển các chi tiết này đến các chương trình đổ bóng, chúng ta phải tạo các đối tượng đệm và lưu trữ (đính kèm) các mảng JavaScript chứa dữ liệu trong các bộ đệm tương ứng.
Note: Sau đó, các đối tượng đệm này sẽ được liên kết với các thuộc tính của chương trình đổ bóng (vertex shader).
Xác định Hình học Bắt buộc
Mô hình 2D hoặc 3D được vẽ bằng cách sử dụng các đỉnh được gọi là mesh. Mỗi khía cạnh trong lưới được gọi làpolygon và một đa giác được tạo từ 3 đỉnh trở lên.
Để vẽ các mô hình trong ngữ cảnh kết xuất WebGL, bạn phải xác định các đỉnh và chỉ số bằng cách sử dụng mảng JavaScript. Ví dụ: nếu chúng ta muốn tạo một tam giác nằm trên các tọa độ {(5,5), (-5,5), (-5, -5)} như được hiển thị trong sơ đồ, thì bạn có thể tạo một mảng cho các đỉnh là -
var vertices = [
0.5,0.5, //Vertex 1
0.5,-0.5, //Vertex 2
-0.5,-0.5, //Vertex 3
];
Tương tự, bạn có thể tạo một mảng cho các chỉ số. Các chỉ số cho các chỉ số tam giác trên sẽ là [0, 1, 2] và có thể được định nghĩa là -
var indices = [ 0,1,2 ]
Để hiểu rõ hơn về các chỉ số, hãy xem xét các mô hình phức tạp hơn như hình vuông. Chúng ta có thể biểu diễn một hình vuông dưới dạng một tập hợp hai hình tam giác. Nếu (0,3,1) và (3,1,2) là hai hình tam giác mà chúng ta định vẽ hình vuông, thì các chỉ số sẽ được định nghĩa là -
var indices = [0,3,1,3,1,2];
Note -
Đối với bản vẽ ban đầu, WebGL cung cấp hai phương pháp sau:
drawArrays() - Trong khi sử dụng phương pháp này, chúng ta truyền các đỉnh của nguyên thủy bằng cách sử dụng các mảng JavaScript.
drawElements() - Trong khi sử dụng phương pháp này, chúng ta truyền cả đỉnh và chỉ số của nguyên thủy bằng mảng JavaScript.
Đối tượng đệm
Đối tượng đệm là một cơ chế được cung cấp bởi WebGL chỉ ra một vùng bộ nhớ được cấp phát trong hệ thống. Trong các đối tượng đệm này, bạn có thể lưu trữ dữ liệu của mô hình bạn muốn vẽ, tương ứng với các đỉnh, chỉ số, màu sắc, v.v.
Sử dụng các đối tượng đệm này, bạn có thể truyền nhiều dữ liệu vào chương trình đổ bóng (vertex shader) thông qua một trong các biến thuộc tính của nó. Vì các đối tượng đệm này nằm trong bộ nhớ GPU, chúng có thể được hiển thị trực tiếp, do đó cải thiện hiệu suất.
Để xử lý hình học, có hai loại đối tượng đệm. Họ là -
Vertex buffer object (VBO)- Nó chứa dữ liệu mỗi đỉnh của mô hình đồ họa sẽ được hiển thị. Chúng tôi sử dụng các đối tượng đệm đỉnh trong WebGL để lưu trữ và xử lý dữ liệu liên quan đến các đỉnh như tọa độ đỉnh, chuẩn, màu và tọa độ kết cấu.
Index buffer objects (IBO) - Nó chứa các chỉ số (dữ liệu chỉ mục) của mô hình đồ họa sẽ được hiển thị.
Sau khi xác định hình học cần thiết và lưu trữ chúng trong các mảng JavaScript, bạn cần chuyển các mảng này tới các đối tượng đệm, từ đó dữ liệu sẽ được chuyển đến các chương trình đổ bóng. Các bước sau sẽ được thực hiện để lưu trữ dữ liệu trong bộ đệm.
Tạo một vùng đệm trống.
Liên kết một đối tượng mảng thích hợp vào vùng đệm trống.
Truyền dữ liệu (đỉnh / chỉ số) vào bộ đệm bằng cách sử dụng một trong các typed arrays.
Bỏ liên kết bộ đệm (Tùy chọn).
Tạo vùng đệm
Để tạo một đối tượng đệm trống, WebGL cung cấp một phương thức được gọi là createBuffer(). Phương thức này trả về một đối tượng đệm mới được tạo, nếu việc tạo thành công; nếu không nó trả về giá trị null trong trường hợp không thành công.
WebGL hoạt động như một máy trạng thái. Khi một bộ đệm được tạo, bất kỳ thao tác đệm tiếp theo nào sẽ được thực hiện trên bộ đệm hiện tại cho đến khi chúng tôi hủy liên kết nó. Sử dụng mã sau để tạo bộ đệm:
var vertex_buffer = gl.createBuffer();
Note - gl là biến tham chiếu đến ngữ cảnh WebGL hiện tại.
Ràng buộc đệm
Sau khi tạo một đối tượng bộ đệm trống, bạn cần liên kết một bộ đệm mảng thích hợp (đích) với nó. WebGL cung cấp một phương thức được gọi làbindBuffer() vì mục đích này.
Cú pháp
Cú pháp của bindBuffer() phương pháp như sau:
void bindBuffer (enum target, Object buffer)
Phương thức này chấp nhận hai tham số và chúng được thảo luận bên dưới.
target- Biến đầu tiên là một giá trị enum đại diện cho kiểu bộ đệm mà chúng ta muốn liên kết với bộ đệm trống. Bạn có hai giá trị enum được xác định trước làm tùy chọn cho tham số này. Họ là -
ARRAY_BUFFER đại diện cho dữ liệu đỉnh.
ELEMENT_ARRAY_BUFFER đại diện cho dữ liệu chỉ mục.
Object buffer- Biến thứ hai là biến tham chiếu đến đối tượng đệm được tạo ở bước trước. Biến tham chiếu có thể là đối tượng đệm đỉnh hoặc đối tượng đệm chỉ mục.
Thí dụ
Đoạn mã sau đây cho thấy cách sử dụng phương thức bindBuffer ().
//vertex buffer
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
//Index buffer
var Index_Buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
Truyền dữ liệu vào bộ đệm
Bước tiếp theo là truyền dữ liệu (đỉnh / chỉ số) vào bộ đệm. Cho đến bây giờ dữ liệu ở dạng mảng và trước khi chuyển nó vào bộ đệm, chúng ta cần bọc nó trong một trong các mảng đã định kiểu WebGL. WebGL cung cấp một phương thức có tênbufferData() vì mục đích này.
Cú pháp
Cú pháp của phương thức bufferData () như sau:
void bufferData (enum target, Object data, enum usage)
Phương thức này chấp nhận ba tham số và chúng được thảo luận bên dưới:
target - Tham số đầu tiên là một giá trị enum đại diện cho loại bộ đệm mảng mà chúng tôi đã sử dụng. Các tùy chọn cho tham số này là:
ARRAY_BUFFER đại diện vertex data.
ELEMENT_ARRAY_BUFFER đại diện index data.
Object data- Tham số thứ hai là giá trị đối tượng chứa dữ liệu cần ghi vào đối tượng đệm. Ở đây chúng ta phải chuyển dữ liệu bằng cách sử dụngtyped arrays.
Usage- Tham số thứ ba của phương thức này là một biến enum chỉ định cách sử dụng dữ liệu đối tượng đệm (dữ liệu được lưu trữ) để vẽ hình. Có ba tùy chọn cho tham số này như được liệt kê bên dưới.
gl.STATIC_DRAW - Dữ liệu sẽ được chỉ định một lần và sử dụng nhiều lần.
gl.STREAM_DRAW - Dữ liệu sẽ được chỉ định một lần và sử dụng một vài lần.
gl.DYNAMIC_DRAW - Dữ liệu sẽ được chỉ định lặp lại và sử dụng nhiều lần.
Thí dụ
Đoạn mã sau đây cho biết cách sử dụng bufferData()phương pháp. Giả sử đỉnh và chỉ số là mảng chứa dữ liệu đỉnh và chỉ số tương ứng.
//vertex buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
//Index buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
Mảng đã nhập
WebGL cung cấp một loại mảng đặc biệt được gọi là typed arraysđể chuyển các phần tử dữ liệu như đỉnh chỉ mục và kết cấu. Các mảng đã nhập này lưu trữ số lượng lớn dữ liệu và xử lý chúng ở định dạng nhị phân nguyên bản giúp mang lại hiệu suất tốt hơn. Các mảng đã nhập được WebGL sử dụng là Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, UInt32Array, Float32Array và Float64Array.
Note
Nói chung, để lưu trữ dữ liệu đỉnh, chúng tôi sử dụng Float32Array; và để lưu trữ dữ liệu chỉ mục, chúng tôi sử dụngUint16Array.
Bạn có thể tạo mảng đã nhập giống như mảng JavaScript bằng cách sử dụng new từ khóa.
Bỏ liên kết bộ đệm
Bạn nên hủy liên kết các bộ đệm sau khi sử dụng chúng. Nó có thể được thực hiện bằng cách chuyển một giá trị null vào vị trí của đối tượng đệm, như hình dưới đây.
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
WebGL cung cấp các phương pháp sau để thực hiện các hoạt động đệm:
Sr.No. | Phương pháp và Mô tả |
---|---|
1 | vô hiệu bindBuffer( đích enum , bộ đệm đối tượng ) mục tiêu - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER |
2 | vô hiệu bufferData( mục tiêu enum , kích thước dài , sử dụng enum ) mục tiêu - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER sử dụng - STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW |
3 | vô hiệu bufferData( đích enum , dữ liệu đối tượng , sử dụng enum ) mục tiêu và cách sử dụng - Tương tự như đối vớibufferData ở trên |
4 | vô hiệu bufferSubData( mục tiêu enum , độ lệch dài , dữ liệu đối tượng ) mục tiêu - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER |
5 | Vật createBuffer() |
6 | vô hiệu deleteBuffer(Bộ đệm đối tượng ) |
7 | bất kì getBufferParameter(enum target , enum pname ) mục tiêu - ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER pname - BUFFER_SIZE, BUFFER_USAGE |
số 8 | bool isBuffer(Bộ đệm đối tượng ) |