Bộ đệm chỉ mục là gì và nó liên quan đến bộ đệm đỉnh như thế nào?


11

Tôi có một bộ đệm đỉnh như thế này:

0.0, 0.0,
1.0, 0.0,
0.0, 0.6,
1.0, 0.6,
0.5, 1.0

Tôi có bộ đệm chỉ mục sau:

0, 2,
2, 4,
4, 3,
3, 2,
2, 1,
1, 0,
0, 3,
3, 1

Tôi biết tôi muốn vẽ gl.LINESbằng WebGL, có nghĩa là nhiều phân đoạn dòng tách biệt.

gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, indexBuffer);

Nó dường như cho phép vẽ nhiều phân đoạn trong một lệnh gọi trong WebGL.

Ai đó có thể ELI5 với tôi, bộ đệm chỉ mục là gì và nó liên quan đến bộ đệm đỉnh như thế nào? Làm thế nào để tạo bộ đệm chỉ mục từ nguyên thủy của tôi?

Câu trả lời:


12

Ai đó có thể ELI5 với tôi, bộ đệm chỉ mục là gì và nó liên quan đến bộ đệm đỉnh như thế nào

Bộ đệm đỉnh của bạn chứa tọa độ X và Y của 5 đỉnh. Họ đang:

index |  X  |  Y
  0   | 0.0 | 0.0 
  1   | 1.0 | 0.0
  2   | 0.0 | 0.6
  3   | 1.0 | 0.6
  4   | 0.5 | 1.0

Bộ đệm chỉ mục của bạn chứa thông tin về những đường sẽ vẽ giữa các đỉnh này. Nó sử dụng chỉ số của từng đỉnh trong bộ đệm đỉnh làm giá trị.

Vì bạn đang vẽ các dòng, mỗi cặp giá trị liên tiếp trong bộ đệm chỉ mục của bạn chỉ ra một phân đoạn dòng. Ví dụ, nếu bộ đệm chỉ mục bắt đầu bằng 0, 2, nó có nghĩa là vẽ một đường giữa các đỉnh 0 và 2 trong mảng đỉnh, trong trường hợp này sẽ vẽ một đường đi từ [0.0, 0.0]đến [0.0, 0.6].

Trong đồ họa sau, mỗi cặp chỉ số được phối màu với đường kẻ chỉ ra:

nhập mô tả hình ảnh ở đây

Tương tự, nếu bạn đang vẽ các hình tam giác thay vì các đường, bạn sẽ cần cung cấp bộ đệm chỉ mục trong đó mỗi 3 giá trị liên tiếp chỉ ra các chỉ số của ba đỉnh trong bộ đệm đỉnh, ví dụ:

0, 1, 2,
2, 1, 3,
2, 3, 4,

5

Nếu bạn có một bộ đệm đỉnh như thế này:

var vertices = [
  0.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.5, 1.0, 0.0
]

Và chỉ cần vẽ nó như là:

// Create an empty buffer object
var vertex_buffer = gl.createBuffer();

// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 5);

Nó sẽ yêu cầu hai tọa độ dành riêng cho mỗi phân đoạn dòng. Với verticesđịnh nghĩa như trên, chỉ có thể vẽ hai dòng :

hai dòng

Nếu bạn có các chỉ số sau được xác định:

var indices = [
  0, 2,
  2, 4,
  4, 3,
  3, 2,
  2, 1,
  1, 0,
  0, 3,
  3, 1
]

Có thể vẽ các đường giao nhau cùng một đỉnh nhiều lần. Điều này làm giảm sự dư thừa. Nếu bạn liên kết bộ đệm chỉ mục và yêu cầu GPU vẽ các đoạn đường nối các đỉnh theo thứ tự được chỉ định trong mảng không đứng đắn:

var index_buffer = gl.createBuffer();

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

// draw geometry lines by indices
gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, index_buffer);

Người ta có thể vẽ các hình phức tạp hơn mà không cần xác định lại các đỉnh giống nhau nhiều lần. Đây là kết quả:

căn nhà

Để đạt được kết quả tương tự mà không có chỉ số, bộ đệm đỉnh sẽ trông như sau:

var vertices = [
  0.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.5, 1.0, 0.0,
  0.5, 1.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.0, 0.0
]

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 16);

Kết quả trong cùng một hình ảnh:

một ngôi nhà khác

Lưu ý sự dư thừa lớn trong các đỉnh được lưu trữ.


2
Nếu bạn có kế hoạch trả lời ngay câu hỏi của mình, ít nhất hãy đề cập đến nó trong câu hỏi để người khác không lãng phí thời gian của họ.
Rotem

2
Mỗi câu hỏi hay nên có 2 hoặc 3 câu trả lời hay. Bạn đã không lãng phí thời gian của bạn và tôi thực sự đánh giá cao hiệu ứng của bạn. Tôi cần chủ đề này để giải thích logic cho một đối tác dự án và bài viết của bạn sẽ giúp anh ta rất nhiều.
Afr

1
@ 5chdn Tự trả lời rất được khuyến khích . Cảm ơn đã thêm câu trả lời này. Nếu bạn có câu trả lời trong đầu khi bạn đăng câu hỏi, có một ô đánh dấu bên dưới câu hỏi sẽ cho phép bạn viết câu trả lời trước khi đăng câu hỏi, vì vậy cả hai sẽ xuất hiện cùng một lúc. Điều này chỉ để cho bạn biết trong trường hợp nó hữu ích - bạn chắc chắn không cần phải làm điều này và tự trả lời vẫn rất được hoan nghênh tại bất kỳ khoảng thời gian nào sau khi đăng câu hỏi.
trichoplax
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.