2011-12-14 36 views
19

Tôi đã đọc this bài viết, và tác giả viết:Có hủy bỏ hiệu suất chương trình trong OpenGL không?

Dưới đây là làm thế nào để viết các ứng dụng hiệu suất cao trên mọi nền tảng trong hai bước đơn giản:
[...]
Thực hiện theo thông lệ tốt nhất. Trong trường hợp của Android và OpenGL, điều này bao gồm những thứ như "cuộc gọi vẽ theo lô", "không sử dụng loại bỏ trong trình phát phân đoạn", v.v.

Tôi chưa bao giờ nghe nói rằng việc hủy bỏ sẽ có tác động xấu đến hiệu suất hoặc như vậy và đã sử dụng nó để tránh pha trộn khi alpha chi tiết không cần thiết.

Ai đó có thể giải thích lý do tại sao và khi sử dụng loại bỏ có thể bị coi là hành vi không tốt và cách loại bỏ + chiều sâu so sánh với alpha + blend?

Chỉnh sửa: Sau khi nhận được câu trả lời cho câu hỏi này, tôi đã thực hiện một số thử nghiệm bằng cách hiển thị gradient nền có tứ kết cấu trên đầu trang đó.

  • Sử dụng GL_DEPTH_TEST và fragment-shader kết thúc với dòng "if( gl_FragColor.a < 0.5){ discard; }" đã về 32 fps.
  • Xóa câu lệnh if/discard khỏi trình tạo phân đoạn đã tăng tốc độ hiển thị tới khoảng 44 fps.
  • Sử dụng GL_BLEND với hàm pha trộn "(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)" thay vì GL_DEPTH_TEST cũng dẫn đến khoảng 44 fps.
+0

Câu hỏi rất thú vị, tôi hy vọng ai đó sẽ có thể trả lời câu hỏi đó. – bvd

Trả lời

16

Tùy thuộc vào phần cứng. Đối với phần cứng PowerVR và các GPU khác sử dụng hiển thị dựa trên nền, sử dụng discard có nghĩa là TBR không còn giả định rằng mọi đoạn được vẽ sẽ trở thành pixel. Giả định này là quan trọng vì nó cho phép TBR đánh giá tất cả các chiều sâu trước tiên, sau đó chỉ đánh giá các trình đổ bóng phân đoạn cho các đoạn trên cùng. Một loại phương pháp hiển thị trả chậm, ngoại trừ phần cứng.

Lưu ý rằng bạn sẽ gặp vấn đề tương tự khi bật thử nghiệm alpha.

+1

Ah, tôi hiểu rồi. Vì vậy, nếu loại bỏ được sử dụng, nó sẽ ảnh hưởng đến mỗi ngói, hoặc chỉ là một trong đó một mảnh đã bị loại bỏ? Nếu nó chỉ ảnh hưởng đến một ô, nó vẫn hiệu quả hơn việc sử dụng alpha/blending, đúng không? – Jave

+1

Bạn có ý nghĩa gì với "alpha/blending"? Trong bất kỳ trường hợp nào, nó sẽ ảnh hưởng đến tất cả các tile thực hiện một shader fragment sử dụng từ khóa 'discard', cho dù nó có thực sự gọi nó hay không. –

+0

Với alpha/pha trộn, tôi chỉ đơn giản có nghĩa là sử dụng một kết cấu với một alphamap xác định khả năng hiển thị của đoạn hiện tại. Nếu tôi nhớ chính xác rằng nó không hoạt động đúng, trừ khi bạn đã kích hoạt GL_BLEND và không phải GL_DEPTH_TEST (nếu bạn render một đối tượng ở phía trước đối tượng khác chẳng hạn)? – Jave

17

"hủy" là xấu đối với mọi kỹ thuật tăng tốc đồ họa chính thống - IMR, TBR, TBDR. Điều này là do khả năng hiển thị của một đoạn (và do đó chiều sâu) chỉ có thể xác định sau khi xử lý phân đoạn và không trong HSR đầu tiên hoặc PowerRR (loại bỏ bề mặt ẩn) vv. hiệu suất; trong trường hợp này, việc xử lý nhiều mảnh vỡ hơn + sự gián đoạn xử lý chiều sâu của các đa giác khác = hiệu ứng xấu

Nếu bạn phải sử dụng loại bỏ, hãy đảm bảo rằng chỉ tris cần nó được đổ bóng. hiệu suất hiển thị tổng thể, hiển thị đối tượng của bạn theo thứ tự: mờ đục, loại bỏ, được trộn.

