2010-06-02 39 views
40

Tôi đang cố gắng để có được một ý tưởng rõ ràng khi tôi nên sử dụng các mảng được lập chỉ mục của các đỉnh OpenGL, được vẽ bằng các phép vẽ [Multi] DrawElements và tương tự, so với khi tôi chỉ nên sử dụng các mảng liền nhau của các đỉnh, được vẽ bằng gl [Multi DrawArrays.Khi nào tôi nên sử dụng các mảng được lập chỉ mục của các đỉnh OpenGL?

(Cập nhật:. Sự đồng thuận trong các câu trả lời tôi nhận được rằng một lúc nào nên sử dụng các đỉnh được lập chỉ mục)

Tôi đã đi qua lại về vấn đề này nhiều lần, vì vậy tôi sẽ phác thảo sự hiểu biết hiện tại của tôi, với hy vọng ai đó có thể nói với tôi rằng bây giờ tôi đã chính xác hơn hoặc ít hơn, hoặc chỉ ra những hiểu lầm còn lại của tôi ở đâu. Cụ thể, tôi có ba kết luận, in đậm. Vui lòng sửa chúng nếu chúng sai.

Một trường hợp đơn giản là nếu hình của tôi bao gồm các mắt lưới để tạo thành bề mặt cong. Trong trường hợp này, các đỉnh ở giữa lưới sẽ có các thuộc tính giống nhau (vị trí, bình thường, màu sắc, phối cảnh kết cấu, vv) cho mỗi tam giác sử dụng đỉnh.

Điều này dẫn tôi đến kết luận rằng:

1. Đối với hình học với vài đường may, mảng lập chỉ mục là một chiến thắng lớn.

Thực hiện theo quy tắc 1 luôn, ngoại trừ:

Đối với hình học đó là rất 'khối ô vuông', trong đó mỗi cạnh đại diện cho một đường may, lợi ích của mảng được lập chỉ mục là ít rõ ràng. Để lấy một khối lập phương đơn giản, mặc dù mỗi đỉnh được sử dụng trong ba mặt khác nhau, chúng ta không thể chia các đỉnh giữa chúng, bởi vì đối với một đỉnh đơn, các chỉ tiêu bề mặt (và các thứ khác có thể, như phối màu và kết cấu)) sẽ khác nhau trên mỗi khuôn mặt. Do đó chúng ta cần giới thiệu một cách rõ ràng các vị trí đỉnh dư thừa vào mảng của chúng ta, để cùng một vị trí có thể được sử dụng nhiều lần với các chuẩn khác nhau, v.v. Điều này có nghĩa là các mảng được lập chỉ mục ít sử dụng hơn.

ví dụ: Khi vẽ một khuôn mặt duy nhất của một khối lập phương:

0  1 
    o---o 
    |\ | 
    | \ | 
    | \| 
    o---o 
3  2 

(điều này có thể được xem xét trong sự cô lập, vì vỉa giữa khuôn mặt này và tất cả các mặt kề nhau có ý nghĩa hơn không ai trong số những đỉnh có thể được chia sẻ giữa khuôn mặt)

nếu hiển thị bằng GL_TRIANGLE_FAN (hoặc _STRIP), thì mỗi khuôn mặt của khối lập phương có thể được hiển thị như sau:

verts = [v0, v1, v2, v3] 
colors = [c0, c0, c0, c0] 
normal = [n0, n0, n0, n0] 

Thêm chỉ mục không cho phép chúng tôi đơn giản hóa điều này.

Từ đó tôi kết luận rằng:

