Để kết xuất voxel, còn gì hiệu quả hơn: VBO được tạo sẵn hoặc trình tạo bóng hình học?


26

Với một mảng voxel khá tĩnh, hiệu quả hơn: sử dụng CPU để tạo trước VBO để hiển thị các mặt voxel (bỏ qua các hình thức kết xuất tiên tiến hơn như diễu hành bây giờ) hoặc sử dụng trình tạo bóng hình học trên GPU để tạo khuôn mặt đang bay?

Tôi không lo lắng về việc cập nhật thay đổi voxels nhưng tất nhiên đó là lợi ích của phiên bản GPU vì bạn không phải xây dựng lại VBO. Ngoài ra, cách tiếp cận GS cảm thấy hiện đại hơn một chút :)

Mặt khác, tôi chưa xem xét chi tiết về cách một GS thực sự hoạt động với đường ống rasterization trong các GPU hiện đại. Liệu nó xuất các đỉnh thành một loại bộ đệm dòng hay là các đỉnh được ghi vào bộ nhớ GPU thông thường ở giữa? Nếu đó là thứ hai, thì việc tạo nhanh có thể làm giảm băng thông và sức mạnh xử lý từ các nhiệm vụ GPU còn lại mà tôi đoán và sau đó sẽ có ích hơn khi thực hiện trên CPU ..

Câu trả lời:


9

Tôi đang nghĩ về một cảnh loại minecraft, trong đó voxel có nghĩa là một thế giới của các khối thực sự được kết xuất bằng đa giác:

Nếu bạn sử dụng một shader hình học, sẽ khó tránh khỏi việc có chính xác ba khuôn mặt (hoặc bất cứ thứ gì) trên mỗi voxel.

Nếu bạn có nhiều khối liền kề có cùng kết cấu thì bạn có thể sử dụng ốp lát họa tiết để có ít hình tam giác hơn trong dải (suy biến) trong cách tiếp cận VBO. Ý tôi là, nếu có một khu vực rộng lớn 6x6 của cỏ voxels, bạn có thể vẽ toàn bộ đỉnh chỉ trong 2 hình tam giác thay vì 64.

Với cách tiếp cận của GS, bạn không thể loại bỏ các khuôn mặt tầm thường bị che khuất bởi các voxels liền kề rất đơn giản với cách tiếp cận VBO.

Tôi chưa thử phương pháp GS, nhưng tôi có thể nói rằng phương pháp VBO với việc kết hợp lặp lại các ô liền kề hoạt động rất tốt. Tôi thấy lộn xộn với các chỉ số phần tử chậm hơn nhiều so với việc chỉ lặp lại các đỉnh. Nếu bạn chia thế giới của mình thành các khối nhỏ đẹp, bạn thường có thể sử dụng chỉ một byte cho mỗi thành phần trên mỗi đỉnh và thậm chí đóng gói thông tin kết cấu và quy tắc (một mặt trên khối lập phương có trục chỉ có 3 quy tắc có thể), v.v. 4 byte cho mỗi đỉnh là tốt và nhanh chóng.

Tôi đã sử dụng các VBO riêng biệt cho mỗi trong số 6 khuôn mặt - bạn chỉ cần vẽ tối đa 3 trong số chúng. Điều này rất phù hợp với kết cấu khác nhau thường được sử dụng trên các phần trên cùng của voxels kiểu minecraft. Bởi vì đối với mỗi bộ bình thường và như vậy là đồng nhất.

Với việc sử dụng các pixmap được xếp theo chiều dọc trong một tập bản đồ với GL_REPEATtrục ngang và có các phiên bản xoay 90 độ trong cùng một tập bản đồ, tôi thấy tôi có thể vẽ một lượng lớn các khối rõ ràng khác nhau bằng cách sử dụng cùng một VBO trong cùng một cuộc gọi. Trong ví dụ về diện tích cỏ 6x6, tôi đã chia nó thành 12 hình tam giác khi tôi chỉ lặp lại trên một chiều trong tập bản đồ của mình.

Tôi hầu như đã làm cho nó hoạt động ở mức rất thấp của chip đồ họa tích hợp và di động, nơi GS chỉ là thứ tôi có thể mơ về một ngày nào đó chơi cùng.


3
Bạn chỉ cần vẽ tối đa 3 mặt cho mỗi voxel, nhưng bạn có thể cần vẽ các mặt khác nhau cho mỗi voxel tùy thuộc vào quan điểm để tối ưu hóa không dễ dàng phải không? Một VBO được tạo sẵn sẽ chứa nhiều hơn một voxel. Nếu quan điểm của bạn ở giữa các voxels, bạn sẽ thấy phía đông của bên này và phía tây của bên kia. Cách duy nhất điều này sẽ giúp là bạn có thể loại bỏ các mặt quay mặt thực tế một cách tầm thường, nhưng trường hợp xấu nhất vẫn là bạn kết xuất 5 trong số 6 mặt trong một nhóm các voxels. Nếu quan điểm của bạn nằm ngoài giới hạn trục của VBO, thì bạn chỉ cần kết xuất 3 mặt.
Bjorn Wesen

Tại chỗ trên Bjorn, nó có thể làm được. (Nhưng tôi đang tạo VBO cho các khối khi cần thiết và xem xét lại những gì tôi đã tạo khi máy ảnh di chuyển, thay vì có cả thế giới trong VBO mọi lúc; vì vậy tôi có thời gian tự nhiên để thực hiện các lựa chọn này)
Sẽ