Ngẫu nhiên, chỉ phần cứng PowerVR xác định khả năng hiển thị trong bước hoãn lại (do đó đó là GPU duy nhất được gọi là "TBDR"). Các giải pháp khác có thể dựa trên gạch (TBR), nhưng vẫn đang sử dụng các kỹ thuật Early Z phụ thuộc vào thứ tự gửi như IMR. TBR và TBDRs pha trộn trên chip (nhanh hơn, ít năng lượng đói hơn đi vào bộ nhớ chính) vì vậy pha trộn nên được ưa chuộng cho tính minh bạch. Thủ tục thông thường để render các đa giác được pha trộn một cách chính xác là vô hiệu hóa việc ghi chiều sâu (nhưng không phải kiểm tra) và hiển thị tris theo thứ tự chiều sâu từ trước đến trước (trừ khi thao tác pha trộn là độc lập theo thứ tự). Phân loại xấp xỉ thường là đủ tốt. Hình học nên được như vậy mà các khu vực rộng lớn của các mảnh hoàn toàn trong suốt được tránh. Nhiều hơn một mảnh vẫn được xử lý trên mỗi pixel theo cách này, nhưng tối ưu hóa độ sâu HW không bị gián đoạn như với các mảnh bị loại bỏ.

+0

"khả năng hiển thị của một đoạn (và do đó độ sâu) chỉ có thể xác định sau khi xử lý phân đoạn và không phải trong thời gian đầu Z-hoặc HSR của PowerVR (loại bỏ bề mặt ẩn), v.v ..." Điều đó không hoàn toàn đúng. Hoặc là đầu-Z hoặc loại bỏ có thể ngăn chặn một mảnh bị rút ra. Vì vậy, nó rất có thể làm một và sau đó khác. PowerVR không thể vì lý do bạn và tôi đã nêu. Nhưng các trình kết xuất truyền thống chắc chắn có thể. Nếu không, nó sẽ chỉ vì logic loại bỏ được đi kèm với logic kiểm tra độ sâu. Đó là một vấn đề thiết kế phần cứng, không phải là sự cần thiết về mặt thuật toán. –

+0

Tôi bỏ lỡ trường hợp một mảnh bị loại bỏ được hiển thị 'đằng sau' hình học hiện có: S - đó là ý của bạn? Cả hai đầu Z và HSR sẽ từ chối các mảnh vỡ mà không cần xử lý mảnh trong tình huống đó. Ngay cả khi đó, Early-Z yêu cầu các mảnh che khuất được hiển thị trước khi những cái bị che khuất, loại bỏ hoặc loại bỏ shader vẫn cần phải được chạy cho những mảnh đó để xác định chiều sâu. HSR không phụ thuộc vào thứ tự gửi trong trường hợp này - ở cuối khung, nếu loại bỏ các mảnh nằm sau các mảng mờ thì chúng không được xử lý bởi PowerVR. – gmaclachlan

+0

Một đoạn có thể không được hiển thị vì nhiều lý do. Độ sâu kiểm tra là một, loại bỏ là khác. Đầu tiên Z chỉ thực hiện kiểm tra độ sâu trước. Lý do duy nhất loại bỏ sẽ can thiệp vào điều này là nếu logic loại bỏ được gắn vào logic kiểm tra độ sâu trong phần cứng. Chỉ vì một cái gì đó vượt qua các bài kiểm tra độ sâu không có nghĩa là nó sẽ vượt qua tất cả mọi thứ. Nếu chiều sâu và loại bỏ được kết hợp, nó chỉ là vì phần cứng được xây dựng theo cách đó, không phải vì nó * có * được thực hiện theo cách đó bởi thuật toán. Bạn sẽ có thể thực hiện các bài kiểm tra Sớm và sau đó vẫn bị loại bỏ. –

1

Đối tượng A ở phía trước đối tượng B. Đối tượng A có trình đổ bóng sử dụng 'loại bỏ'. Như vậy, tôi không thể làm 'Early-Z' đúng bởi vì tôi cần biết những phần nào của Object B sẽ được hiển thị thông qua Object A. Điều này có nghĩa là Object A phải vượt qua tất cả các cách thức thông qua các đường ống xử lý cho đến gần thời điểm (cho đến khi xử lý đoạn được thực hiện) trước khi tôi có thể xác định đối tượng B có thực sự hiển thị hay không.

Điều này là xấu đối với HSR và 'Early-Z' là đối tượng có khả năng bị tắc phải ngồi và chờ thông tin chuyên sâu được cập nhật trước khi chúng có thể được xử lý. Như đã được nói ở trên, nó xấu cho tất cả mọi người, hoặc, trong cách thân thiện hơn một chút "Bạn bè không cho phép bạn bè sử dụng Discard".

2

Ngoài ra, chỉ cần có câu lệnh "if" trong trình đổ bóng đoạn của bạn có thể gây ra sự chậm lại lớn trên một số phần cứng. (Cụ thể, các GPU có nhiều đường ống dẫn hoặc lệnh đơn/nhiều dữ liệu sẽ có các hình phạt hiệu suất lớn từ các báo cáo chi nhánh). Vì vậy, kết quả kiểm tra của bạn có thể là kết hợp của câu lệnh "if" và các hiệu ứng mà người khác đã đề cập.

(Đối với những gì đáng giá, thử nghiệm trên Galaxy Nexus của tôi đã cho thấy một tốc độ lớn khi tôi chuyển sang phân loại sâu đối tượng bán trong suốt của mình và đưa chúng trở lại phía trước, thay vì hiển thị theo thứ tự ngẫu nhiên và loại bỏ các đoạn trong bóng đổ.)

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