2. Khi render hình học mà là tất cả vỉa hoặc chủ yếu là đường may, khi sử dụng GL_TRIANGLE_STRIP hoặc _FAN, sau đó tôi không bao giờ nên sử dụng mảng lập chỉ mục, và nên thay vì luôn luôn sử dụng gl [Multi DrawArrays.

(Cập nhật: Trả lời cho biết kết luận này là sai.Mặc dù chỉ số không cho phép chúng tôi để giảm kích thước của mảng ở đây, họ nên vẫn được sử dụng vì lợi ích hiệu suất khác, như đã thảo luận trong các ý kiến)

Ngoại lệ duy nhất để cai trị 2 là:

Khi sử dụng GL_TRIANGLES (thay vì dải hoặc quạt), thì một nửa các đỉnh vẫn có thể được sử dụng lại hai lần, với các chuẩn mực và màu sắc giống nhau, v.v., vì mỗi mặt khối lập phương được hiển thị dưới dạng hai hình tam giác riêng biệt. Một lần nữa, cho cùng một mặt khối duy nhất:

0  1 
    o---o 
    |\ | 
    | \ | 
    | \| 
    o---o 
3  2 

Nếu không có chỉ số, sử dụng GL_TRIANGLES, các mảng sẽ là một cái gì đó như:

verts = [v0, v1, v2, v2, v3, v0] 
normals = [n0, n0, n0, n0, n0, n0] 
colors = [c0, c0, c0, c0, c0, c0] 

Từ một đỉnh và một bình thường thường 3 nổi từng, và một màu thường là 3 byte, cho phép, đối với mỗi mặt khối lập phương, khoảng:

verts = 6 * 3 floats = 18 floats 
normals = 6 * 3 floats = 18 floats 
colors = 6 * 3 bytes = 18 bytes 

= 36 floats and 18 bytes per cube face. 

(tôi biết số byte có thể thay đổi nếu loại khác nhau được sử dụng, những con số chính xác là chỉ dành riêng cho illust . Ration)

Với chỉ số này, chúng ta có thể đơn giản hóa này một chút, đưa ra:

verts = [v0, v1, v2, v3]  (4 * 3 = 12 floats) 
normals = [n0, n0, n0, n0]  (4 * 3 = 12 floats) 
colors = [c0, c0, c0, c0]  (4 * 3 = 12 bytes) 
indices = [0, 1, 2, 2, 3, 0] (6 shorts) 

= 24 floats + 12 bytes, and maybe 6 shorts, per cube face. 

Xem cách trong trường hợp sau, đỉnh 0 và 2 được sử dụng hai lần, nhưng chỉ thể hiện một lần trong mỗi Verts , mảng chuẩn và mảng màu. Điều này nghe có vẻ như một chiến thắng nhỏ để sử dụng các chỉ số, ngay cả trong trường hợp cực đoan của mỗi cạnh hình học duy nhất là một đường may.

Điều này dẫn tôi đến kết luận rằng:

3. Khi sử dụng GL_TRIANGLES, một lúc nào nên sử dụng mảng lập chỉ mục, ngay cả đối với hình học mà là các đường nối.

Vui lòng sửa kết luận của tôi bằng chữ in đậm nếu chúng sai.

+1

Tôi thực sự thích định dạng của câu hỏi này. – SimpleVar

Trả lời

33

Từ đó tôi kết luận rằng khi vẽ hình học mà là tất cả vỉa hoặc chủ yếu là đường may, khi sử dụng GL_TRIANGLE_STRIP hoặc _FAN, sau đó tôi không bao giờ nên sử dụng mảng lập chỉ mục, và nên thay vì luôn luôn sử dụng gl [Multi] DrawArrays.

Không, và lý do khá đơn giản.

Kết luận của bạn dựa trên thực tế bạn đã phân tích một quad đơn được tạo thành bởi hai hình tam giác. Hai tam giác được vẽ bằng quạt/dải tam giác không thể đơn giản hóa bằng các mảng được lập chỉ mục.

Nhưng hãy thử suy nghĩ về hình học địa hình lớn. Mỗi khối địa hình được vẽ như một hình tứ giác, sử dụng quạt nguyên thủy/dải nguyên thủy. Ví dụ:

Mỗi dải tam giác trong hình có điểm chung tất cả các đỉnh với dải tam giác liền kề, và sử dụng các chỉ số cho phép để nén các định nghĩa hình học, thay vì lặp lại đỉnh cho mỗi dải tam giác.


Về cơ bản, bản vẽ nguyên thủy (hình tam giác, người hâm mộ và dải) sử dụng các chỉ số là hữu ích bất cứ khi nào bạn có thể chia sẻ hầu hết các đỉnh của một nguyên thủy duy nhất với nhau.

Chia sẻ thông tin cho phép lưu băng thông truyền tải thông tin, nhưng nó không phải là lợi thế duy nhất. Trên thực tế các mảng lập chỉ mục cho phép:

  • Tránh đồng bộ hóa các thông tin thuộc với cùng đỉnh "khái niệm", quy định nhiều lần
  • phép để thực hiện các hoạt động đổ bóng cùng trên một đỉnh duy nhất thay vì thực hiện nhiều lần, một cho mỗi đỉnh sao chép.
  • Hơn nữa, kết hợp việc sử dụng dải tam giác/quạt và chỉ mục cho phép ứng dụng nén bộ đệm chỉ mục, vì đặc điểm kỹ thuật của dải/quạt yêu cầu ít chỉ mục hơn (tam giác yêu cầu 3 chỉ số cho mỗi khuôn mặt).

Không thể sử dụng mảng được lập chỉ mục, như bạn đã chỉ định, bất cứ khi nào đỉnh không thể chia sẻ mọi thông tin được liên kết với nó (màu, kết cấu và vv) với đỉnh khác trùng.


Chỉ vì mục đích hoàn chỉnh, kích thước thông tin cần thiết cho đặc tả hình học không phải là yếu tố duy nhất xác định hoạt động kết xuất tối ưu.

Infact, một yếu tố cơ bản khác để hiển thị nguyên thủy là bản địa hóa bộ nhớ cache của dữ liệu. Dữ liệu hình học được chỉ định không đúng (các đối tượng đệm không xen kẽ, các dải tam giác dài ...) gây ra rất nhiều lỗi trong bộ nhớ cache, làm giảm hiệu năng của card đồ họa.

Để tối ưu hóa hoạt động kết xuất, đặc điểm kỹ thuật đỉnh sẽ được sắp xếp lại theo cách sử dụng lại các đỉnh được chỉ định trước đó, với xác suất cao nhất. Theo cách đó, dòng bộ nhớ cache thẻ đồ họa có thể tái sử dụng các đỉnh được chỉ định trước đó mà không cần tìm nạp chúng từ bộ nhớ.

+2

+1 nhưng tôi sẽ thêm rằng bằng cách sử dụng các chỉ mục thì bộ nhớ cache đỉnh sẽ xuất hiện. Chừng nào các đỉnh được chia sẻ giữa các hình tam giác khác nhau được sử dụng gần nhau thì card đồ họa đã biết kết quả của chỉ số biến đổi "i" là gì và, do đó, sẽ sử dụng câu trả lời được lưu trong bộ nhớ cache thay vì tính lại nó. Điều này là rất hữu ích nếu bạn có các chương trình đỉnh phức tạp ... Nó cũng có nghĩa là số lượng công việc biến đổi đỉnh giữa chỉ mục không bị tước bỏ và không lập chỉ mục bị tước là giống hệt nhau. Con đường không bị tước bỏ được tối ưu hóa hơn để bạn có được hiệu suất tốt hơn bị tước bỏ. – Goz

+0

Đó là tất cả có ý nghĩa, cảm ơn rất nhiều cho đầu vào của bạn. Tuy nhiên, kết luận (2), mà bạn trích dẫn, cụ thể nói rằng nó chỉ áp dụng "khi kết xuất hình học mà tất cả các đường nối hoặc chủ yếu là đường nối" ý định của tôi là hình ảnh của lưới lớn bạn hiển thị sẽ rơi vào kết luận (1) : "đối với hình học có vài đường nối, mảng được lập chỉ mục là một chiến thắng lớn". Lời xin lỗi của tôi Tôi không rõ lắm. Ghi nhớ điều này, bạn vẫn không đồng ý với kết luận 2? Rất cám ơn. –

+0

IMHO, việc sử dụng dải/quạt nguyên thủy (có ot không có đường nối) không ngụ ý việc sử dụng sai hình dạng được lập chỉ mục, như đã nêu trong báo giá. – Luca

Các vấn đề liên quan