Tăng tốc độ làm mờ?


9

Tôi đang làm việc trên một ứng dụng phụ 2d trong PyGame. Đối với mỗi bản đồ, chúng tôi sử dụng một kết cấu (đây là kích thước thực tế của kết cấu):

kết cấu bản đồ

Sau đó, chúng tôi tải hình ảnh với mã này:

sprite = pygame.image.load("Maps/MapTesting.png")
sprite.convert()
sprite = pygame.transform.scale(sprite,
              (sprite.get_width()*6, sprite.get_height()*6))

Như bạn có thể thấy, kết cấu được thổi lên 6 lần để tạo kết cấu bản đồ thực tế. Trung bình kết cấu này là khoảng 4500x800. Kết cấu này phải được làm mờ trên màn hình mọi khung hình , vì toàn bộ màn hình bị bẩn (nhờ cuộn bên). Chúng tôi làm điều đó bằng cách sử dụng mã này:

screen.blit(sprite, (0, 0),
(cameraposx, cameraposy, windowheight, windowwidth))

Và nó hoạt động. Vấn đề là nó khá chậm: Tôi nhận được 40 FPS ít ỏi trên một PC thấp, và điều đó không có bất kỳ AI / đối tượng thực tế nào đang diễn ra, trong khi chúng tôi đang nhắm tới 60 FPS. Làm thế nào chúng ta có thể tăng tốc này?


Lưu ý rằng mã trên được vệ sinh và đưa ra khỏi bối cảnh. Mã đầy đủ có thể được tìm thấy ở đây: https://github.com/nightcracker/PyGG2

Và cuối cùng nhưng không kém phần quan trọng, trong khi hình ảnh trên có thể trông giống như 8 bit, có những yếu tố trong trò chơi đòi hỏi độ sâu bit nhiều hơn.


Chia thành một kích thước lành mạnh cho mỗi kết cấu, giả sử 1024 rộng cho mỗi khối và chỉ làm mờ hai cái có liên quan tại một thời điểm.
Jari Komppa

@JariKomppa: Đã thử nó, không có tác dụng gì với việc làm mờ (pygame đủ thông minh để làm mờ chỉ các chỉnh sửa tôi nói với nó), chỉ sử dụng bộ nhớ.
orlp

Bạn không thể ... không sử dụng pygame (trollface.jpg) .... jkjk, trong trường hợp này tôi đoán đó không phải là nơi xảy ra tình trạng chậm lại của bạn, bạn đã thử nghiệm rộng rãi chưa?
ultifinitus

@ultifinitus: Vâng, tôi định hình nó bằng cProfile.
orlp

Sự khác biệt về tốc độ nếu bạn hiển thị nó ở độ phân giải thực tế là gì? Điều gì nếu bạn tính toán trước hình ảnh lớn hơn?
ultifinitus

Câu trả lời:


7

Hãy để tôi liệt kê một số tối ưu hóa được so sánh chung liên quan đến Blits pixel lên một bề mặt (theo kinh nghiệm của tôi).

1) Thông thường hình ảnh bảng màu (hình ảnh được lập chỉ mục) khi được làm mờ, sẽ trải qua một cấp độ chuyển hướng bổ sung (để có được màu sắc). Vì vậy, chúng sẽ bị chậm khi làm mờ khi so sánh với hình ảnh màu thực.

2) Dữ liệu pixel màu thực (giả sử không có dữ liệu Alpha - say24 bit) có thể được làm mờ rất nhanh vì chúng ta có thể tạo một memcpy cho mỗi đường quét của hình ảnh (nếu chúng ta đang sao chép một phần hình ảnh) vào bộ đệm khung của thiết bị .Nếu dữ liệu được làm mờ là một hình ảnh đầy đủ, thì chúng ta có thể ghi nhớ trực tiếp toàn bộ dữ liệu nhanh hơn nhiều!

3) Làm mờ dữ liệu pixel Alpha sẽ tốn kém nhất vì nó sẽ bao gồm việc tính toán từng kết quả thành phần và chúng ta cần phải đóng gói lại dữ liệu RGB. Nói một cách đơn giản, nhiều thao tác hơn cho mỗi pixel để có được màu cuối cùng!

Finalrgb = Alpha*(Srgb) + (1-Alpha)*Drgb (this is for normal blend equation)
    where Srgb is source-rgb (we need to apply for each of the component for final color)
       Drgb is the color that will be there in the destination buffer.

Tôi chưa từng làm việc với pyGame trước đây. Nhưng, một cái nhìn nhanh về mã souce của nó, khiến tôi cho rằng nó đang sử dụng các chức năng Blit 'sdl' dưới mui xe. Thông thường Sdl blit sẽ rất nhanh và được tối ưu hóa, vì vậy, chỉ cần thực hiện một lần nữa các điểm trên và hồ sơ một lần nữa! Chúc may mắn!

* Cập nhật: * Cài đặt phím màu giống như thêm một kiểm tra bổ sung khi làm mờ từng pixel trên bề mặt. Một số thứ như thế này -

       for(eachPixelColor in allPixels)
         {
            if(eachPixelColor is NOT colorKeyColor)
            {
              copy color to the frame buffer!
            }

         }

Vì vậy, ở đây nếu bạn thấy, chúng tôi bị hạn chế không sử dụng memcpy vì chúng tôi cần kiểm tra tính hợp lệ của từng pixel!


Ok, vì nó bật ra một cuộc gọi đến set_colorkeytrong kết cấu bản đồ, tạo cho nó một kênh alpha (đắt tiền). Đã convertsửa lỗi đó và hiện tôi đang chạy 150 FPS ổn định trên PC crap này. Cảm ơn!
orlp

hey sẽ chỉnh sửa liên quan đến khóa màu thậm chí quên thêm một số thông tin abt: D
Ayyappa

5

sprite.convert() không làm những gì bạn nghĩ nó làm.

sprite = sprite.convert() là những gì bạn cần.


sprite = sprite.convert()Mặc dù vậy , tôi có mã thực sự :)
orlp

Aha, tốt. :) Trong trường hợp đó, tôi không có nhiều thứ để cung cấp cho bạn ngoại trừ việc xem xét sử dụng pyglet thay vì pygame hoặc sử dụng trực tiếp pyOpenGL nếu bạn cảm thấy thoải mái với OpenGL.
Kylotan

@Kylotan: bạn đời bắt tốt! tôi chưa kiểm tra nó :)
Ayyappa

hoặc, thậm chí tốt hơn:sprite = pygame.image.load("Maps/MapTesting.png").convert()
MestreLion
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.