10

Điều gì về tùy chọn thứ ba, sử dụng các mảng không ổn định? Về cơ bản, bạn vẽ nhiều hộp (được tạo từ một khối 8 đỉnh đơn giản) với một lệnh gọi duy nhất, tìm nguồn cung cấp các vị trí (và dữ liệu khác) dưới dạng các thuộc tính từ VBO của dữ liệu voxel (sử dụng glVertexAttribDivisortrong OpenGL, tôi chắc chắn DX cũng vậy. Cách này có thể nhanh hơn cách tiếp cận shader hình học mặc dù mã ứng dụng (không phải shader) khá giống nhau, vì tôi nhớ các shader hình học có tiếng là chậm, mặc dù tôi không có kinh nghiệm với chúng (hoặc chạy theo) trên phần cứng 2.1.

Nhưng dù sao đi nữa, các shader hình học hoặc các mảng được điều khiển sẽ phù hợp hơn so với hình học voxel do CPU tạo ra, đặc biệt là khi dữ liệu voxel có thể thay đổi. Kết hợp với phản hồi chuyển đổi (đầu ra luồng trong DX?), Bạn có thể thiết lập một số kỹ thuật loại bỏ dựa trên GPU tốt.


Vâng, đây là giải pháp tốt nhất cho vấn đề này. Tại sao không xảy ra với tôi? :)
Notabene

Sau một số thử nghiệm tôi phải nói với bạn rằng hình học nướng đánh bại bất kỳ sự cố định nào bằng một lề rộng. Tôi chưa thử shader hình học mặc dù.
Jari Komppa

@JariKomppa bạn có thể nói rõ hơn về ý nghĩa của hình học nướng không?
Steven Lu

Trường hợp được dịch trước và sao chép vào một lưới duy nhất. Giống như có một lưới đại diện cho một trăm khối hoặc bất cứ điều gì.
Jari Komppa

@JariKomppa Tôi đã thấy kết quả tương tự, trong đó việc tạo lưới nhanh hơn nhiều. Tuy nhiên, trên gtx 680, tùy chọn instaging dường như hoạt động nhanh hơn, kỳ lạ hơn nhiều.
Levi H

1

Phiên bản shader hình học nghe tốt hơn nhiều đối với tôi. Bạn chỉ có thể có điểm vbo và hộp xây dựng khi đang bay (điểm đầu vào, luồng tam giác đầu ra). Nó sẽ nhanh (thậm chí nhanh hơn nếu bạn sẽ sử dụng đơn vị tessname trong mô hình shader 5 eq. DX11) và sẽ giảm băng thông cực kỳ, nó sẽ là giải pháp tốt và sạch.

Về GS. Nó được đặt giữa shader đỉnh và pixel shader và sửa đổi luồng đỉnh (nguyên thủy) đầu ra. Trong khi shader đỉnh chỉ hoạt động trên các đỉnh, shader hình học hoạt động trên toàn bộ nguyên thủy. Đầu ra của luồng này chỉ chuyển đến trình đổ bóng pixel (và được rasterized trước khóa học đó :)) và không có cách nào để lưu nó. (Có thể bằng một số kết xuất điên rồ thành kết cấu và sau đó phân tích cú pháp ... nhưng không có khả năng đơn giản thực sự nào)

Lưu ý về hiệu suất: Bạn sẽ có thể để mọi thứ trong trình đổ bóng hình học và bỏ qua (chỉ truyền dữ liệu) trình tạo bóng đỉnh. Nhưng nó không phải là cách tốt nhất. Tốt hơn (nhanh hơn) là thực hiện hầu hết các phép biến đổi có thể trên trình tạo bóng đỉnh và cố gắng giảm thiểu chương trình đổ bóng hình học. Đừng ngại sử dụng cho chu kỳ nếu bạn sẽ cần nó (ví dụ để tạo hộp). Trình biên dịch sẽ hủy đăng ký nó cho bạn.


2
Có thể là một ý tưởng tốt để kiểm tra các voxels liền kề trong hình học và / hoặc shader đỉnh và loại bỏ các đỉnh hoặc bỏ qua các mặt nếu chúng bị chặn. Nếu không, giải pháp GS sẽ tăng băng thông được sử dụng thay thế.
Tamschi

Bandwith sẽ không phải là vấn đề lớn (từ kinh nghiệm của tôi), nhưng tất nhiên đó là sự thật. Và bạn không thể tìm kiếm trong các nguyên thủy khác trong GS (tôi biết :)).
Notabene

@Tamschi: vâng, vấn đề này xảy ra với tôi ngay sau khi viết câu hỏi này .. đối với phiên bản CPU, voxels ở giữa chất rắn bị triệt tiêu, nhưng điều này có thể là không thể đối với GPU mà không vượt qua trước với số tiền sẽ lên tới khác biệt ..
Bjorn Wesen

1
Bạn có thể liên kết bộ đệm đỉnh với đồng phục isamplerBuffer hoặc usamplerBuffer trong shader, sau đó thực hiện tra cứu với kết cấu (name_of_uniform, index). Một tùy chọn khác là liên kết bộ đệm với một mảng đồng nhất, giúp bạn tự do hơn trong định dạng đỉnh bạn muốn sử dụng.
Tamschi
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.