Hiệu quả Sprite Batching


7

Đang xem xét chuyển từ XNA sang API của 3D3D (Molehill). Vì vậy, khi kiểm tra hiệu năng tôi đã triển khai thực hiện theo đợt sprite, nhưng hiệu suất không tuyệt vời lắm, trong khi với XNA, tôi có thể dễ dàng rút ra tới 500 000 quads nhưng với triển khai Molehill của tôi, tôi có thể rút ra khoảng 1000 quads và trong khi sự khác biệt hiệu năng khá ấn tượng đã được dự kiến ​​ở phía CPU, điều này là do bị ràng buộc GPU.

Vì vậy, hiện tại việc thực hiện như sau.

set render states

let texture be null
let batchSize be arbitrary

for each sprite in queue
    if texture is not sprite texture
    or buffers are full

        upload vertex data to index buffer
        upload index data to vertex buffer

        bind texture
        draw triangles

        flush vertex data
        flush index data


    add sprite vertices to vertex data
    add sprite indices to index data
end

upload remaining vertex data to vertex buffer
upload remaining index data to index buffer
draw remaining triangles

flush data

Nút thắt đang tải lên bộ đệm, nhưng để triển khai tốt hơn, tôi hy vọng có một cuộc thảo luận ở đây.

Chúc mừng.

Sửa đổi:

Một tối ưu hóa xuất hiện trong đầu là duy trì bộ đệm chỉ mục, vì các chỉ số có thể dự đoán được và sẽ luôn tuân theo cùng định dạng. Đang đi đến điểm chuẩn mà bây giờ.


Bộ nhớ đệm bộ đệm chỉ mục không có hiệu suất tăng đáng chú ý, vì vậy, trong nỗ lực cố gắng hiểu nút thắt ở đâu, tôi đã chuyển nó sang C # / XNA, chậm hơn một chút so với triển khai của Microsoft nhưng vẫn có dung lượng GPU hơn 500 lần so với việc thực hiện Molehill.

Có phải Molehill chỉ đơn giản là một lớp trừu tượng cực kỳ xấu?


Làm cho Index Buffer bền bỉ là một ý tưởng tốt, điều đó có thể giúp đạt được một chút hoàn hảo. Điều khác duy nhất tôi có thể nghĩ đến khi nhìn vào mã giả của bạn là bạn luôn liên kết lại kết cấu. Bạn nên kiểm tra xem kết cấu có thay đổi giữa các cuộc gọi hay không và sau đó liên kết một kết cấu mới, nếu không, bạn sẽ không nhận được hiệu suất khi sử dụng Texture Altas chẳng hạn.
Jonathan Connell

Trên thực tế, kết cấu chỉ bị ràng buộc một lần, có lẽ đọc lại nó.
Casper Beyer

Ồ vâng, nó ngụ ý rằng "kết cấu" được gán cho kết cấu của sprite khi liên kết.
Casper Beyer

Bạn có 'Bind Texture' trong mỗi vòng lặp. Tôi đã nói rằng nó nên là nếu bạn không gọi Bind Texture khi kết cấu không thay đổi giữa hai họa tiết. Hiện tại, bạn đang yêu cầu GPU liên kết lại một kết cấu trong mỗi vòng lặp; đó là một hoạt động tốn kém và có thể không cần thiết.
Jonathan Connell

Một lần nữa, nó chỉ bị ràng buộc một lần. Một kiểm tra có điều kiện hầu như không phải là một hoạt động tốn kém.
Casper Beyer

Câu trả lời:


2

Bạn có thể có nhiều bản đồ của các họa tiết trong đó khóa của chúng là kết cấu, sau đó khi kết xuất, đi qua từng phím trong bản đồ và hiển thị từng nhóm các họa tiết được liên kết với kết cấu đó. Nếu tất cả các sprite đều có chung một kết cấu thì bạn có thể biểu diễn mọi sprite bằng hai tam giác và tọa độ kết cấu, có nghĩa là bạn có thể vẽ tất cả các sprite sử dụng cùng một kết cấu trong một lần chạy, với một bộ đệm đỉnh và bộ đệm chỉ mục.

Mặc dù tôi đang sử dụng XNA, tôi đã thực hiện quy trình kết xuất và tạo khối của riêng mình thay vì sử dụng lô sprite và tôi kết xuất khoảng 3000 sprite cùng một lúc và hiện nhận được khoảng 600 khung hình / giây trên Nvidia GTX 275, sử dụng quy trình I miêu tả trên. Khi tôi vừa truyền các sprite cho phương thức spritebatch, XNA cho nó khoảng 25 khung hình / giây.

Trong trường hợp của tôi, thay vì một multimap, tôi có một lớp (SpriteData) có chứa kết cấu và một danh sách các đỉnh. Bất cứ khi nào một sprite đăng ký với trình kết xuất, trình kết xuất sẽ đi qua Danh sách SpriteData cho đến khi tìm thấy một loại kết cấu phù hợp và thêm sprite đó vào danh sách đỉnh.

Tôi cũng đang thực hiện phân vùng không gian để đảm bảo rằng chỉ các sprite trong chế độ xem đang được xem xét.

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.